From 4077a94c31368093f657556cac798b610d14a185 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Fri, 12 Oct 2018 13:21:32 +0530 Subject: [PATCH 001/281] AndroidKernel: Use host machine tools Use the host directory of tools for kernel cross compilation to ensure build results are reproducible across different machines. Change-Id: I804745bb1962c46e944ba43e77e8876435c9059e Signed-off-by: Mukesh Ojha --- AndroidKernel.mk | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidKernel.mk b/AndroidKernel.mk index 7233829c3c84..6ea10f781194 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -46,7 +46,7 @@ TARGET_KERNEL_CROSS_COMPILE_PREFIX := $(strip $(TARGET_KERNEL_CROSS_COMPILE_PREF ifeq ($(TARGET_KERNEL_CROSS_COMPILE_PREFIX),) KERNEL_CROSS_COMPILE := arm-eabi- else -KERNEL_CROSS_COMPILE := $(TARGET_KERNEL_CROSS_COMPILE_PREFIX) +KERNEL_CROSS_COMPILE := $(shell pwd)/$(TARGET_TOOLS_PREFIX) endif ifeq ($(TARGET_PREBUILT_KERNEL),) diff --git a/Makefile b/Makefile index 8e7cef480bb3..6ef35aaafe04 100644 --- a/Makefile +++ b/Makefile @@ -366,7 +366,7 @@ CHECK = sparse # Use the wrapper for the compiler. This wrapper scans for new # warnings and causes the build to stop upon encountering them -CC = $(srctree)/scripts/gcc-wrapper.py $(REAL_CC) +CC = $(PYTHON) $(srctree)/scripts/gcc-wrapper.py $(REAL_CC) CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ -Wbitwise -Wno-return-void $(CF) From 1fb9158725c8dbbdfb6115b2daa7aba089ddb8b7 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Fri, 8 Mar 2019 11:37:34 -0800 Subject: [PATCH 002/281] ARM: dts: msm: enable cpu dai and group tdm Enable QUAT TDM RX1 cpu dai. Enable group tdm for QUAT TDM ports RX0 and RX1. CRs-Fixed: 2409954 Change-Id: Id5d368b15aa46597c5abd178929abe351018ba2f Signed-off-by: Vignesh Kulothungan --- arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi | 4 ++-- arch/arm64/boot/dts/qcom/sdm845-audio.dtsi | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi index 13e5187ed6b5..dcbfe47cec8f 100644 --- a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi +++ b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, 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 @@ -509,7 +509,7 @@ }; }; - qcom,msm-dai-tdm-quat-rx { + msm_dai_tdm_quat_rx: qcom,msm-dai-tdm-quat-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37168>; qcom,msm-cpudai-tdm-group-num-ports = <1>; diff --git a/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi index b5c1ded20fc7..a64467c3ef68 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, 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 @@ -67,7 +67,8 @@ <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>, <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>, <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_tx_0>, - <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>; + <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>, + <&dai_quat_tdm_rx_1>; asoc-cpu-names = "msm-dai-q6-hdmi.8", "msm-dai-q6-dp.24608", "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", @@ -89,7 +90,8 @@ "msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36865", "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881", "msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36897", - "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913"; + "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913", + "msm-dai-q6-tdm.36914"; }; }; @@ -99,3 +101,13 @@ elemental-addr = [ff ff ff fe 17 02]; }; }; + +&msm_dai_tdm_quat_rx { + qcom,msm-cpudai-tdm-group-num-ports = <2>; + qcom,msm-cpudai-tdm-group-port-id = <36912 36914>; + dai_quat_tdm_rx_1: qcom,msm-dai-q6-tdm-quat-rx-1 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36914>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; +}; From 69eab5c91f320aa82162358f05c3171191b86894 Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Mon, 15 Apr 2019 12:41:12 +0800 Subject: [PATCH 003/281] sched/fair: Allow load bigger task load balance when nr_running is 2 When there is only 2 tasks in 1 cpu and the other task is currently running, allow load bigger task to be balanced if the other task is currently running. Change-Id: I489e9624ba010f9293272a67585e8209a786b787 Signed-off-by: Maria Yu --- kernel/sched/fair.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 08391ffd5377..c1ee2958a3a9 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -8560,7 +8560,17 @@ static int detach_tasks(struct lb_env *env) if (sched_feat(LB_MIN) && load < 16 && !env->sd->nr_balance_failed) goto next; - if ((load / 2) > env->imbalance) + /* + * p is not running task when we goes until here, so if p is one + * of the 2 task in src cpu rq and not the running one, + * that means it is the only task that can be balanced. + * So only when there is other tasks can be balanced or + * there is situation to ignore big task, it is needed + * to skip the task load bigger than 2*imbalance. + */ + if (((cpu_rq(env->src_cpu)->nr_running > 2) || + (env->flags & LBF_IGNORE_BIG_TASKS)) && + ((load / 2) > env->imbalance)) goto next; detach_task(p, env); From bf00da2adea4f6b1af5b2da1ff4ac5b30ce0726f Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Tue, 7 May 2019 15:32:13 +0530 Subject: [PATCH 004/281] msm: ipa: Handle resume iface Handle resume iface after disconnect and suspend. Change-Id: Iae71c450bb184bfa1abe80651f1191b420789c1e Signed-off-by: Chaitanya Pratapa Signed-off-by: Mohammed Javid --- .../platform/msm/ipa/ipa_clients/ipa_gsb.c | 120 +++++++++++------- 1 file changed, 77 insertions(+), 43 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c index bc04ed4a5cfd..45294a41d560 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c @@ -438,7 +438,9 @@ static void ipa_gsb_pm_cb(void *user_data, enum ipa_pm_cb_event event) IPA_GSB_DBG_LOW("wake up clients\n"); for (i = 0; i < MAX_SUPPORTED_IFACE; i++) - if (ipa_gsb_ctx->iface[i] != NULL) + if (ipa_gsb_ctx->iface[i] != NULL && + ipa_gsb_ctx->iface[i]->is_connected && + !ipa_gsb_ctx->iface[i]->is_resumed) ipa_gsb_ctx->iface[i]->wakeup_request( ipa_gsb_ctx->iface[i]->priv); } @@ -478,6 +480,53 @@ static int ipa_gsb_register_pm(void) return ret; } +static int ipa_bridge_stop_channel_deactivate_pm(u32 hdl) +{ + int ret = 0; + + if (ipa_gsb_ctx->num_resumed_iface == 1) { + ret = ipa_stop_gsi_channel( + ipa_gsb_ctx->cons_hdl); + if (ret) { + IPA_GSB_ERR( + "fail to stop cons ep %d\n", + ret); + return ret; + } + + ret = ipa_pm_deactivate_sync(ipa_gsb_ctx->pm_hdl); + if (ret) { + IPA_GSB_ERR("fail to deactivate ipa pm\n"); + ipa_start_gsi_channel(ipa_gsb_ctx->cons_hdl); + return ret; + } + } + return ret; +} + +static int ipa_bridge_activate_pm_start_channel(u32 hdl) +{ + int ret = 0; + + if (ipa_gsb_ctx->num_resumed_iface == 0) { + ret = ipa_pm_activate_sync(ipa_gsb_ctx->pm_hdl); + if (ret) { + IPA_GSB_ERR("fail to activate ipa pm\n"); + return ret; + } + + ret = ipa_start_gsi_channel( + ipa_gsb_ctx->cons_hdl); + if (ret) { + IPA_GSB_ERR( + "fail to start con ep %d\n", + ret); + return ret; + } + } + return ret; +} + int ipa_bridge_init(struct ipa_bridge_init_params *params, u32 *hdl) { int i, ret; @@ -881,9 +930,18 @@ int ipa_bridge_connect(u32 hdl) ipa_gsb_ctx->iface[hdl]->is_connected = true; ipa_gsb_ctx->iface[hdl]->is_resumed = true; + /* Connected == 0, would have started above already, + * So, ignore it. + */ + if (ipa_gsb_ctx->num_connected_iface != 0) + ipa_bridge_activate_pm_start_channel(hdl); + ipa_gsb_ctx->num_connected_iface++; IPA_GSB_DBG("connected iface: %d\n", ipa_gsb_ctx->num_connected_iface); + /* Wake up remaining clients. */ + if (ipa_gsb_ctx->num_resumed_iface == 0) + ipa_gsb_pm_cb(NULL, IPA_PM_REQUEST_WAKEUP); ipa_gsb_ctx->num_resumed_iface++; IPA_GSB_DBG("num resumed iface: %d\n", ipa_gsb_ctx->num_resumed_iface); @@ -973,6 +1031,13 @@ int ipa_bridge_disconnect(u32 hdl) if (ipa_gsb_ctx->iface[hdl]->is_resumed) { ipa_gsb_ctx->iface[hdl]->is_resumed = false; + + /* Connected < 1, would have stopped above already, + * So, ignore it. + */ + if (ipa_gsb_ctx->num_connected_iface >= 1) + ipa_bridge_stop_channel_deactivate_pm(hdl); + ipa_gsb_ctx->num_resumed_iface--; IPA_GSB_DBG("num resumed iface: %d\n", ipa_gsb_ctx->num_resumed_iface); @@ -1022,25 +1087,11 @@ int ipa_bridge_resume(u32 hdl) } mutex_lock(&ipa_gsb_ctx->lock); - if (ipa_gsb_ctx->num_resumed_iface == 0) { - ret = ipa_pm_activate_sync(ipa_gsb_ctx->pm_hdl); - if (ret) { - IPA_GSB_ERR("fail to activate ipa pm\n"); - mutex_unlock(&ipa_gsb_ctx->lock); - mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]); - return ret; - } - - ret = ipa_start_gsi_channel( - ipa_gsb_ctx->cons_hdl); - if (ret) { - IPA_GSB_ERR( - "fail to start con ep %d\n", - ret); - mutex_unlock(&ipa_gsb_ctx->lock); - mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]); - return ret; - } + ret = ipa_bridge_activate_pm_start_channel(hdl); + if (ret) { + mutex_unlock(&ipa_gsb_ctx->lock); + mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]); + return ret; } ipa_gsb_ctx->iface[hdl]->is_resumed = true; @@ -1094,30 +1145,13 @@ int ipa_bridge_suspend(u32 hdl) } mutex_lock(&ipa_gsb_ctx->lock); - if (ipa_gsb_ctx->num_resumed_iface == 1) { - ret = ipa_stop_gsi_channel( - ipa_gsb_ctx->cons_hdl); - if (ret) { - IPA_GSB_ERR( - "fail to stop cons ep %d\n", - ret); - atomic_set(&ipa_gsb_ctx->suspend_in_progress, 0); - mutex_unlock(&ipa_gsb_ctx->lock); - mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]); - return ret; - } - - ret = ipa_pm_deactivate_sync(ipa_gsb_ctx->pm_hdl); - if (ret) { - IPA_GSB_ERR("fail to deactivate ipa pm\n"); - ipa_start_gsi_channel(ipa_gsb_ctx->cons_hdl); - atomic_set(&ipa_gsb_ctx->suspend_in_progress, 0); - mutex_unlock(&ipa_gsb_ctx->lock); - mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]); - return ret; - } + ret = ipa_bridge_stop_channel_deactivate_pm(hdl); + if (ret) { + atomic_set(&ipa_gsb_ctx->suspend_in_progress, 0); + mutex_unlock(&ipa_gsb_ctx->lock); + mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]); + return ret; } - ipa_gsb_ctx->iface[hdl]->is_resumed = false; ipa_gsb_ctx->num_resumed_iface--; IPA_GSB_DBG_LOW("num resumed iface: %d\n", From 3434ddb20bf1ee041eb4190db58948b84513c867 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 31 May 2019 09:30:35 -0700 Subject: [PATCH 005/281] Revert "x86/build: Move _etext to actual end of .text" This reverts commit 87386764dac1e8dde46ad792e072bd8e8004ee00 which is commit 392bef709659abea614abfe53cf228e7a59876a4 upstream. This breaks the android build at the moment as it still uses binutils :( Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/vmlinux.lds.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 51b772f9d886..55f04875293f 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -111,10 +111,10 @@ SECTIONS *(.text.__x86.indirect_thunk) __indirect_thunk_end = .; #endif - } :text = 0x9090 - /* End of text section */ - _etext = .; + /* End of text section */ + _etext = .; + } :text = 0x9090 NOTES :text :note From c43c800dfdce67567413aef82354169b962eb0c4 Mon Sep 17 00:00:00 2001 From: Ajit Kumar Date: Thu, 2 May 2019 12:51:34 +0530 Subject: [PATCH 006/281] soc: qcom: bgdaemon: add interface for BG status Add an interface to find if BG is in running state. Change-Id: I8049e9d22cd0eb6e9df367f964bc72a538fd2db9 Signed-off-by: Ajit Kumar --- drivers/soc/qcom/bgcom_interface.c | 17 ++++++++++++++++- drivers/soc/qcom/bgcom_interface.h | 9 ++++++++- drivers/soc/qcom/subsys-pil-bg.c | 5 +++++ include/uapi/linux/bgcom_interface.h | 6 +++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/bgcom_interface.c b/drivers/soc/qcom/bgcom_interface.c index 75c99287e851..f2ec13253314 100644 --- a/drivers/soc/qcom/bgcom_interface.c +++ b/drivers/soc/qcom/bgcom_interface.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -95,6 +95,7 @@ static dev_t bg_dev; static int device_open; static void *handle; static bool twm_exit; +static bool bg_app_running; static struct bgcom_open_config_type config_type; static DECLARE_COMPLETION(bg_modem_down_wait); @@ -381,6 +382,10 @@ static long bg_com_ioctl(struct file *filp, twm_exit = true; ret = 0; break; + case BG_APP_RUNNING: + bg_app_running = true; + ret = 0; + break; default: ret = -ENOIOCTLCMD; } @@ -590,6 +595,16 @@ bool is_twm_exit(void) } EXPORT_SYMBOL(is_twm_exit); +bool is_bg_running(void) +{ + if (bg_app_running) { + bg_app_running = false; + return true; + } + return false; +} +EXPORT_SYMBOL(is_bg_running); + static struct notifier_block ssr_modem_nb = { .notifier_call = ssr_modem_cb, .priority = 0, diff --git a/drivers/soc/qcom/bgcom_interface.h b/drivers/soc/qcom/bgcom_interface.h index 235995e21d5a..fa8921c678bb 100644 --- a/drivers/soc/qcom/bgcom_interface.h +++ b/drivers/soc/qcom/bgcom_interface.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -26,4 +26,11 @@ int bg_soft_reset(void); */ bool is_twm_exit(void); +/* + * is_bg_running() + * Return true if bg is running. + * value is auto cleared once read. + */ +bool is_bg_running(void); + #endif /* BGCOM_INTERFACE_H */ diff --git a/drivers/soc/qcom/subsys-pil-bg.c b/drivers/soc/qcom/subsys-pil-bg.c index d1b5feadf989..c3ee42f59146 100644 --- a/drivers/soc/qcom/subsys-pil-bg.c +++ b/drivers/soc/qcom/subsys-pil-bg.c @@ -271,6 +271,11 @@ static int bg_powerup(const struct subsys_desc *subsys) struct pil_bg_data *bg_data = subsys_to_data(subsys); int ret; + if (is_bg_running()) { + pr_debug("bg is already up\n"); + return 0; + } + init_completion(&bg_data->err_ready); if (!bg_data->qseecom_handle) { ret = pil_load_bg_tzapp(bg_data); diff --git a/include/uapi/linux/bgcom_interface.h b/include/uapi/linux/bgcom_interface.h index 1ee7b8714018..25219f7dbf0f 100644 --- a/include/uapi/linux/bgcom_interface.h +++ b/include/uapi/linux/bgcom_interface.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, 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 @@ -20,6 +20,7 @@ #define BGCOM_SOFT_RESET 6 #define BGCOM_MODEM_DOWN2_BG 7 #define BGCOM_TWM_EXIT 8 +#define BGCOM_BG_APP_RUNNING 9 #define EXCHANGE_CODE 'V' struct bg_ui_data { @@ -61,6 +62,9 @@ enum bg_event_type { #define BG_TWM_EXIT \ _IOWR(EXCHANGE_CODE, BGCOM_TWM_EXIT, \ struct bg_ui_data) +#define BG_APP_RUNNING \ + _IOWR(EXCHANGE_CODE, BGCOM_BG_APP_RUNNING, \ + struct bg_ui_data) #define BG_MODEM_DOWN2_BG_DONE \ _IOWR(EXCHANGE_CODE, BGCOM_MODEM_DOWN2_BG, \ struct bg_ui_data) From 04817ed3f0bedf9aad47315e394c14c6290080c3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 6 Jun 2019 19:32:44 +0200 Subject: [PATCH 007/281] Revert "fib_rules: fix error in backport of e9919a24d302 ("fib_rules: return 0...")" The fib_rules change was incorrect and will be reverted upstream soon. Drop it now so that devices start working again. Bug: 133653863 Signed-off-by: Greg Kroah-Hartman --- net/core/fib_rules.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 268e32005273..25c25e85ca06 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -487,7 +487,6 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh) } if (rule_exists(ops, frh, tb, rule)) { - err = 0; if (nlh->nlmsg_flags & NLM_F_EXCL) err = -EEXIST; goto errout_free; From 83ae225d5ce35d30680f5e3d938565fe54998c62 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 6 Jun 2019 19:37:24 +0200 Subject: [PATCH 008/281] Revert "fib_rules: return 0 directly if an exactly same rule exists when NLM_F_EXCL not supplied" The fib_rules change was incorrect and will be reverted upstream soon. Drop it now so that devices start working again. Bug: 133653863 Signed-off-by: Greg Kroah-Hartman --- net/core/fib_rules.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 25c25e85ca06..31c4041f7586 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -486,9 +486,9 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh) rule->uid_range = fib_kuid_range_unset; } - if (rule_exists(ops, frh, tb, rule)) { - if (nlh->nlmsg_flags & NLM_F_EXCL) - err = -EEXIST; + if ((nlh->nlmsg_flags & NLM_F_EXCL) && + rule_exists(ops, frh, tb, rule)) { + err = -EEXIST; goto errout_free; } From e53fcdd909a9c2753acf266843e16adc2e3d3a02 Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Wed, 5 Jun 2019 09:37:46 -0700 Subject: [PATCH 009/281] BACKPORT: binder: fix race between munmap() and direct reclaim commit 5cec2d2e5839f9c0fec319c523a911e0a7fd299f upstream. An munmap() on a binder device causes binder_vma_close() to be called which clears the alloc->vma pointer. If direct reclaim causes binder_alloc_free_page() to be called, there is a race where alloc->vma is read into a local vma pointer and then used later after the mm->mmap_sem is acquired. This can result in calling zap_page_range() with an invalid vma which manifests as a use-after-free in zap_page_range(). The fix is to check alloc->vma after acquiring the mmap_sem (which we were acquiring anyway) and skip zap_page_range() if it has changed to NULL. Bug: 120025196 Change-Id: I2f3284d294326ec7736303374769640a1e028783 Cc: Ben Hutchings Signed-off-by: Todd Kjos Reviewed-by: Joel Fernandes (Google) Cc: stable # 4.14 Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder_alloc.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 34454b073b82..ce006afaf4ed 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -891,14 +891,13 @@ enum lru_status binder_alloc_free_page(struct list_head *item, index = page - alloc->pages; page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; + + mm = alloc->vma_vm_mm; + if (!mmget_not_zero(mm)) + goto err_mmget; + if (!down_write_trylock(&mm->mmap_sem)) + goto err_down_write_mmap_sem_failed; vma = alloc->vma; - if (vma) { - if (!mmget_not_zero(alloc->vma_vm_mm)) - goto err_mmget; - mm = alloc->vma_vm_mm; - if (!down_write_trylock(&mm->mmap_sem)) - goto err_down_write_mmap_sem_failed; - } list_lru_isolate(lru, item); spin_unlock(lock); @@ -909,10 +908,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item, zap_page_range(vma, page_addr, PAGE_SIZE, NULL); trace_binder_unmap_user_end(alloc, index); - - up_write(&mm->mmap_sem); - mmput(mm); } + up_write(&mm->mmap_sem); + mmput(mm); trace_binder_unmap_kernel_start(alloc, index); From b8f2f4b8f6d7f100019675e6bd03c02c6f291753 Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Wed, 24 Apr 2019 12:31:18 -0700 Subject: [PATCH 010/281] UPSTREAM: binder: check for overflow when alloc for security context commit 0b0509508beff65c1d50541861bc0d4973487dc5 upstream. When allocating space in the target buffer for the security context, make sure the extra_buffers_size doesn't overflow. This can only happen if the given size is invalid, but an overflow can turn it into a valid size. Fail the transaction if an overflow is detected. Bug: 130571081 Change-Id: Ibaec652d2073491cc426a4a24004a848348316bf Signed-off-by: Todd Kjos Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 3eada68d7668..aee08f322723 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3229,6 +3229,7 @@ static void binder_transaction(struct binder_proc *proc, if (target_node && target_node->txn_security_ctx) { u32 secid; + size_t added_size; security_task_getsecid(proc->tsk, &secid); ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); @@ -3238,7 +3239,15 @@ static void binder_transaction(struct binder_proc *proc, return_error_line = __LINE__; goto err_get_secctx_failed; } - extra_buffers_size += ALIGN(secctx_sz, sizeof(u64)); + added_size = ALIGN(secctx_sz, sizeof(u64)); + extra_buffers_size += added_size; + if (extra_buffers_size < added_size) { + /* integer overflow of extra_buffers_size */ + return_error = BR_FAILED_REPLY; + return_error_param = EINVAL; + return_error_line = __LINE__; + goto err_bad_extra_size; + } } trace_binder_transaction(reply, t, target_node); @@ -3587,6 +3596,7 @@ static void binder_transaction(struct binder_proc *proc, t->buffer->transaction = NULL; binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: +err_bad_extra_size: if (secctx) security_release_secctx(secctx, secctx_sz); err_get_secctx_failed: From dd8caf4d77d99fae68aa1e9b1c47d1ad1a91df12 Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Wed, 11 Oct 2017 10:12:19 +0530 Subject: [PATCH 011/281] mtd: msm_qpic_nand: Add support for performance stats Add support to collect driver level performance statistics on reads, writes and erases. Below are the commands to enable, reset and read the stats - echo 1 > /sys/module/msm_qpic_nand/parameters/enable_perfstats echo > /sys/devices/platform/1b00000.nand/perf_stats cat /sys/devices/platform/1b00000.nand/perf_stats The module parameter "enable_perfstats" can also be enabled during boot up by adding this to the kernel command line - "msm_qpic_nand.enable_perfstats=1". Change-Id: I20b35219a4bffd90682137969ecd5e854bea9a6b Signed-off-by: Sahitya Tummala Signed-off-by: Pradeep P V K --- drivers/mtd/devices/msm_qpic_nand.c | 203 ++++++++++++++++++++++++++++ drivers/mtd/devices/msm_qpic_nand.h | 22 ++- 2 files changed, 224 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/devices/msm_qpic_nand.c b/drivers/mtd/devices/msm_qpic_nand.c index da24e2cfc709..2139655e6d4a 100644 --- a/drivers/mtd/devices/msm_qpic_nand.c +++ b/drivers/mtd/devices/msm_qpic_nand.c @@ -26,6 +26,183 @@ #define MAX_DESC 16 static bool enable_euclean; +static bool enable_perfstats; + +static ssize_t msm_nand_attr_perf_stats_show(struct device *dev, + struct device_attribute *attr, + char *buf); +static ssize_t msm_nand_attr_perf_stats_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); + +static struct device_attribute dev_msm_nand_perf_stats = + __ATTR(perf_stats, 0644, + msm_nand_attr_perf_stats_show, msm_nand_attr_perf_stats_store); + +#define print_sysfs(fmt, ...) \ +{ \ + count += scnprintf(buf + count, PAGE_SIZE - count, \ + fmt, ##__VA_ARGS__); \ +} + +static ssize_t msm_nand_attr_perf_stats_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count = 0; + struct msm_nand_info *info = dev_get_drvdata(dev); + + if (!enable_perfstats) { + print_sysfs("Performance stats is disabled\n"); + return count; + } + + spin_lock(&info->perf.lock); + print_sysfs("total_read_size = %llu\n", info->perf.total_read_size); + print_sysfs("total_write_size = %llu\n", info->perf.total_write_size); + print_sysfs("total_erase_blks = %llu\n\n", info->perf.total_erase_blks); + + print_sysfs("total_read_time_us = %lld\n", + ktime_to_us(info->perf.total_read_time)); + print_sysfs("total_write_time_us = %lld\n", + ktime_to_us(info->perf.total_write_time)); + print_sysfs("total_erase_time_us = %lld\n\n", + ktime_to_us(info->perf.total_erase_time)); + + print_sysfs("min_read_time_us = %lld\n", + ktime_to_us(info->perf.min_read_time)); + print_sysfs("min_write_time_us = %lld\n", + ktime_to_us(info->perf.min_write_time)); + print_sysfs("min_erase_time_us = %lld\n\n", + ktime_to_us(info->perf.min_erase_time)); + + print_sysfs("max_read_time_us = %lld\n", + ktime_to_us(info->perf.max_read_time)); + print_sysfs("max_write_time_us = %lld\n", + ktime_to_us(info->perf.max_write_time)); + print_sysfs("max_erase_time_us = %lld\n\n", + ktime_to_us(info->perf.max_erase_time)); + + spin_unlock(&info->perf.lock); + return count; +} + +static ssize_t msm_nand_attr_perf_stats_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct msm_nand_info *info = dev_get_drvdata(dev); + + if (!enable_perfstats) { + pr_err("couldn't write as perf stats is disabled\n"); + return -EPERM; + } + + if (count > 1 || (count == 1 && *buf != '\n')) { + pr_err("write not permitted\n"); + return -EPERM; + } + + spin_lock(&info->perf.lock); + info->perf.min_read_time = ktime_set(KTIME_MAX, 0); + info->perf.min_write_time = ktime_set(KTIME_MAX, 0); + info->perf.min_erase_time = ktime_set(KTIME_MAX, 0); + + info->perf.max_read_time = ktime_set(0, 0); + info->perf.max_write_time = ktime_set(0, 0); + info->perf.max_erase_time = ktime_set(0, 0); + + info->perf.total_read_time = ktime_set(0, 0); + info->perf.total_write_time = ktime_set(0, 0); + info->perf.total_erase_time = ktime_set(0, 0); + + info->perf.total_read_size = 0; + info->perf.total_write_size = 0; + info->perf.total_erase_blks = 0; + spin_unlock(&info->perf.lock); + + return count; +} + +static void msm_nand_init_perf_stats(struct msm_nand_info *info) +{ + spin_lock_init(&info->perf.lock); + info->perf.min_read_time = ktime_set(KTIME_MAX, 0); + info->perf.min_write_time = ktime_set(KTIME_MAX, 0); + info->perf.min_erase_time = ktime_set(KTIME_MAX, 0); +} + +static void msm_nand_init_sysfs(struct device *dev) +{ + sysfs_attr_init(&dev_msm_nand_perf_stats); + if (device_create_file(dev, &dev_msm_nand_perf_stats)) + pr_err("Sysfs entry create failed"); +} + +static void msm_nand_cleanup_sysfs(struct device *dev) +{ + device_remove_file(dev, &dev_msm_nand_perf_stats); +} + +static void msm_nand_update_read_perf_stats(struct msm_nand_info *info, + ktime_t start, u32 size) +{ + ktime_t time_delta; + + time_delta = ktime_sub(ktime_get(), start); + + spin_lock(&info->perf.lock); + info->perf.total_read_size += size; + info->perf.total_read_time = ktime_add(info->perf.total_read_time, + time_delta); + if (ktime_after(time_delta, info->perf.max_read_time)) + info->perf.max_read_time = time_delta; + + if (ktime_before(time_delta, info->perf.min_read_time)) + info->perf.min_read_time = time_delta; + + spin_unlock(&info->perf.lock); +} + +static void msm_nand_update_write_perf_stats(struct msm_nand_info *info, + ktime_t start, u32 size) +{ + ktime_t time_delta; + + time_delta = ktime_sub(ktime_get(), start); + + spin_lock(&info->perf.lock); + info->perf.total_write_size += size; + info->perf.total_write_time = ktime_add(info->perf.total_write_time, + time_delta); + if (ktime_after(time_delta, info->perf.max_write_time)) + info->perf.max_write_time = time_delta; + + if (ktime_before(time_delta, info->perf.min_write_time)) + info->perf.min_write_time = time_delta; + + spin_unlock(&info->perf.lock); +} + +static void msm_nand_update_erase_perf_stats(struct msm_nand_info *info, + ktime_t start, u32 count) +{ + ktime_t time_delta; + + time_delta = ktime_sub(ktime_get(), start); + + spin_lock(&info->perf.lock); + info->perf.total_erase_blks += count; + info->perf.total_erase_time = ktime_add(info->perf.total_erase_time, + time_delta); + if (ktime_after(time_delta, info->perf.max_erase_time)) + info->perf.max_erase_time = time_delta; + + if (ktime_before(time_delta, info->perf.min_erase_time)) + info->perf.min_erase_time = time_delta; + + spin_unlock(&info->perf.lock); +} /* * Get the DMA memory for requested amount of size. It returns the pointer @@ -1610,6 +1787,7 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, struct sps_iovec iovec_temp; bool erased_page; uint64_t fix_data_in_pages = 0; + ktime_t start; /* * The following 6 commands will be sent only once for the first @@ -1634,6 +1812,9 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, } *dma_buffer; struct msm_nand_rw_cmd_desc *cmd_list = NULL; + if (unlikely(enable_perfstats)) + start = ktime_get(); + memset(&rw_params, 0, sizeof(struct msm_nand_rw_params)); err = msm_nand_validate_mtd_params(mtd, true, from, ops, &rw_params); if (err) @@ -1941,6 +2122,8 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, err, ops->retlen, ops->oobretlen); pr_debug("========================================================\n"); + if (unlikely(enable_perfstats) && likely(!err)) + msm_nand_update_read_perf_stats(info, start, ops->retlen); return err; } @@ -2161,6 +2344,8 @@ static int msm_nand_write_oob(struct mtd_info *mtd, loff_t to, struct msm_nand_rw_reg_data data; struct sps_iovec *iovec; struct sps_iovec iovec_temp; + ktime_t start; + /* * The following 7 commands will be sent only once : * For first codeword (CW) - addr0, addr1, dev0_cfg0, dev0_cfg1, @@ -2184,6 +2369,9 @@ static int msm_nand_write_oob(struct mtd_info *mtd, loff_t to, } *dma_buffer; struct msm_nand_rw_cmd_desc *cmd_list = NULL; + if (unlikely(enable_perfstats)) + start = ktime_get(); + memset(&rw_params, 0, sizeof(struct msm_nand_rw_params)); err = msm_nand_validate_mtd_params(mtd, false, to, ops, &rw_params); if (err) @@ -2359,6 +2547,8 @@ static int msm_nand_write_oob(struct mtd_info *mtd, loff_t to, err, ops->retlen, ops->oobretlen); pr_debug("================================================\n"); + if (unlikely(enable_perfstats) && likely(!err)) + msm_nand_update_write_perf_stats(info, start, ops->retlen); return err; } @@ -2456,6 +2646,8 @@ static int msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr) struct msm_nand_erase_reg_data data; struct sps_iovec *iovec; struct sps_iovec iovec_temp; + ktime_t start; + /* * The following 9 commands are required to erase a page - * flash, addr0, addr1, cfg0, cfg1, exec, flash_status(read), @@ -2468,6 +2660,9 @@ static int msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr) uint32_t flash_status; } *dma_buffer; + if (unlikely(enable_perfstats)) + start = ktime_get(); + if (mtd->writesize == PAGE_SIZE_2K) page = instr->addr >> 11; @@ -2582,6 +2777,8 @@ static int msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr) mutex_unlock(&info->lock); msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer)); out: + if (unlikely(enable_perfstats) && likely(!err)) + msm_nand_update_erase_perf_stats(info, start, 1); return err; } @@ -3536,6 +3733,8 @@ static int msm_nand_probe(struct platform_device *pdev) info->nand_phys, info->bam_phys, info->bam_irq); pr_info("Allocated DMA buffer at virt_addr 0x%pK, phys_addr 0x%x\n", info->nand_chip.dma_virt_addr, info->nand_chip.dma_phys_addr); + msm_nand_init_sysfs(dev); + msm_nand_init_perf_stats(info); goto out; free_bam: msm_nand_bam_free(info); @@ -3557,6 +3756,7 @@ static int msm_nand_remove(struct platform_device *pdev) { struct msm_nand_info *info = dev_get_drvdata(&pdev->dev); + msm_nand_cleanup_sysfs(&pdev->dev); if (pm_runtime_suspended(&(pdev)->dev)) pm_runtime_resume(&(pdev)->dev); @@ -3601,6 +3801,9 @@ static struct platform_driver msm_nand_driver = { module_param(enable_euclean, bool, 0644); MODULE_PARM_DESC(enable_euclean, "Set this parameter to enable reporting EUCLEAN to upper layer when the correctable bitflips are equal to the max correctable limit."); +module_param(enable_perfstats, bool, 0644); +MODULE_PARM_DESC(enable_perfstats, "Set this parameter to enable collection and reporting of performance data."); + module_platform_driver(msm_nand_driver); MODULE_ALIAS(DRIVER_NAME); diff --git a/drivers/mtd/devices/msm_qpic_nand.h b/drivers/mtd/devices/msm_qpic_nand.h index 043c2153ccc4..f63397be2d6f 100644 --- a/drivers/mtd/devices/msm_qpic_nand.h +++ b/drivers/mtd/devices/msm_qpic_nand.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, 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 @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #define PAGE_SIZE_2K 2048 @@ -298,6 +300,23 @@ struct msm_nand_clk_data { bool rpmh_clk; }; +struct msm_nand_perf_stats { + u64 total_read_size; + u64 total_write_size; + u64 total_erase_blks; + ktime_t total_read_time; + ktime_t total_write_time; + ktime_t total_erase_time; + ktime_t min_read_time; + ktime_t min_write_time; + ktime_t min_erase_time; + ktime_t max_read_time; + ktime_t max_write_time; + ktime_t max_erase_time; + spinlock_t lock; +}; + + /* Structure that defines NANDc private data. */ struct msm_nand_info { struct mtd_info mtd; @@ -322,6 +341,7 @@ struct msm_nand_info { struct mutex lock; struct flash_identification flash_dev; struct msm_nand_clk_data clk_data; + struct msm_nand_perf_stats perf; u64 dma_mask; }; From a2e7303245187f31e1cbdc11f21d49a50002187b Mon Sep 17 00:00:00 2001 From: Xipeng Gu Date: Thu, 13 Jun 2019 20:46:07 +0800 Subject: [PATCH 012/281] mdss: mdp: Remove incorrect return value Remove incorrect return value when split mode not use, this incorrect value cause command mode pingpong timeout issue. Change-Id: I2a407930fda4932ac10b2985bae4aee6e8af8e8f Signed-off-by: Xipeng Gu --- drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index 17a0989e2a15..1c70637e6191 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -709,7 +709,6 @@ int mdss_mdp_get_split_display_ctls(struct mdss_mdp_ctl **ctl, swap(*ctl, *sctl); } } else { - rc = -EINVAL; pr_debug("%s no split mode:%d\n", __func__, (*ctl)->mfd->split_mode); } From 0a8a3e5b476235f7ef917318bd388751e7c56af2 Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Tue, 4 Jun 2019 17:01:00 -0400 Subject: [PATCH 013/281] BACKPORT: Add support for BPF_FUNC_probe_read_str Downstream kernel is missing support for this. It is needed by I/O readahead project to read strings from kernel memory on Pixel v4.9. Add support for the same. Bug: 135210418 Change-Id: I37895b395d3fd2637f1d69e111c4a6e2b8c0327a Signed-off-by: Joel Fernandes --- kernel/trace/bpf_trace.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 7cc06f267be5..c7aab158ea81 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -81,6 +81,35 @@ static const struct bpf_func_proto bpf_probe_read_proto = { .arg3_type = ARG_ANYTHING, }; +BPF_CALL_3(bpf_probe_read_str, void *, dst, u32, size, const void *, unsafe_ptr) +{ + int ret; + + /* + * The strncpy_from_unsafe() call will likely not fill the entire + * buffer, but that's okay in this circumstance as we're probing + * arbitrary memory anyway similar to bpf_probe_read() and might + * as well probe the stack. Thus, memory is explicitly cleared + * only in error case, so that improper users ignoring return + * code altogether don't copy garbage; otherwise length of string + * is returned that can be used for bpf_perf_event_output() et al. + */ + ret = strncpy_from_unsafe(dst, unsafe_ptr, size); + if (unlikely(ret < 0)) + memset(dst, 0, size); + + return ret; +} + +static const struct bpf_func_proto bpf_probe_read_str_proto = { + .func = bpf_probe_read_str, + .gpl_only = true, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_RAW_STACK, + .arg2_type = ARG_CONST_STACK_SIZE, + .arg3_type = ARG_ANYTHING, +}; + BPF_CALL_3(bpf_probe_write_user, void *, unsafe_ptr, const void *, src, u32, size) { @@ -434,6 +463,8 @@ static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id) return &bpf_map_delete_elem_proto; case BPF_FUNC_probe_read: return &bpf_probe_read_proto; + case BPF_FUNC_probe_read_str: + return &bpf_probe_read_str_proto; case BPF_FUNC_ktime_get_ns: return &bpf_ktime_get_ns_proto; case BPF_FUNC_tail_call: From 0c1ee05e1e725a8cd212677370b2edcd167ad54f Mon Sep 17 00:00:00 2001 From: Chih-Wei Huang Date: Fri, 14 Jun 2019 15:58:23 +0800 Subject: [PATCH 014/281] efi/libstub: remove duplicate nokaslr The same patch was applied twice (8fca3c364 and e3111d522). Change-Id: I2f3284d294326ec7736303374769640a1e022878 Signed-off-by: Chih-Wei Huang --- drivers/firmware/efi/libstub/efi-stub-helper.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 13c4abba8959..1c963c4d1bde 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -48,13 +48,6 @@ int __pure nokaslr(void) #define EFI_ALLOC_ALIGN EFI_PAGE_SIZE #endif -static int __section(.data) __nokaslr; - -int __pure nokaslr(void) -{ - return __nokaslr; -} - #define EFI_MMAP_NR_SLACK_SLOTS 8 struct file_info { From 41b8ec9cad02f63fe02d8ec032cfe0f3079dae45 Mon Sep 17 00:00:00 2001 From: Xipeng Gu Date: Thu, 13 Jun 2019 20:41:34 +0800 Subject: [PATCH 015/281] ARM: dts: msm: Enable RM67162 edo cmd panel on Spyro Add changes to: 1.add ldos for dsi and panel. 2.add panel properties for RM67162 edo command mode panel. Change-Id: Idc2ae4c0f361fe36a863b078ef78a7356f715a20 Signed-off-by: Xipeng Gu --- .../qcom/dsi-panel-edo-rm67162-qvga-cmd.dtsi | 4 +- .../boot/dts/qcom/msm8937-mdss-panels.dtsi | 26 ++++++- .../boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi | 15 +++- arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 78 ++++++++++++------- 4 files changed, 93 insertions(+), 30 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-edo-rm67162-qvga-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-edo-rm67162-qvga-cmd.dtsi index 286d20779a83..c48ae817d2be 100644 --- a/arch/arm64/boot/dts/qcom/dsi-panel-edo-rm67162-qvga-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/dsi-panel-edo-rm67162-qvga-cmd.dtsi @@ -44,7 +44,7 @@ 29 01 00 00 00 00 02 05 00 29 01 00 00 00 00 02 FE 00 29 01 00 00 00 00 02 35 00 - 29 01 00 00 00 00 02 51 00 + 29 01 00 00 00 00 02 51 80 29 01 00 00 00 00 02 53 20 29 01 00 00 78 00 02 11 00 29 01 00 00 05 00 02 29 00]; @@ -67,7 +67,7 @@ qcom,mdss-dsi-te-using-te-pin; qcom,mdss-dsi-panel-timings = [7d 25 1d 00 37 33 22 27 1e 03 04 00]; - qcom,mdss-dsi-t-clk-post = <0x20>; + qcom,mdss-dsi-t-clk-post = <0x09>; qcom,mdss-dsi-t-clk-pre = <0x2c>; qcom,mdss-dsi-bl-min-level = <1>; qcom,mdss-dsi-bl-max-level = <255>; diff --git a/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi index 528e8aa3025e..6f3b1ab14456 100644 --- a/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, 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 @@ -26,6 +26,7 @@ #include "dsi-panel-nt35695b-truly-fhd-video.dtsi" #include "dsi-panel-nt35695b-truly-fhd-cmd.dtsi" #include "dsi-panel-icn9706-720-1440p-video.dtsi" +#include "dsi-panel-edo-rm67162-qvga-cmd.dtsi" &soc { dsi_panel_pwr_supply: dsi_panel_pwr_supply { @@ -69,4 +70,27 @@ qcom,supply-post-on-sleep = <10>; }; }; + + dsi_pm660_panel_pwr_supply: dsi_pm660_panel_pwr_supply { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <2800000>; + qcom,supply-max-voltage = <2800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,panel-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi index 6de406df0f9a..7a0305399628 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi @@ -15,7 +15,20 @@ #include "sdm429w-pm660.dtsi" &mdss_dsi0 { - qcom,dsi-pref-prim-pan = <&dsi_hx8399c_hd_vid>; + qcom,dsi-pref-prim-pan = <&dsi_edo_rm67162_qvga_cmd>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-te-gpio = <&tlmm 24 0>; + qcom,platform-reset-gpio = <&tlmm 60 0>; + qcom,platform-enable-gpio = <&tlmm 69 0>; +}; + +&dsi_edo_rm67162_qvga_cmd { + /delete-property/ qcom,mdss-dsi-panel-timings; + qcom,mdss-dsi-panel-timings-phy-12nm = [06 05 01 01 00 03 01 03]; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,panel-supply-entries = <&dsi_pm660_panel_pwr_supply>; }; &dsi_hx8399c_hd_vid { diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index 7238e1b194ab..9d4db12beed9 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -295,32 +295,6 @@ }; }; -&mdss_dsi { - /delete-property/ vdda-supply; - /delete-property/ vddio-supply; -}; - -&mdss_dsi0 { - /delete-property/ vdd-supply; - /delete-property/ vddio-supply; - /delete-property/ bklight_en-supply; - /delete-property/ lab-supply; - /delete-property/ ibb-supply; -}; - -&mdss_dsi1 { - /delete-property/ vdd-supply; - /delete-property/ vddio-supply; -}; - -&mdss_dsi0_pll { - /delete-property/ vddio-supply; -}; - -&mdss_dsi1_pll { - /delete-property/ vddio-supply; -}; - &i2c_2 { /delete-node/ qcom,smb1355@8; /delete-node/ qcom,smb1355@c; @@ -693,3 +667,55 @@ &usb_otg { extcon = <&pm660_charger>; }; + +&mdss_dsi { + /delete-property/ vdda-supply; + /delete-property/ vddio-supply; + /delete-property/ bklight_en-supply; + /delete-property/ lab-supply; + /delete-property/ ibb-supply; + vdda-supply = <&L6A>; /* 0.8v */ + vddio-supply = <&L13A>; /* 1.8v */ + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <800000>; + qcom,supply-max-voltage = <800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <20>; + }; + }; +}; + +&mdss_dsi0 { + /delete-property/ vdd-supply; + /delete-property/ vddio-supply; + /delete-property/ bklight_en-supply; + /delete-property/ lab-supply; + /delete-property/ ibb-supply; + vdd-supply = <&L15A>;/* 2.8v */ + vddio-supply = <&L13A>; /* 1.8v */ +}; + +&mdss_dsi1 { + status = "disabled"; + /delete-property/ vdd-supply; + /delete-property/ vddio-supply; +}; + +&mdss_dsi0_pll { + /delete-property/ vddio-supply; + vddio-supply = <&L13A>;/* 1.8v */ +}; + +&mdss_dsi1_pll { + /delete-property/ vddio-supply; + vddio-supply = <&L13A>; +}; + From 33ef3ba97d399aad96fe51fdf4a7e2cd662b5479 Mon Sep 17 00:00:00 2001 From: Krishna Manikandan Date: Tue, 9 Apr 2019 17:00:41 +0530 Subject: [PATCH 016/281] drm/msm/sde: stage border fill after ctl start timeout In some error cases ctl start irq is delayed more than ctl start timeout period and it is received after programming the next commit CTL registers but before next flush. Due to this only new CTL register configuration takes effect but not the pipe configuration. This is leading to smmu fault. Staging border-fill in these cases after ctl start timeout will help prevent illegal iova 0x0 (non-configured pipe) transactions onto the bus. Change-Id: I85418df3a922a8468f31adc285fac217e8f2eee4 Signed-off-by: Raviteja Tamatam Signed-off-by: Krishna Manikandan --- drivers/gpu/drm/msm/sde/sde_crtc.c | 27 ++++++++++++++++++- drivers/gpu/drm/msm/sde/sde_encoder.c | 18 +++++++++++++ drivers/gpu/drm/msm/sde/sde_encoder.h | 7 +++++ drivers/gpu/drm/msm/sde/sde_encoder_phys.h | 2 ++ .../gpu/drm/msm/sde/sde_encoder_phys_cmd.c | 9 ++++++- 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index 2c7f7589c1d3..f8e3f23b6874 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -757,6 +757,25 @@ static bool sde_crtc_mode_fixup(struct drm_crtc *crtc, return true; } +static int _sde_crtc_get_ctlstart_timeout(struct drm_crtc *crtc) +{ + struct drm_encoder *encoder; + int rc = 0; + + if (!crtc || !crtc->dev) + return 0; + + list_for_each_entry(encoder, + &crtc->dev->mode_config.encoder_list, head) { + if (encoder->crtc != crtc) + continue; + + if (sde_encoder_get_intf_mode(encoder) == INTF_MODE_CMD) + rc += sde_encoder_get_ctlstart_timeout_state(encoder); + } + + return rc; +} static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer, struct sde_plane_state *pstate, struct sde_format *format) @@ -3184,7 +3203,13 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, if (unlikely(!sde_crtc->num_mixers)) return; - _sde_crtc_blend_setup(crtc, old_state, true); + if (_sde_crtc_get_ctlstart_timeout(crtc)) { + _sde_crtc_blend_setup(crtc, old_state, false); + SDE_ERROR("border fill only commit after ctlstart timeout\n"); + } else { + _sde_crtc_blend_setup(crtc, old_state, true); + } + _sde_crtc_dest_scaler_setup(crtc); /* cancel the idle notify delayed work */ diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c index 34777b3072a0..0237b993daaa 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder.c @@ -3229,6 +3229,24 @@ int sde_encoder_idle_request(struct drm_encoder *drm_enc) return 0; } +int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *drm_enc) +{ + struct sde_encoder_virt *sde_enc = NULL; + int i, count = 0; + + if (!drm_enc) + return 0; + + sde_enc = to_sde_encoder_virt(drm_enc); + + for (i = 0; i < sde_enc->num_phys_encs; i++) { + count += atomic_read(&sde_enc->phys_encs[i]->ctlstart_timeout); + atomic_set(&sde_enc->phys_encs[i]->ctlstart_timeout, 0); + } + + return count; +} + /** * _sde_encoder_trigger_flush - trigger flush for a physical encoder * drm_enc: Pointer to drm encoder structure diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.h b/drivers/gpu/drm/msm/sde/sde_encoder.h index a4cf4679d96b..62b0c9bef31b 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.h +++ b/drivers/gpu/drm/msm/sde/sde_encoder.h @@ -266,4 +266,11 @@ int sde_encoder_in_clone_mode(struct drm_encoder *enc); */ void sde_encoder_control_idle_pc(struct drm_encoder *enc, bool enable); +/** + * sde_encoder_get_ctlstart_timeout_state - checks if ctl start timeout happened + * @drm_enc: Pointer to drm encoder structure + * @Return: non zero value if ctl start timeout occurred + */ +int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *enc); + #endif /* __SDE_ENCODER_H__ */ diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h index 163a36d2fcb2..ab161568d1f8 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h @@ -267,6 +267,7 @@ struct sde_encoder_irq { * @pending_retire_fence_cnt: Atomic counter tracking the pending retire * fences that have to be signalled. * @pending_kickoff_wq: Wait queue for blocking until kickoff completes + * @ctlstart_timeout: Indicates if ctl start timeout occurred * @irq: IRQ tracking structures * @cont_splash_single_flush Variable to check if single flush is enabled. * @cont_splash_settings Variable to store continuous splash settings. @@ -301,6 +302,7 @@ struct sde_encoder_phys { atomic_t pending_kickoff_cnt; atomic_t pending_retire_fence_cnt; wait_queue_head_t pending_kickoff_wq; + atomic_t ctlstart_timeout; struct sde_encoder_irq irq[INTR_IDX_MAX]; u32 cont_splash_single_flush; bool cont_splash_settings; diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c index 4409408ba3fe..d6e8fd34e051 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019 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 @@ -193,6 +193,7 @@ static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) phys_enc, SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE); atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0); + atomic_set(&phys_enc->ctlstart_timeout, 0); } /* notify all synchronous clients first, then asynchronous clients */ @@ -292,6 +293,7 @@ static void sde_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx) ctl = phys_enc->hw_ctl; atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0); + atomic_set(&phys_enc->ctlstart_timeout, 0); time_diff_us = ktime_us_delta(ktime_get(), cmd_enc->rd_ptr_timestamp); @@ -1054,6 +1056,7 @@ static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc) SDE_ERROR("invalid encoder\n"); return; } + atomic_set(&phys_enc->ctlstart_timeout, 0); SDE_DEBUG_CMDENC(cmd_enc, "pp %d state %d\n", phys_enc->hw_pp->idx - PINGPONG_0, phys_enc->enable_state); @@ -1176,6 +1179,9 @@ static int _sde_encoder_phys_cmd_wait_for_ctl_start( "ctl start interrupt wait failed\n"); else ret = 0; + + if (sde_encoder_phys_cmd_is_master(phys_enc)) + atomic_inc_return(&phys_enc->ctlstart_timeout); } return ret; @@ -1476,6 +1482,7 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init( atomic_set(&phys_enc->pending_retire_fence_cnt, 0); atomic_set(&cmd_enc->pending_rd_ptr_cnt, 0); atomic_set(&cmd_enc->pending_vblank_cnt, 0); + atomic_set(&phys_enc->ctlstart_timeout, 0); init_waitqueue_head(&phys_enc->pending_kickoff_wq); init_waitqueue_head(&cmd_enc->pending_vblank_wq); atomic_set(&cmd_enc->autorefresh.kickoff_cnt, 0); From 140596ac7f467f58819073ad5bce08e5d6ca90ea Mon Sep 17 00:00:00 2001 From: Ramandeep Trehan Date: Tue, 18 Jun 2019 12:53:03 +0530 Subject: [PATCH 017/281] ARM: dts: msm: Enable qseecom for sdxpoorwills Enable qseecom driver for communication with trusted applications. Change-Id: I5409f2ec7c12728cf132b805edc5dd1cd9f925d4 Signed-off-by: Ramandeep Trehan --- arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dtsi index 629f9b8111db..c8fe49212a52 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dtsi @@ -16,6 +16,10 @@ status = "okay"; }; +&qcom_seecom { + status = "okay"; +}; + &usb { status = "okay"; qcom,connector-type-uAB; From b9dc7bb832a34591a894666f847f429afd9ead55 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Wed, 12 Jun 2019 10:29:50 -0400 Subject: [PATCH 018/281] mm: memcontrol: fix NULL pointer crash in test_clear_page_writeback() Jaegeuk and Brad report a NULL pointer crash when writeback ending tries to update the memcg stats: BUG: unable to handle kernel NULL pointer dereference at 00000000000003b0 IP: test_clear_page_writeback+0x12e/0x2c0 [...] RIP: 0010:test_clear_page_writeback+0x12e/0x2c0 Call Trace: end_page_writeback+0x47/0x70 f2fs_write_end_io+0x76/0x180 [f2fs] bio_endio+0x9f/0x120 blk_update_request+0xa8/0x2f0 scsi_end_request+0x39/0x1d0 scsi_io_completion+0x211/0x690 scsi_finish_command+0xd9/0x120 scsi_softirq_done+0x127/0x150 __blk_mq_complete_request_remote+0x13/0x20 flush_smp_call_function_queue+0x56/0x110 generic_smp_call_function_single_interrupt+0x13/0x30 smp_call_function_single_interrupt+0x27/0x40 call_function_single_interrupt+0x89/0x90 RIP: 0010:native_safe_halt+0x6/0x10 (gdb) l *(test_clear_page_writeback+0x12e) 0xffffffff811bae3e is in test_clear_page_writeback (./include/linux/memcontrol.h:619). 614 mod_node_page_state(page_pgdat(page), idx, val); 615 if (mem_cgroup_disabled() || !page->mem_cgroup) 616 return; 617 mod_memcg_state(page->mem_cgroup, idx, val); 618 pn = page->mem_cgroup->nodeinfo[page_to_nid(page)]; 619 this_cpu_add(pn->lruvec_stat->count[idx], val); 620 } 621 622 unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, 623 gfp_t gfp_mask, The issue is that writeback doesn't hold a page reference and the page might get freed after PG_writeback is cleared (and the mapping is unlocked) in test_clear_page_writeback(). The stat functions looking up the page's node or zone are safe, as those attributes are static across allocation and free cycles. But page->mem_cgroup is not, and it will get cleared if we race with truncation or migration. It appears this race window has been around for a while, but less likely to trigger when the memcg stats were updated first thing after PG_writeback is cleared. Recent changes reshuffled this code to update the global node stats before the memcg ones, though, stretching the race window out to an extent where people can reproduce the problem. Update test_clear_page_writeback() to look up and pin page->mem_cgroup before clearing PG_writeback, then not use that pointer afterward. It is a partial revert of 62cccb8c8e7a ("mm: simplify lock_page_memcg()") but leaves the pageref-holding callsites that aren't affected alone. Bug: 134442369 (Joel: added mem_cgroup_update_stat function to keep backport minimal) (Cherry-picked from 739f79fc9db1) Change-Id: I692226d6f183c11c27ed096967e6a5face3b9741 Link: http://lkml.kernel.org/r/20170809183825.GA26387@cmpxchg.org Fixes: 62cccb8c8e7a ("mm: simplify lock_page_memcg()") Signed-off-by: Johannes Weiner Reported-by: Jaegeuk Kim Tested-by: Jaegeuk Kim Reported-by: Bradley Bolen Tested-by: Brad Bolen Cc: Vladimir Davydov Cc: Michal Hocko Cc: [4.6+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Joel Fernandes --- include/linux/memcontrol.h | 36 +++++++++++++++++++++++++++++-- mm/memcontrol.c | 43 +++++++++++++++++++++++++++----------- mm/page-writeback.c | 14 ++++++++++--- 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 8b35bdbdc214..5fbbfa6ce1f2 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -490,7 +490,8 @@ bool mem_cgroup_oom_synchronize(bool wait); extern int do_swap_account; #endif -void lock_page_memcg(struct page *page); +struct mem_cgroup *lock_page_memcg(struct page *page); +void __unlock_page_memcg(struct mem_cgroup *memcg); void unlock_page_memcg(struct page *page); /** @@ -529,6 +530,27 @@ static inline void mem_cgroup_dec_page_stat(struct page *page, mem_cgroup_update_page_stat(page, idx, -1); } +static inline void mem_cgroup_update_stat(struct mem_cgroup *memcg, + enum mem_cgroup_stat_index idx, int val) +{ + VM_BUG_ON(!(rcu_read_lock_held())); + + if (memcg) + this_cpu_add(memcg->stat->count[idx], val); +} + +static inline void mem_cgroup_inc_stat(struct mem_cgroup *memcg, + enum mem_cgroup_stat_index idx) +{ + mem_cgroup_update_stat(memcg, idx, 1); +} + +static inline void mem_cgroup_dec_stat(struct mem_cgroup *memcg, + enum mem_cgroup_stat_index idx) +{ + mem_cgroup_update_stat(memcg, idx, -1); +} + unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, gfp_t gfp_mask, unsigned long *total_scanned); @@ -709,7 +731,12 @@ mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) { } -static inline void lock_page_memcg(struct page *page) +static inline struct mem_cgroup *lock_page_memcg(struct page *page) +{ + return NULL; +} + +static inline void __unlock_page_memcg(struct mem_cgroup *memcg) { } @@ -771,6 +798,11 @@ static inline void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx) { } + +static inline void mem_cgroup_dec_stat(struct mem_cgroup *memcg, + enum mem_cgroup_stat_index idx) +{ +} #endif /* CONFIG_MEMCG */ #ifdef CONFIG_CGROUP_WRITEBACK diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 86a6b331b964..8dfd048ca160 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1619,9 +1619,13 @@ bool mem_cgroup_oom_synchronize(bool handle) * @page: the page * * This function protects unlocked LRU pages from being moved to - * another cgroup and stabilizes their page->mem_cgroup binding. + * another cgroup. + * + * It ensures lifetime of the returned memcg. Caller is responsible + * for the lifetime of the page; __unlock_page_memcg() is available + * when @page might get freed inside the locked section. */ -void lock_page_memcg(struct page *page) +struct mem_cgroup *lock_page_memcg(struct page *page) { struct mem_cgroup *memcg; unsigned long flags; @@ -1630,18 +1634,24 @@ void lock_page_memcg(struct page *page) * The RCU lock is held throughout the transaction. The fast * path can get away without acquiring the memcg->move_lock * because page moving starts with an RCU grace period. - */ + * + * The RCU lock also protects the memcg from being freed when + * the page state that is going to change is the only thing + * preventing the page itself from being freed. E.g. writeback + * doesn't hold a page reference and relies on PG_writeback to + * keep off truncation, migration and so forth. + */ rcu_read_lock(); if (mem_cgroup_disabled()) - return; + return NULL; again: memcg = page->mem_cgroup; if (unlikely(!memcg)) - return; + return NULL; if (atomic_read(&memcg->moving_account) <= 0) - return; + return memcg; spin_lock_irqsave(&memcg->move_lock, flags); if (memcg != page->mem_cgroup) { @@ -1657,18 +1667,18 @@ void lock_page_memcg(struct page *page) memcg->move_lock_task = current; memcg->move_lock_flags = flags; - return; + return memcg; } EXPORT_SYMBOL(lock_page_memcg); /** - * unlock_page_memcg - unlock a page->mem_cgroup binding - * @page: the page + * __unlock_page_memcg - unlock and unpin a memcg + * @memcg: the memcg + * + * Unlock and unpin a memcg returned by lock_page_memcg(). */ -void unlock_page_memcg(struct page *page) +void __unlock_page_memcg(struct mem_cgroup *memcg) { - struct mem_cgroup *memcg = page->mem_cgroup; - if (memcg && memcg->move_lock_task == current) { unsigned long flags = memcg->move_lock_flags; @@ -1680,6 +1690,15 @@ void unlock_page_memcg(struct page *page) rcu_read_unlock(); } + +/** + * unlock_page_memcg - unlock a page->mem_cgroup binding + * @page: the page + */ +void unlock_page_memcg(struct page *page) +{ + __unlock_page_memcg(page->mem_cgroup); +} EXPORT_SYMBOL(unlock_page_memcg); /* diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 46e36366a03a..9225827230d8 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -2704,9 +2704,10 @@ EXPORT_SYMBOL(clear_page_dirty_for_io); int test_clear_page_writeback(struct page *page) { struct address_space *mapping = page_mapping(page); + struct mem_cgroup *memcg; int ret; - lock_page_memcg(page); + memcg = lock_page_memcg(page); if (mapping && mapping_use_writeback_tags(mapping)) { struct inode *inode = mapping->host; struct backing_dev_info *bdi = inode_to_bdi(inode); @@ -2734,13 +2735,20 @@ int test_clear_page_writeback(struct page *page) } else { ret = TestClearPageWriteback(page); } + + /* + * NOTE: Page might be free now! Writeback doesn't hold a page + * reference on its own, it relies on truncation to wait for + * the clearing of PG_writeback. The below can only access + * page state that is static across allocation cycles. + */ if (ret) { - mem_cgroup_dec_page_stat(page, MEM_CGROUP_STAT_WRITEBACK); + mem_cgroup_dec_stat(memcg, MEM_CGROUP_STAT_WRITEBACK); dec_node_page_state(page, NR_WRITEBACK); dec_zone_page_state(page, NR_ZONE_WRITE_PENDING); inc_node_page_state(page, NR_WRITTEN); } - unlock_page_memcg(page); + __unlock_page_memcg(memcg); return ret; } From f57f4cd66ff1adf149ee220944ae11c0d7da7f5a Mon Sep 17 00:00:00 2001 From: shaoxing Date: Wed, 12 Jun 2019 13:30:51 +0800 Subject: [PATCH 019/281] ARM: dts: msm: make LD6A Voltage vote compatible in Spyro Make LD6A voltage vote compatible between display and usb. Change-Id: Ibc8e367e55f34454ce56ee878e230e5ba376ef8f Signed-off-by: Shaoxing --- arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 2 +- arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index 9d4db12beed9..65047b2be907 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -685,7 +685,7 @@ reg = <0>; qcom,supply-name = "vdda"; qcom,supply-min-voltage = <800000>; - qcom,supply-max-voltage = <800000>; + qcom,supply-max-voltage = <930000>; qcom,supply-enable-load = <100000>; qcom,supply-disable-load = <100>; qcom,supply-post-on-sleep = <20>; diff --git a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi index 905e12804695..804900150be9 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi @@ -160,7 +160,7 @@ status = "okay"; L6A: pm660_l6: regulator-l6 { regulator-min-microvolt = <670000>; - regulator-max-microvolt = <928000>; + regulator-max-microvolt = <930000>; qcom,init-voltage = <670000>; status = "okay"; }; From b90514ba0008087497790245e669b5677ad2758a Mon Sep 17 00:00:00 2001 From: Roman Kiryanov Date: Wed, 19 Jun 2019 11:10:09 -0700 Subject: [PATCH 020/281] ANDROID: kernel: cgroup: cpuset: Add missing allocation of cpus_requested in alloc_trial_cpuset alloc_trial_cpuset missed allocation of the alloc_trial_cpuset field which caused it to be shared from the base cs provided. Once update_cpumask parsed buf into cpus_requested and updated cpus_allowed, the result were never written to cs because cs and trialcs shared the same pointer to cpus_requested and cpus_requested always matched to itself and no updates were written. This caused cpus_requested to be non-empty and cpus_allowed empty. This issue occurs only with CONFIG_CPUMASK_OFFSTACK enabled (e.g. via CONFIG_MAXSMP). Bug: 134051784 Bug: 120444281 Fixes: 4803def4e0b2 ("ANDROID: cpuset: Make cpusets restore on hotplug") Test: enable CONFIG_CPUSETS, boot and check logcat that Test: libprocessgroup does not fail with something similar to Test: AddTidToCgroup failed to write '2354'; fd=93: No space left on device Signed-off-by: Roman Kiryanov Change-Id: I866836b5c0acfde8349c250a510ee89d8d37cb8e --- kernel/cpuset.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 194e2f24841b..e0d05cffa17a 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -420,14 +420,19 @@ static struct cpuset *alloc_trial_cpuset(struct cpuset *cs) if (!alloc_cpumask_var(&trial->cpus_allowed, GFP_KERNEL)) goto free_cs; + if (!alloc_cpumask_var(&trial->cpus_requested, GFP_KERNEL)) + goto free_allowed; if (!alloc_cpumask_var(&trial->effective_cpus, GFP_KERNEL)) goto free_cpus; cpumask_copy(trial->cpus_allowed, cs->cpus_allowed); + cpumask_copy(trial->cpus_requested, cs->cpus_requested); cpumask_copy(trial->effective_cpus, cs->effective_cpus); return trial; free_cpus: + free_cpumask_var(trial->cpus_requested); +free_allowed: free_cpumask_var(trial->cpus_allowed); free_cs: kfree(trial); @@ -441,6 +446,7 @@ static struct cpuset *alloc_trial_cpuset(struct cpuset *cs) static void free_trial_cpuset(struct cpuset *trial) { free_cpumask_var(trial->effective_cpus); + free_cpumask_var(trial->cpus_requested); free_cpumask_var(trial->cpus_allowed); kfree(trial); } From 4395469838e071db673f6837bc3cb5fbcc5c1f90 Mon Sep 17 00:00:00 2001 From: Roman Kiryanov Date: Wed, 19 Jun 2019 11:11:59 -0700 Subject: [PATCH 021/281] ANDROID: kernel: cgroup: cpuset: Clear cpus_requested for empty buf update_cpumask had a special case for empty buf which did not update cpus_requested. This change reduces differences (only to parsing) in empty/non-empty codepaths to make them consistent. Bug: 120444281 Fixes: 4803def4e0b2 ("ANDROID: cpuset: Make cpusets restore on hotplug") Test: check that writes to /dev/cpuset/background/tasks Test: work as expected, e.g.: Test: echo $$ > /dev/cpuset/background/tasks Test: echo > /dev/cpuset/background/tasks Signed-off-by: Roman Kiryanov Change-Id: I49d320ea046636ec38bd23f053317abc59f64f8e --- kernel/cpuset.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/cpuset.c b/kernel/cpuset.c index e0d05cffa17a..428c8e503af1 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -957,23 +957,23 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, return -EACCES; /* - * An empty cpus_allowed is ok only if the cpuset has no tasks. + * An empty cpus_requested is ok only if the cpuset has no tasks. * Since cpulist_parse() fails on an empty mask, we special case * that parsing. The validate_change() call ensures that cpusets * with tasks have cpus. */ if (!*buf) { - cpumask_clear(trialcs->cpus_allowed); + cpumask_clear(trialcs->cpus_requested); } else { retval = cpulist_parse(buf, trialcs->cpus_requested); if (retval < 0) return retval; + } - if (!cpumask_subset(trialcs->cpus_requested, cpu_present_mask)) - return -EINVAL; + if (!cpumask_subset(trialcs->cpus_requested, cpu_present_mask)) + return -EINVAL; - cpumask_and(trialcs->cpus_allowed, trialcs->cpus_requested, cpu_active_mask); - } + cpumask_and(trialcs->cpus_allowed, trialcs->cpus_requested, cpu_active_mask); /* Nothing to do if the cpus didn't change */ if (cpumask_equal(cs->cpus_requested, trialcs->cpus_requested)) From 45d56022f1700792ee7854a1efcdbd2137ad1132 Mon Sep 17 00:00:00 2001 From: Nirmal Abraham Date: Wed, 19 Jun 2019 17:19:52 +0530 Subject: [PATCH 022/281] ARM: dts: msm: Change dynamic fps list for SDM710/845 Update the dfps list in descending order. This makes sure that the display modes send by driver to userspace will have the modes with fps value in descending order so that the first entry in the mode indicates the max framerate capability of the panel. Change-Id: I1442952b8bf1348ee429410ec3a3810bc477197f Signed-off-by: Nirmal Abraham --- arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi | 10 +++++----- arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi index 2887f380affc..400f5f7c5fca 100644 --- a/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -637,7 +637,7 @@ qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; - qcom,dsi-supported-dfps-list = <53 55 60>; + qcom,dsi-supported-dfps-list = <60 55 53>; qcom,esd-check-enabled; qcom,mdss-dsi-panel-status-check-mode = "reg_read"; qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; @@ -712,7 +712,7 @@ qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; - qcom,dsi-supported-dfps-list = <53 55 60>; + qcom,dsi-supported-dfps-list = <60 55 53>; qcom,esd-check-enabled; qcom,mdss-dsi-panel-status-check-mode = "reg_read"; qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; @@ -952,7 +952,7 @@ qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; - qcom,dsi-supported-dfps-list = <48 53 55 60>; + qcom,dsi-supported-dfps-list = <60 55 53 48>; qcom,mdss-dsi-display-timings { timing@0 { qcom,mdss-dsi-panel-phy-timings = [00 1c 05 06 0b 0c @@ -1006,7 +1006,7 @@ qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; - qcom,dsi-supported-dfps-list = <55 60>; + qcom,dsi-supported-dfps-list = <60 55>; qcom,esd-check-enabled; qcom,mdss-dsi-panel-status-check-mode = "reg_read"; qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi index 8c746e502766..7735237e95ff 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -564,7 +564,7 @@ qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; - qcom,dsi-supported-dfps-list = <53 55 60>; + qcom,dsi-supported-dfps-list = <60 55 53>; qcom,esd-check-enabled; qcom,mdss-dsi-panel-status-check-mode = "reg_read"; qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; @@ -636,7 +636,7 @@ qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; - qcom,dsi-supported-dfps-list = <53 55 60>; + qcom,dsi-supported-dfps-list = <60 55 53>; qcom,esd-check-enabled; qcom,mdss-dsi-panel-status-check-mode = "reg_read"; qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; From fd1f4cf59dd73194e2ca5102aa8614e46d5e8d90 Mon Sep 17 00:00:00 2001 From: Veerabhadrarao Badiganti Date: Wed, 19 Jun 2019 18:44:24 +0530 Subject: [PATCH 023/281] ARM: dt: qcom: Supply dll-hsr settings sdhc on sdxpoorwills Supply dll-hsr settings for eMMC and SD card on sdxpoorwills. Change-Id: I0cc5add94505a056ed84a23fe6b72e31654fb506 Signed-off-by: Veerabhadrarao Badiganti --- arch/arm/boot/dts/qcom/sdxpoorwills.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi index fa37005d1c5d..582afa6eb0a7 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi @@ -588,6 +588,9 @@ qcom,restore-after-cx-collapse; + /* DLL HSR settings. Refer go/hsr - DLL settings */ + qcom,dll-hsr-list = <0x0007642c 0x0 0x10 0x2c010800 0x80040868>; + status = "disabled"; }; From 2d521c8d764ea0429533ede0301c7ab23580f806 Mon Sep 17 00:00:00 2001 From: Rajesha Kini Date: Wed, 19 Jun 2019 23:10:09 +0530 Subject: [PATCH 024/281] ARM: dts: msm: Add support for audio in SA415M CCARD Add support for audio in SA415M CCARD using the TLV320AIC3x codec. Change-Id: I83ed8a2507693fb4d427f1a4739995b37e9d9b48 Signed-off-by: Rajesha Kini Signed-off-by: Gustavo Solaira --- .../bindings/sound/qcom-audio-dev.txt | 71 ++++++++++++++++ .../arm/boot/dts/qcom/sdxpoorwills-ccard.dtsi | 80 +++++++++++++++++++ 2 files changed, 151 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt index a37bb61a7edc..e939e8ca9798 100644 --- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt @@ -2587,6 +2587,77 @@ Example: "msm-dai-q6-auxpcm.2"; }; +* SDX ASoC Auto Machine driver + +Required properties: +- compatible : "qcom,sdx-asoc-snd-auto" +- qcom,model : The user-visible name of this sound card. +- qcom,prim_mi2s_aux_master : Handle to prim_master pinctrl configurations +- qcom,prim_mi2s_aux_slave : Handle to prim_slave pinctrl configurations +- qcom,sec_mi2s_aux_master : Handle to sec_master pinctrl configurations +- qcom,sec_mi2s_aux_slave : Handle to sec_slave pinctrl configurations +- asoc-platform: This is phandle list containing the references to platform device + nodes that are used as part of the sound card dai-links. +- asoc-platform-names: This property contains list of platform names. The order of + the platform names should match to that of the phandle order + given in "asoc-platform". +- asoc-cpu: This is phandle list containing the references to cpu dai device nodes + that are used as part of the sound card dai-links. +- asoc-cpu-names: This property contains list of cpu dai names. The order of the + cpu dai names should match to that of the phandle order give + in "asoc-cpu". The cpu names are in the form of "%s.%d" form, + where the id (%d) field represents the back-end AFE port id that + this CPU dai is associated with. +- asoc-codec: This is phandle list containing the references to codec dai device + nodes that are used as part of the sound card dai-links. +- asoc-codec-names: This property contains list of codec dai names. The order of the + codec dai names should match to that of the phandle order given + in "asoc-codec". + +Example: + + sound-auto { + compatible = "qcom,sdx-asoc-snd-auto"; + qcom,model = "sdx-auto-i2s-snd-card"; + qcom,prim_mi2s_aux_master = <&prim_master>; + qcom,prim_mi2s_aux_slave = <&prim_slave>; + qcom,sec_mi2s_aux_master = <&sec_master>; + qcom,sec_mi2s_aux_slave = <&sec_slave>; + + asoc-platform = <&pcm0>, <&pcm1>, <&voip>, <&voice>, + <&loopback>, <&hostless>, <&afe>, <&routing>, + <&pcm_dtmf>, <&host_pcm>, <&compress>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", + "msm-voip-dsp", "msm-pcm-voice", + "msm-pcm-loopback", "msm-pcm-hostless", + "msm-pcm-afe", "msm-pcm-routing", + "msm-pcm-dtmf", "msm-voice-host-pcm", + "msm-compress-dsp"; + asoc-cpu = <&dai_pri_auxpcm>, <&mi2s_prim>, <&mi2s_sec>, + <&dtmf_tx>, + <&rx_capture_tx>, <&rx_playback_rx>, + <&tx_capture_tx>, <&tx_playback_rx>, + <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>, + <&afe_proxy_tx>, <&incall_record_rx>, + <&incall_record_tx>, <&incall_music_rx>, + <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>, + <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>, + <&dai_sec_auxpcm>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", + "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-stub-dev.4", "msm-dai-stub-dev.5", + "msm-dai-stub-dev.6", "msm-dai-stub-dev.7", + "msm-dai-stub-dev.8", "msm-dai-q6-dev.224", + "msm-dai-q6-dev.225", "msm-dai-q6-dev.241", + "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", + "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", + "msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36865", + "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881", + "msm-dai-q6-auxpcm.2"; + asoc-codec = <&tlv320aic3x_codec>, <&stub_codec>; + asoc-codec-names = "tlv320aic3x-codec", "msm-stub-codec.1"; + }; + * APQ8096 Automotive ASoC Machine driver Required properties: diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-ccard.dtsi index 0ad0e0bd2da8..d327aa35e437 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills-ccard.dtsi @@ -37,6 +37,17 @@ reg = <0x86400000 0x9300000>; }; +&i2c_3 { + tlv320aic3x_codec: tlv320aic3x@18 { + compatible = "ti,tlv320aic3x"; + reg = <0x18>; + gpio-reset = <&tlmm 86 0>; + reset-inverted; + AVDD-supply = <&codec_vreg>; + IOVDD-supply = <&codec_vreg>; + }; +}; + &i2c_4 { asm330@6a { reg = <0x6b>; @@ -59,6 +70,10 @@ status = "disabled"; }; +&clock_audio_up { + status = "disabled"; +}; + &smb138x { status = "disabled"; }; @@ -70,3 +85,68 @@ &vreg_wlan { gpio = <&tlmm 81 GPIO_ACTIVE_HIGH>; }; + +&soc { + snd_tlv3x: sound-auto { + compatible = "qcom,sdx-asoc-snd-auto"; + qcom,model = "sdx-auto-i2s-snd-card"; + qcom,prim_mi2s_aux_master = <&prim_master>; + qcom,prim_mi2s_aux_slave = <&prim_slave>; + qcom,sec_mi2s_aux_master = <&sec_master>; + qcom,sec_mi2s_aux_slave = <&sec_slave>; + + pinctrl-names = "default"; + pinctrl-0 = <&a2b_cdc_sel_default>, <&i2s_mclk_active>; + + asoc-platform = <&pcm0>, <&pcm1>, <&voip>, <&voice>, + <&loopback>, <&hostless>, <&afe>, <&routing>, + <&pcm_dtmf>, <&host_pcm>, <&compress>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", + "msm-voip-dsp", "msm-pcm-voice", + "msm-pcm-loopback", "msm-pcm-hostless", + "msm-pcm-afe", "msm-pcm-routing", + "msm-pcm-dtmf", "msm-voice-host-pcm", + "msm-compress-dsp"; + asoc-cpu = <&dai_pri_auxpcm>, <&mi2s_prim>, <&mi2s_sec>, + <&dtmf_tx>, + <&rx_capture_tx>, <&rx_playback_rx>, + <&tx_capture_tx>, <&tx_playback_rx>, + <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>, + <&afe_proxy_tx>, <&incall_record_rx>, + <&incall_record_tx>, <&incall_music_rx>, + <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>, + <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>, + <&dai_sec_auxpcm>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", + "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-stub-dev.4", "msm-dai-stub-dev.5", + "msm-dai-stub-dev.6", "msm-dai-stub-dev.7", + "msm-dai-stub-dev.8", "msm-dai-q6-dev.224", + "msm-dai-q6-dev.225", "msm-dai-q6-dev.241", + "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", + "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", + "msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36865", + "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881", + "msm-dai-q6-auxpcm.2"; + asoc-codec = <&tlv320aic3x_codec>, <&stub_codec>; + asoc-codec-names = "tlv320aic3x-codec", "msm-stub-codec.1"; + }; + + codec_vreg: regulator-codec-tlv320aic3x { + compatible = "regulator-fixed"; + regulator-name = "codec_vreg"; + startup-delay-us = <100>; + gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&pmxpoorwills_gpios { + a2b_cdc_sel { + a2b_cdc_sel_default: a2b_cdc_sel_default { + pins = "gpio1"; + power-source = <1>; + output-high; + }; + }; +}; From 9388e783bb0524a6f7d0dec02be38ece20465d5f Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Tue, 23 Apr 2019 19:27:58 +0530 Subject: [PATCH 025/281] msm: ipa: Fix not asserting BIT40 BIT40 is used to differentiate the accesses over PCIe from IPA. It is not required to assert BIT40 when updating to host as it can become an invalid address at host. Make a change to not assert BIT40 when updating rp to host. Change-Id: I88a43f2a07959f03025b253b0968757a7ec4d169 Signed-off-by: Chaitanya Pratapa --- .../msm/ipa/ipa_clients/ipa_mhi_client.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c b/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c index 10d34ea3321b..7c9738178eeb 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c @@ -73,6 +73,12 @@ #define IPA_MHI_CLIENT_HOST_ADDR_COND(addr) \ ((ipa_mhi_client_ctx->assert_bit40)?(IPA_MHI_HOST_ADDR(addr)):(addr)) +/* De-assert bit #40 in address when updating to host. */ +#define IPA_MHI_HOST_UPDATE(addr) ((addr) & ~(BIT_ULL(40))) + +#define IPA_MHI_CLIENT_HOST_ADDR_UPDATE(addr) \ + ((ipa_mhi_client_ctx->assert_bit40)?(IPA_MHI_HOST_UPDATE(addr)):(addr)) + enum ipa_mhi_rm_state { IPA_MHI_RM_STATE_RELEASED, IPA_MHI_RM_STATE_REQUESTED, @@ -1338,8 +1344,13 @@ static int ipa_mhi_suspend_gsi_channel(struct ipa_mhi_channel_ctx *channel) } /* check if channel was stopped completely */ - if (res) + if (res) { channel->stop_in_proc = true; + } else { + /* Dump RP/WP. */ + ipa_mhi_query_ch_info(channel->client, + &channel->ch_info); + } IPA_MHI_DBG("GSI channel is %s\n", (channel->stop_in_proc) ? "STOP_IN_PROC" : "STOP"); @@ -2017,7 +2028,8 @@ static void ipa_mhi_update_host_ch_state(bool update_rp) ipa_assert(); return; } - + channel->ch_info.rp = + IPA_MHI_CLIENT_HOST_ADDR_UPDATE(channel->ch_info.rp); res = ipa_mhi_read_write_host(IPA_MHI_DMA_TO_HOST, &channel->ch_info.rp, channel->channel_context_addr + @@ -2055,6 +2067,8 @@ static void ipa_mhi_update_host_ch_state(bool update_rp) return; } + channel->ch_info.rp = + IPA_MHI_CLIENT_HOST_ADDR_UPDATE(channel->ch_info.rp); res = ipa_mhi_read_write_host(IPA_MHI_DMA_TO_HOST, &channel->ch_info.rp, channel->channel_context_addr + From b6a4669e30e78d962c54a52113b8a628169f6593 Mon Sep 17 00:00:00 2001 From: Archana Sriram Date: Mon, 21 Jan 2019 15:17:32 +0530 Subject: [PATCH 026/281] msm: kgsl: Change data type for GPU ib vote Change data type for gpu ib vote to unsigned long to suit the bw vote data type in devfreq governor functions. Change-Id: I6aeb201ee67d111ee527c17e051b5125968a9683 Signed-off-by: Archana Sriram --- drivers/gpu/msm/kgsl_pwrctrl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index d6fc98b0f10f..85e1bf8531ea 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -64,7 +64,7 @@ static const char * const clocks[] = { "ahb_clk" }; -static unsigned int ib_votes[KGSL_MAX_BUSLEVELS]; +static unsigned long ib_votes[KGSL_MAX_BUSLEVELS]; static int last_vote_buslevel; static int max_vote_buslevel; @@ -127,7 +127,7 @@ static void _record_pwrevent(struct kgsl_device *device, /** * kgsl_get_bw() - Return latest msm bus IB vote */ -static unsigned int kgsl_get_bw(void) +static unsigned long kgsl_get_bw(void) { return ib_votes[last_vote_buslevel]; } @@ -141,8 +141,8 @@ static unsigned int kgsl_get_bw(void) static void _ab_buslevel_update(struct kgsl_pwrctrl *pwr, unsigned long *ab) { - unsigned int ib = ib_votes[last_vote_buslevel]; - unsigned int max_bw = ib_votes[max_vote_buslevel]; + unsigned long ib = ib_votes[last_vote_buslevel]; + unsigned long max_bw = ib_votes[max_vote_buslevel]; if (!ab) return; From b253ec13105020c0b0e4ed275dd7ed6d374d2909 Mon Sep 17 00:00:00 2001 From: Fei Date: Fri, 21 Jun 2019 15:24:42 +0800 Subject: [PATCH 027/281] input: touchscreen: cyttsp5: fix gesture wakeup issue The gesture report size is not 4 bytes by default. After fix this, touch gesture wakeup works. Change-Id: I7a8d0b8cacd596ef69551cef75e9bdbcbf159245 Signed-off-by: Fei --- .../input/touchscreen/cyttsp5/cyttsp5_core.c | 157 ++++++++++++------ .../cyttsp5/cyttsp5_device_access.c | 2 +- .../touchscreen/cyttsp5/cyttsp5_mt_common.c | 16 +- .../input/touchscreen/cyttsp5/cyttsp5_regs.h | 2 + 4 files changed, 124 insertions(+), 53 deletions(-) diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c index a8f1df3b1aa6..ef4bf38d32f2 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c @@ -3614,7 +3614,8 @@ static void cyttsp5_watchdog_work(struct work_struct *work) struct cyttsp5_core_data *cd = container_of(work, struct cyttsp5_core_data, watchdog_work); - int rc; + int rc = 0; + /*fix CDT207254 *if found the current sleep_state is SS_SLEEPING *then no need to request_exclusive, directly return @@ -3768,6 +3769,7 @@ static int cyttsp5_core_sleep_(struct cyttsp5_core_data *cd) mutex_lock(&cd->system_lock); cd->sleep_state = SS_SLEEP_ON; + cd->large_power_state = 0; mutex_unlock(&cd->system_lock); return rc; @@ -3801,13 +3803,11 @@ static int cyttsp5_wakeup_host(struct cyttsp5_core_data *cd) /* TSG5 EasyWake */ int rc = 0; int event_id; - int size = get_unaligned_le16(&cd->input_buf[0]); /* Validate report */ - if (size != 4 || cd->input_buf[2] != 4) + if (cd->input_buf[2] != 4) rc = -EINVAL; - cd->wake_initiated_by_device = 1; event_id = cd->input_buf[3]; parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: e=%d, rc=%d\n", @@ -3818,6 +3818,21 @@ static int cyttsp5_wakeup_host(struct cyttsp5_core_data *cd) goto exit; } + if (event_id != 3 && event_id != 0xAA) { + dev_err(cd->dev, "do not wake up by filter\n"); + if (event_id == GESTURE_SINGLE_QUICK_CALL) + goto callcb; + else + goto exit; + } + + if (cd->wake_initiated_by_device == 1) { + dev_dbg(cd->dev, "%s: try to re-send power key\n", __func__); + goto exit; + } + cd->wake_initiated_by_device = 1; + +callcb: /* attention WAKE */ call_atten_cb(cd, CY_ATTEN_WAKE, 0); exit: @@ -4094,9 +4109,24 @@ static int cyttsp5_read_input(struct cyttsp5_core_data *cd) read: rc = cyttsp5_adap_read_default_nosize(cd, cd->input_buf, CY_MAX_INPUT); if (rc) { - dev_err(dev, "%s: Error getting report, r=%d\n", - __func__, rc); + dev_err(dev, "%s: Error getting report, r=%d\n", __func__, rc); + #ifdef PATCH_WAKEUP_NACK_ISSUE + if (cd->sleep_state == SS_SLEEP_ON) { + cd->input_buf[0] = 0x07; + cd->input_buf[1] = 0x00; + cd->input_buf[2] = 0x04; + cd->input_buf[3] = 0xAA; + cd->input_buf[4] = 0x00; + cd->input_buf[5] = 0x00; + cd->input_buf[6] = 0x00; + dev_info(dev, "Self recover for I2C Bus err\n"); + rc = 0; + } else + return rc; + + #else return rc; + #endif } parade_debug(dev, DEBUG_LEVEL_2, "%s: Read input successfully\n", __func__); @@ -4805,38 +4835,6 @@ static void cyttsp5_startup_work_function(struct work_struct *work) __func__, rc); } -/* - * CONFIG_PM_RUNTIME option is removed in 3.19.0. - */ - -static int cyttsp5_core_rt_suspend(struct device *dev) -{ - struct cyttsp5_core_data *cd = dev_get_drvdata(dev); - int rc; - - rc = cyttsp5_core_sleep(cd); - if (rc < 0) { - dev_err(dev, "%s: Error on sleep\n", __func__); - return -EAGAIN; - } - return 0; -} - -static int cyttsp5_core_rt_resume(struct device *dev) -{ - struct cyttsp5_core_data *cd = dev_get_drvdata(dev); - int rc; - - rc = cyttsp5_core_wake(cd); - if (rc < 0) { - dev_err(dev, "%s: Error on wake\n", __func__); - return -EAGAIN; - } - - return 0; -} - - #if defined(CONFIG_PM_SLEEP) static int cyttsp5_core_suspend(struct device *dev) { @@ -4851,18 +4849,24 @@ static int cyttsp5_core_suspend(struct device *dev) * This will not prevent resume * Required to prevent interrupts before i2c awake */ - disable_irq(cd->irq); - cd->irq_disabled = 1; + + /* + * disable_irq(cd->irq); + * cd->irq_disabled = 1; + */ if (device_may_wakeup(dev)) { parade_debug(dev, DEBUG_LEVEL_2, "%s Device MAY wakeup\n", __func__); - if (!enable_irq_wake(cd->irq)) + if (!enable_irq_wake(cd->irq)) { cd->irq_wake = 1; + dev_info(dev, "suspend irq - cd->irq_wake = 1\n"); + } } else parade_debug(dev, DEBUG_LEVEL_1, "%s Device MAY NOT wakeup\n", __func__); + cd->forbit_bigobject = 0; return 0; } @@ -4877,10 +4881,13 @@ static int cyttsp5_core_resume(struct device *dev) * I2C bus pm does not call suspend if device runtime suspended * This flag is cover that case */ - if (cd->irq_disabled) { - enable_irq(cd->irq); - cd->irq_disabled = 0; - } + + /* + * if (cd->irq_disabled) { + * enable_irq(cd->irq); + * cd->irq_disabled = 0; + * } + */ if (device_may_wakeup(dev)) { parade_debug(dev, DEBUG_LEVEL_2, "%s Device MAY wakeup\n", @@ -4925,10 +4932,25 @@ static int cyttsp5_pm_notifier(struct notifier_block *nb, } #endif +#ifdef USE_FB_SUSPEND_RESUME +static int cyttsp5_temp_suspend(struct device *dev) +{ + return 0; +} + +static int cyttsp5_temp_resume(struct device *dev) +{ + return 0; +} +#endif + const struct dev_pm_ops cyttsp5_pm_ops = { +#ifdef USE_FB_SUSPEND_RESUME + //SET_SYSTEM_SLEEP_PM_OPS(cyttsp5_core_suspend, cyttsp5_core_resume) + SET_SYSTEM_SLEEP_PM_OPS(cyttsp5_temp_suspend, cyttsp5_temp_resume) +#else SET_SYSTEM_SLEEP_PM_OPS(cyttsp5_core_suspend, cyttsp5_core_resume) - SET_RUNTIME_PM_OPS(cyttsp5_core_rt_suspend, cyttsp5_core_rt_resume, - NULL) +#endif }; EXPORT_SYMBOL_GPL(cyttsp5_pm_ops); @@ -5461,7 +5483,7 @@ static ssize_t cyttsp5_platform_data_show(struct device *dev, struct cyttsp5_platform_data *pdata = dev_get_platdata(dev); ssize_t ret; - ret = snprintf(buf, PAGE_SIZE, + ret = snprintf(buf, CY_MAX_PRBUF_SIZE, "%s: %d\n" "%s: %d\n" "%s: %d\n" @@ -5489,6 +5511,37 @@ static ssize_t cyttsp5_platform_data_show(struct device *dev, return ret; } +static ssize_t cyttsp5_bigobjectoff_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int data; + int error; + struct cyttsp5_core_data *cd = dev_get_drvdata(dev); + + error = kstrtoint(buf, 10, &data); + if (error < 0) + return error; + + if (data != 0) + cd->forbit_bigobject = 1; + else + cd->forbit_bigobject = 0; + + pr_info("cyttsp5_bigobjectoff_store forbitobject:%d\n", + cd->forbit_bigobject); + return count; +} + +static ssize_t cyttsp5_bigobjectoff_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cyttsp5_core_data *cd = dev_get_drvdata(dev); + ssize_t ret; + + ret = snprintf(buf, CY_MAX_PRBUF_SIZE, "%d\n", cd->forbit_bigobject); + return ret; +} + static struct device_attribute attributes[] = { __ATTR(ic_ver, 0444, cyttsp5_ic_ver_show, NULL), __ATTR(drv_ver, 0444, cyttsp5_drv_ver_show, NULL), @@ -5509,6 +5562,9 @@ static struct device_attribute attributes[] = { #endif __ATTR(panel_id, 0444, cyttsp5_panel_id_show, NULL), __ATTR(platform_data, 0444, cyttsp5_platform_data_show, NULL), + __ATTR(bigobject_off, 0600, + cyttsp5_bigobjectoff_show, + cyttsp5_bigobjectoff_store), }; static int add_sysfs_interfaces(struct device *dev) @@ -5563,15 +5619,14 @@ static ssize_t cyttsp5_ttdl_restart_store(struct device *dev, #endif rc = cyttsp5_probe(cyttsp5_bus_ops_save, &client->dev, client->irq, - 512); + 512); if (!rc) { is_cyttsp5_probe_success = true; dev_err(dev, "%s restart successful\n", __func__); } else { is_cyttsp5_probe_success = false; - dev_err(dev, "%s: ttdl restart failed r=%d\n", - __func__, rc); + dev_err(dev, "%s: ttdl restart failed r=%d\n", __func__, rc); } #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c index 2cdea6fad07c..59bf31a8bf17 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c @@ -4885,7 +4885,7 @@ static void cyttsp5_cmcp_parse_threshold_file(const struct firmware *fw, cyttsp5_get_device_access_data(dev); if (!fw) { - dev_info(dev, "%s: No builtin cmcp threshold file\n", __func__); + dev_dbg(dev, "%s: No builtin cmcp threshold file\n", __func__); goto exit; } diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c index 69fe9979d62c..62f92c34ba0f 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c @@ -312,6 +312,7 @@ static void cyttsp5_get_mt_touches(struct cyttsp5_mt_data *md, static int cyttsp5_xy_worker(struct cyttsp5_mt_data *md) { struct device *dev = md->dev; + struct cyttsp5_core_data *cd = dev_get_drvdata(dev); struct cyttsp5_sysinfo *si = md->si; int max_tch = si->sensing_conf_data.max_tch; struct cyttsp5_touch tch; @@ -332,6 +333,19 @@ static int cyttsp5_xy_worker(struct cyttsp5_mt_data *md) __func__); if (md->pdata->flags & CY_MT_FLAG_NO_TOUCH_ON_LO) num_cur_tch = 0; + + if (tch.hdr[CY_TCH_LO] && cd->large_power_state != 1) { + dev_info(dev, + "%s: Large area detected forbitobject:%d\n", + __func__, cd->forbit_bigobject); + if (cd->forbit_bigobject != 1) { + input_report_key(md->input, KEY_POWER, 1); + input_sync(md->input); + input_report_key(md->input, KEY_POWER, 0); + input_sync(md->input); + cd->large_power_state = 1; + } + } } if (num_cur_tch == 0 && md->num_prv_rec == 0) @@ -359,7 +373,7 @@ static void cyttsp5_mt_send_dummy_event(struct cyttsp5_core_data *cd, u8 key_value = 0; - dev_err(cd->dev, "%s report_id:%X\n", __func__, cd->input_buf[2]); + dev_dbg(cd->dev, "%s report_id:%X\n", __func__, cd->input_buf[2]); switch (cd->input_buf[3]) { case GESTURE_DOUBLE_TAP: diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h b/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h index 933daaefd537..4fb6ae3cc55a 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h @@ -67,6 +67,7 @@ /* #define EASYWAKE_TSG6 */ +#define CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_BINARY_FW_UPGRADE #define CY_FW_FILE_PREFIX "cyttsp5_fw" #define CY_FW_FILE_SUFFIX ".bin" @@ -1025,6 +1026,7 @@ struct cyttsp5_core_data { u8 debug_level; u32 watchdog_interval; u8 show_timestamp; + int forbit_bigobject; }; struct gd_sensor { From d18ec1766d8b4d3b6ac0d75bcb12923ff4adbc66 Mon Sep 17 00:00:00 2001 From: Xipeng Gu Date: Wed, 19 Jun 2019 17:46:10 +0800 Subject: [PATCH 028/281] ARM: dts: msm: add idle mode switch Add RM67162 panel idle mode switch. Change-Id: Ib40b1c4f4cf1223992dd3353d70271f385a8d760 Signed-off-by: Xipeng Gu --- .../boot/dts/qcom/dsi-panel-edo-rm67162-qvga-cmd.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-edo-rm67162-qvga-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-edo-rm67162-qvga-cmd.dtsi index c48ae817d2be..2cc77aefec29 100644 --- a/arch/arm64/boot/dts/qcom/dsi-panel-edo-rm67162-qvga-cmd.dtsi +++ b/arch/arm64/boot/dts/qcom/dsi-panel-edo-rm67162-qvga-cmd.dtsi @@ -54,6 +54,15 @@ 05 01 00 00 14 00 02 4F 01]; qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-idle-on-command = [ + 15 01 00 00 00 00 02 FE 00 + 05 01 00 00 00 00 01 39 /* Idle-Mode On */ + ]; + qcom,mdss-dsi-idle-off-command = [ + 05 01 00 00 00 00 01 38 /* Idle-Mode Off */ + ]; + qcom,mdss-dsi-idle-on-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-idle-off-command-state = "dsi_lp_mode"; qcom,mdss-dsi-h-sync-pulse = <1>; qcom,mdss-dsi-traffic-mode = "burst_mode"; qcom,mdss-dsi-lane-map = "lane_map_0123"; From 607c64ef7027ba94fe71bf44739bf70f6ebfeeea Mon Sep 17 00:00:00 2001 From: Xipeng Gu Date: Fri, 21 Jun 2019 18:12:04 +0800 Subject: [PATCH 029/281] ARM: dts: msm: Fix incorrect timing of dsi Add correct timing of dsi. Change-Id: Ic7edcb28b8d90c703edbdcf3acdd0e86eaac0674 Signed-off-by: Xipeng Gu --- arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi index 7a0305399628..b5a22f9abf73 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi @@ -26,7 +26,7 @@ &dsi_edo_rm67162_qvga_cmd { /delete-property/ qcom,mdss-dsi-panel-timings; - qcom,mdss-dsi-panel-timings-phy-12nm = [06 05 01 01 00 03 01 03]; + qcom,mdss-dsi-panel-timings-phy-12nm = [06 05 01 0A 00 03 01 0F]; qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; qcom,panel-supply-entries = <&dsi_pm660_panel_pwr_supply>; }; From 15c93be13aba8391370615d9dc08b2bee67f1582 Mon Sep 17 00:00:00 2001 From: Atul Raut Date: Tue, 9 Apr 2019 22:35:51 -0700 Subject: [PATCH 030/281] soc: qcom: boot_stats: Enable marker for atomic context Add support to atomic context Change-Id: Id81def21a51d141f156c8c83893bd50a37697dd4 Acked-by: Lakshit Tyagi Signed-off-by: Atul Raut --- drivers/soc/qcom/boot_marker.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/soc/qcom/boot_marker.c b/drivers/soc/qcom/boot_marker.c index b7a442c84a98..c506aa3cd5a4 100644 --- a/drivers/soc/qcom/boot_marker.c +++ b/drivers/soc/qcom/boot_marker.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -35,7 +35,7 @@ struct boot_marker { char marker_name[BOOT_MARKER_MAX_LEN]; unsigned long long int timer_value; struct list_head list; - struct mutex lock; + spinlock_t slock; }; static struct dentry *dent_bkpi, *dent_bkpi_status, *dent_mpm_timer; @@ -51,7 +51,7 @@ static void _create_boot_marker(const char *name, ((timer_value % TIMER_KHZ) * 1000) / TIMER_KHZ); - new_boot_marker = kmalloc(sizeof(*new_boot_marker), GFP_KERNEL); + new_boot_marker = kmalloc(sizeof(*new_boot_marker), GFP_ATOMIC); if (!new_boot_marker) return; @@ -59,9 +59,9 @@ static void _create_boot_marker(const char *name, sizeof(new_boot_marker->marker_name)); new_boot_marker->timer_value = timer_value; - mutex_lock(&boot_marker_list.lock); + spin_lock(&boot_marker_list.slock); list_add_tail(&(new_boot_marker->list), &(boot_marker_list.list)); - mutex_unlock(&boot_marker_list.lock); + spin_unlock(&boot_marker_list.slock); } static void set_bootloader_stats(void) @@ -98,7 +98,7 @@ static ssize_t bootkpi_reader(struct file *fp, char __user *user_buffer, if (!buf) return -ENOMEM; - mutex_lock(&boot_marker_list.lock); + spin_lock(&boot_marker_list.slock); list_for_each_entry(marker, &boot_marker_list.list, list) { temp += scnprintf(buf + temp, PAGE_SIZE - temp, "%-41s:%llu.%03llu seconds\n", @@ -107,7 +107,7 @@ static ssize_t bootkpi_reader(struct file *fp, char __user *user_buffer, (((marker->timer_value % TIMER_KHZ) * 1000) / TIMER_KHZ)); } - mutex_unlock(&boot_marker_list.lock); + spin_unlock(&boot_marker_list.slock); rc = simple_read_from_buffer(user_buffer, count, position, buf, temp); kfree(buf); return rc; @@ -211,7 +211,7 @@ static int __init init_bootkpi(void) } INIT_LIST_HEAD(&boot_marker_list.list); - mutex_init(&boot_marker_list.lock); + spin_lock_init(&boot_marker_list.slock); set_bootloader_stats(); return 0; } @@ -223,13 +223,13 @@ static void __exit exit_bootkpi(void) struct boot_marker *temp_addr; debugfs_remove_recursive(dent_bkpi); - mutex_lock(&boot_marker_list.lock); + spin_lock(&boot_marker_list.slock); list_for_each_entry_safe(marker, temp_addr, &boot_marker_list.list, list) { list_del(&marker->list); kfree(marker); } - mutex_unlock(&boot_marker_list.lock); + spin_unlock(&boot_marker_list.slock); boot_stats_exit(); } module_exit(exit_bootkpi); From f3883f9049c6ad2bebd868d6ba2de0177fa7a25e Mon Sep 17 00:00:00 2001 From: Rajasekaran Kalidoss Date: Tue, 16 Oct 2018 19:30:14 +0530 Subject: [PATCH 031/281] cnss2: Update WLAN composite USB I/F number for QCN7605 For QCN7605 composite usb ,the WLAN interface number is 2. update this number to register CNSS as driver for WLAN I/F. Change-Id: I8dd97d18bf57e4268f194f846ad7c2e7b77afe50 Signed-off-by: Rajasekaran Kalidoss --- drivers/net/wireless/cnss2/usb.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/cnss2/usb.c b/drivers/net/wireless/cnss2/usb.c index 6cf5aaea1b37..60d81b10cc84 100644 --- a/drivers/net/wireless/cnss2/usb.c +++ b/drivers/net/wireless/cnss2/usb.c @@ -185,7 +185,8 @@ int cnss_usb_call_driver_remove(struct cnss_usb_data *usb_priv) } static struct usb_driver cnss_usb_driver; -#define QCN7605_WLAN_INTERFACE_NUM 0x0000 +#define QCN7605_WLAN_STANDALONE_INTERFACE_NUM 0x0000 +#define QCN7605_WLAN_COMPOSITE_INTERFACE_NUM 0x0002 static int cnss_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) @@ -207,15 +208,6 @@ static int cnss_usb_probe(struct usb_interface *interface, goto out; } - if (interface->cur_altsetting->desc.bInterfaceNumber == - QCN7605_WLAN_INTERFACE_NUM) { - if (usb_driver_claim_interface(&cnss_usb_driver, - interface, - NULL)) { - ret = -ENODEV; - goto reset_priv; - } - } bcd_device = le16_to_cpu(usb_dev->descriptor.bcdDevice); usb_priv->plat_priv = plat_priv; usb_priv->usb_intf = interface; @@ -256,7 +248,6 @@ static int cnss_usb_probe(struct usb_interface *interface, cnss_unregister_subsys(plat_priv); reset_ctx: plat_priv->bus_priv = NULL; -reset_priv: devm_kfree(&usb_dev->dev, usb_priv); out: return ret; @@ -317,15 +308,13 @@ static int cnss_usb_reset_resume(struct usb_interface *interface) } static struct usb_device_id cnss_usb_id_table[] = { - { USB_DEVICE_AND_INTERFACE_INFO(QCN7605_USB_VENDOR_ID, - QCN7605_COMPOSITE_PRODUCT_ID, - QCN7605_WLAN_INTERFACE_NUM, - 0xFF, 0xFF) }, - { USB_DEVICE_AND_INTERFACE_INFO(QCN7605_USB_VENDOR_ID, - QCN7605_STANDALONE_PRODUCT_ID, - QCN7605_WLAN_INTERFACE_NUM, - 0xFF, 0xFF) }, - {} /* Terminating entry */ + { USB_DEVICE_INTERFACE_NUMBER(QCN7605_USB_VENDOR_ID, + QCN7605_COMPOSITE_PRODUCT_ID, + QCN7605_WLAN_COMPOSITE_INTERFACE_NUM) }, + { USB_DEVICE_INTERFACE_NUMBER(QCN7605_USB_VENDOR_ID, + QCN7605_STANDALONE_PRODUCT_ID, + QCN7605_WLAN_STANDALONE_INTERFACE_NUM) }, + {} /* Terminating entry */ }; static struct usb_driver cnss_usb_driver = { From c0bb13c9fd268dad9d079404d980de22ecf8f2d1 Mon Sep 17 00:00:00 2001 From: Rajasekaran Kalidoss Date: Mon, 8 Oct 2018 13:48:21 +0530 Subject: [PATCH 032/281] cnss2: Update QMI files with cold cal data changes QCN7605 supports cold boot cal data upload/download over QMI for HL transports. QMI structures are updated to support this. Change-Id: Ic91f856ced8d30ab31cb305396ec476c6ca55f40 Signed-off-by: Rajasekaran Kalidoss --- .../cnss2/wlan_firmware_service_v01.c | 96 +++++++++++++++++++ .../cnss2/wlan_firmware_service_v01.h | 18 +++- 2 files changed, 110 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/cnss2/wlan_firmware_service_v01.c b/drivers/net/wireless/cnss2/wlan_firmware_service_v01.c index 14e9d36524b8..5c60f529d11f 100644 --- a/drivers/net/wireless/cnss2/wlan_firmware_service_v01.c +++ b/drivers/net/wireless/cnss2/wlan_firmware_service_v01.c @@ -1310,6 +1310,46 @@ struct elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[] = { struct wlfw_initiate_cal_download_ind_msg_v01, cal_id), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof( + struct wlfw_initiate_cal_download_ind_msg_v01, + total_size_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof( + struct wlfw_initiate_cal_download_ind_msg_v01, + total_size), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof( + struct wlfw_initiate_cal_download_ind_msg_v01, + cal_data_location_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof( + struct wlfw_initiate_cal_download_ind_msg_v01, + cal_data_location), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, @@ -1426,6 +1466,24 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { .offset = offsetof(struct wlfw_cal_download_req_msg_v01, end), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_cal_download_req_msg_v01, + cal_data_location_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_cal_download_req_msg_v01, + cal_data_location), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, @@ -1473,6 +1531,26 @@ struct elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[] = { wlfw_initiate_cal_update_ind_msg_v01, total_size), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct + wlfw_initiate_cal_update_ind_msg_v01, + cal_data_location_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct + wlfw_initiate_cal_update_ind_msg_v01, + cal_data_location), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, @@ -1616,6 +1694,24 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, end), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, + cal_data_location_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, + cal_data_location), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, diff --git a/drivers/net/wireless/cnss2/wlan_firmware_service_v01.h b/drivers/net/wireless/cnss2/wlan_firmware_service_v01.h index dc2f355a0660..2ef74280e7b1 100644 --- a/drivers/net/wireless/cnss2/wlan_firmware_service_v01.h +++ b/drivers/net/wireless/cnss2/wlan_firmware_service_v01.h @@ -396,9 +396,13 @@ extern struct elem_info wlfw_cal_report_resp_msg_v01_ei[]; struct wlfw_initiate_cal_download_ind_msg_v01 { enum wlfw_cal_temp_id_enum_v01 cal_id; + u8 total_size_valid; + u32 total_size; + u8 cal_data_location_valid; + u32 cal_data_location; }; -#define WLFW_INITIATE_CAL_DOWNLOAD_IND_MSG_V01_MAX_MSG_LEN 7 +#define WLFW_INITIATE_CAL_DOWNLOAD_IND_MSG_V01_MAX_MSG_LEN 21 extern struct elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[]; struct wlfw_cal_download_req_msg_v01 { @@ -414,9 +418,11 @@ struct wlfw_cal_download_req_msg_v01 { u8 data[QMI_WLFW_MAX_DATA_SIZE_V01]; u8 end_valid; u8 end; + u8 cal_data_location_valid; + u32 cal_data_location; }; -#define WLFW_CAL_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6178 +#define WLFW_CAL_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6185 extern struct elem_info wlfw_cal_download_req_msg_v01_ei[]; struct wlfw_cal_download_resp_msg_v01 { @@ -429,9 +435,11 @@ extern struct elem_info wlfw_cal_download_resp_msg_v01_ei[]; struct wlfw_initiate_cal_update_ind_msg_v01 { enum wlfw_cal_temp_id_enum_v01 cal_id; u32 total_size; + u8 cal_data_location_valid; + u32 cal_data_location; }; -#define WLFW_INITIATE_CAL_UPDATE_IND_MSG_V01_MAX_MSG_LEN 14 +#define WLFW_INITIATE_CAL_UPDATE_IND_MSG_V01_MAX_MSG_LEN 21 extern struct elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[]; struct wlfw_cal_update_req_msg_v01 { @@ -455,9 +463,11 @@ struct wlfw_cal_update_resp_msg_v01 { u8 data[QMI_WLFW_MAX_DATA_SIZE_V01]; u8 end_valid; u8 end; + u8 cal_data_location_valid; + u32 cal_data_location; }; -#define WLFW_CAL_UPDATE_RESP_MSG_V01_MAX_MSG_LEN 6181 +#define WLFW_CAL_UPDATE_RESP_MSG_V01_MAX_MSG_LEN 6188 extern struct elem_info wlfw_cal_update_resp_msg_v01_ei[]; struct wlfw_msa_info_req_msg_v01 { From 5f129c6db3447471b02acc3e029a52821847cbb1 Mon Sep 17 00:00:00 2001 From: Nagireddy Annem Date: Fri, 14 Jun 2019 16:16:04 +0530 Subject: [PATCH 033/281] soc: qcom: Fix blackghost status irq missing during BG SSR BG gpio status irq handler is not calling sometimes due to enable_irq is clearing gpio intruppt status register, hence gpio summary irq is not calling status irq handler, with adding delay also we are seeing issue sometimes, fix it by removing enable_irq. Change-Id: Iab49d51485b3ffa25723abee52dcbd5e6e47d15e Signed-off-by: Nagireddy Annem --- drivers/soc/qcom/subsys-pil-bg.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/soc/qcom/subsys-pil-bg.c b/drivers/soc/qcom/subsys-pil-bg.c index d1b5feadf989..b40c46c27db7 100644 --- a/drivers/soc/qcom/subsys-pil-bg.c +++ b/drivers/soc/qcom/subsys-pil-bg.c @@ -294,7 +294,6 @@ static int bg_powerup(const struct subsys_desc *subsys) __func__, bg_data->status_irq, ret); return ret; } - disable_irq(bg_data->status_irq); /* Enable status and err fatal irqs */ ret = pil_boot(&bg_data->desc); @@ -303,9 +302,6 @@ static int bg_powerup(const struct subsys_desc *subsys) "%s: BG PIL Boot failed\n", __func__); return ret; } - /* wait for msm_gpio_irq_handler to get invoked before enable irq */ - usleep_range(5000, 6000); - enable_irq(bg_data->status_irq); ret = wait_for_err_ready(bg_data); if (ret) { dev_err(bg_data->desc.dev, From 7a68953b8ec01fb9d88cecc291c529f64168941b Mon Sep 17 00:00:00 2001 From: Neng Chen Date: Tue, 25 Jun 2019 18:29:06 +0800 Subject: [PATCH 034/281] ARM: dts: msm: change voltage for front camera vio supply The front camera vio should be fixed with 1.8V. Change-Id: Iaf2423d501751675649ab19c0bd730d5b7337ede Signed-off-by: Neng Chen --- arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi index 45abf9497ad1..1106d331eb76 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi @@ -244,8 +244,8 @@ cam_vaf-supply = <&pm660_l19>; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; - qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-max-voltage = <1200000 0 2800000 3200000>; + qcom,cam-vreg-min-voltage = <1200000 1800000 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2800000 3200000>; qcom,cam-vreg-op-mode = <200000 0 80000 100000>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk1_default From ec9ef181089601e80119d943d3765774e796ef27 Mon Sep 17 00:00:00 2001 From: zhaochen Date: Fri, 21 Jun 2019 11:00:19 +0800 Subject: [PATCH 035/281] ARM: dts: msm: remove device tree compile for SDM429 spyro EVT Because of some conflict(this dtb involve sdm439-qrd) in spyro project, need to remove this dtb compile, and will reorganization these dtsi to sdm429-spyro(pure) would not effect any other project. Change-Id: Ide9fd8320d45cbe88ab1f3d93303c1baed772061 Signed-off-by: zhaochen --- arch/arm64/boot/dts/qcom/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index b932dab70dbd..16cfd5fa1eec 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -644,8 +644,7 @@ dtb-$(CONFIG_ARCH_SDM429) += sdm429-mtp.dtb \ sdm429-cdp.dtb \ sdm429-qrd.dtb \ sda429-mtp.dtb \ - sda429-cdp.dtb \ - sdm429-qrd-spyro-evt.dtb + sda429-cdp.dtb endif From b0bca7a2dea5aaa5cdea691af0bbdea5070ba80a Mon Sep 17 00:00:00 2001 From: Tengfei Fan Date: Thu, 27 Jun 2019 11:00:08 +0800 Subject: [PATCH 036/281] defconfig: msm: Enable BPF related defconfigs xt_qtaguid is getting deprecated and should use BPF related defconfigs instead. Change-Id: Ib4921b7ec1ebec1f475d490beb4ce9aa9eeb18e9 Signed-off-by: Tengfei Fan --- arch/arm/configs/msm8937-perf_defconfig | 1 + arch/arm/configs/msm8937_defconfig | 1 + arch/arm/configs/msm8937go-perf_defconfig | 1 + arch/arm/configs/msm8937go_defconfig | 1 + arch/arm/configs/msm8953-perf_defconfig | 1 + arch/arm/configs/msm8953_defconfig | 1 + 6 files changed, 6 insertions(+) diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig index edb7c31f979d..98966079d70e 100755 --- a/arch/arm/configs/msm8937-perf_defconfig +++ b/arch/arm/configs/msm8937-perf_defconfig @@ -220,6 +220,7 @@ CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_FLOW=y +CONFIG_NET_CLS_BPF=y CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_CMP=y CONFIG_NET_EMATCH_NBYTE=y diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig index 7c661e76969d..ada99da4b1a5 100755 --- a/arch/arm/configs/msm8937_defconfig +++ b/arch/arm/configs/msm8937_defconfig @@ -223,6 +223,7 @@ CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_FLOW=y +CONFIG_NET_CLS_BPF=y CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_CMP=y CONFIG_NET_EMATCH_NBYTE=y diff --git a/arch/arm/configs/msm8937go-perf_defconfig b/arch/arm/configs/msm8937go-perf_defconfig index cbb3cdcd0197..6ab6c96a84bd 100755 --- a/arch/arm/configs/msm8937go-perf_defconfig +++ b/arch/arm/configs/msm8937go-perf_defconfig @@ -220,6 +220,7 @@ CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_FLOW=y +CONFIG_NET_CLS_BPF=y CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_CMP=y CONFIG_NET_EMATCH_NBYTE=y diff --git a/arch/arm/configs/msm8937go_defconfig b/arch/arm/configs/msm8937go_defconfig index 335c7555cc88..41f11be32766 100755 --- a/arch/arm/configs/msm8937go_defconfig +++ b/arch/arm/configs/msm8937go_defconfig @@ -223,6 +223,7 @@ CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_FLOW=y +CONFIG_NET_CLS_BPF=y CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_CMP=y CONFIG_NET_EMATCH_NBYTE=y diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig index ac443139a395..d072b6790d9a 100755 --- a/arch/arm/configs/msm8953-perf_defconfig +++ b/arch/arm/configs/msm8953-perf_defconfig @@ -215,6 +215,7 @@ CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_FLOW=y +CONFIG_NET_CLS_BPF=y CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_CMP=y CONFIG_NET_EMATCH_NBYTE=y diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig index e7ed639f93a0..8ba9cceaa5ac 100755 --- a/arch/arm/configs/msm8953_defconfig +++ b/arch/arm/configs/msm8953_defconfig @@ -219,6 +219,7 @@ CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_FLOW=y +CONFIG_NET_CLS_BPF=y CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_CMP=y CONFIG_NET_EMATCH_NBYTE=y From b92c4841b22d97d254a631ce2961a50d2cd1c117 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Singh Date: Tue, 30 Apr 2019 15:45:37 +0530 Subject: [PATCH 037/281] soc: qcom: smem: validate fields of shared structures Structures in shared memory that can be modified by remote processors may have untrusted values, they should be validated before use. Adding proper validation before using fields of shared structures. CRs-Fixed: 2421611 Change-Id: Ifed71c506a26105eac3db9ee35f086d7dbf5a3a3 Signed-off-by: Deepak Kumar Singh --- drivers/soc/qcom/smem.c | 134 +++++++++++++++++++++++++++++----------- 1 file changed, 97 insertions(+), 37 deletions(-) diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 18ec52f2078a..bd1ced19fa85 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Sony Mobile Communications AB. - * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2013, 2019 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 @@ -228,7 +228,7 @@ struct smem_region { * struct qcom_smem - device data for the smem device * @dev: device pointer * @hwlock: reference to a hwspinlock - * @partitions: list of pointers to partitions affecting the current + * @ptable_entries: list of pointers to partitions table entry of current * processor/host * @num_regions: number of @regions * @regions: list of the memory regions defining the shared memory @@ -238,12 +238,24 @@ struct qcom_smem { struct hwspinlock *hwlock; - struct smem_partition_header *partitions[SMEM_HOST_COUNT]; + struct smem_ptable_entry *ptable_entries[SMEM_HOST_COUNT]; unsigned num_regions; struct smem_region regions[0]; }; +/* Pointer to the one and only smem handle */ +static struct qcom_smem *__smem; + +/* Timeout (ms) for the trylock of remote spinlocks */ +#define HWSPINLOCK_TIMEOUT 1000 + +static struct smem_partition_header * +ptable_entry_to_phdr(struct smem_ptable_entry *entry) +{ + return __smem->regions[0].virt_base + le32_to_cpu(entry->offset); +} + static struct smem_private_entry * phdr_to_last_private_entry(struct smem_partition_header *phdr) { @@ -283,32 +295,32 @@ static void *entry_to_item(struct smem_private_entry *e) return p + sizeof(*e) + le16_to_cpu(e->padding_hdr); } -/* Pointer to the one and only smem handle */ -static struct qcom_smem *__smem; - -/* Timeout (ms) for the trylock of remote spinlocks */ -#define HWSPINLOCK_TIMEOUT 1000 - static int qcom_smem_alloc_private(struct qcom_smem *smem, - unsigned host, + struct smem_ptable_entry *entry, unsigned item, size_t size) { - struct smem_partition_header *phdr; struct smem_private_entry *hdr, *end; + struct smem_partition_header *phdr; size_t alloc_size; void *cached; + void *p_end; + + phdr = ptable_entry_to_phdr(entry); + p_end = (void *)phdr + le32_to_cpu(entry->size); - phdr = smem->partitions[host]; hdr = phdr_to_first_private_entry(phdr); end = phdr_to_last_private_entry(phdr); cached = phdr_to_first_cached_entry(phdr); + if (WARN_ON((void *)end > p_end || (void *)cached > p_end)) + return -EINVAL; + while (hdr < end) { if (hdr->canary != SMEM_PRIVATE_CANARY) { dev_err(smem->dev, - "Found invalid canary in host %d partition\n", - host); + "Found invalid canary in host %d:%d partition\n", + phdr->host0, phdr->host1); return -EINVAL; } @@ -317,6 +329,8 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem, hdr = private_entry_next(hdr); } + if (WARN_ON((void *)hdr > p_end)) + return -EINVAL; /* Check that we don't grow into the cached region */ alloc_size = sizeof(*hdr) + ALIGN(size, 8); @@ -389,6 +403,7 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem, */ int qcom_smem_alloc(unsigned host, unsigned item, size_t size) { + struct smem_ptable_entry *entry; unsigned long flags; int ret; @@ -407,10 +422,12 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size) if (ret) return ret; - if (host < SMEM_HOST_COUNT && __smem->partitions[host]) - ret = qcom_smem_alloc_private(__smem, host, item, size); - else + if (host < SMEM_HOST_COUNT && __smem->ptable_entries[host]) { + entry = __smem->ptable_entries[host]; + ret = qcom_smem_alloc_private(__smem, entry, item, size); + } else { ret = qcom_smem_alloc_global(__smem, item, size); + } hwspin_unlock_irqrestore(__smem->hwlock, &flags); @@ -422,9 +439,11 @@ static void *qcom_smem_get_global(struct qcom_smem *smem, unsigned item, size_t *size) { + struct smem_global_entry *entry; struct smem_header *header; struct smem_region *area; - struct smem_global_entry *entry; + u64 entry_offset; + u32 e_size; u32 aux_base; unsigned i; @@ -442,9 +461,16 @@ static void *qcom_smem_get_global(struct qcom_smem *smem, area = &smem->regions[i]; if (area->aux_base == aux_base || !aux_base) { + e_size = le32_to_cpu(entry->size); + entry_offset = le32_to_cpu(entry->offset); + + if (WARN_ON(e_size + entry_offset > area->size)) + return ERR_PTR(-EINVAL); + if (size != NULL) - *size = le32_to_cpu(entry->size); - return area->virt_base + le32_to_cpu(entry->offset); + *size = e_size; + + return area->virt_base + entry_offset; } } @@ -452,35 +478,58 @@ static void *qcom_smem_get_global(struct qcom_smem *smem, } static void *qcom_smem_get_private(struct qcom_smem *smem, - unsigned host, + struct smem_ptable_entry *entry, unsigned item, size_t *size) { struct smem_partition_header *phdr; struct smem_private_entry *e, *end; + void *item_ptr, *p_end; + u32 partition_size; + u32 padding_data; + u32 e_size; + + phdr = ptable_entry_to_phdr(entry); + partition_size = le32_to_cpu(entry->size); + p_end = (void *)phdr + partition_size; - phdr = smem->partitions[host]; e = phdr_to_first_private_entry(phdr); end = phdr_to_last_private_entry(phdr); + if (WARN_ON((void *)end > p_end)) + return ERR_PTR(-EINVAL); + while (e < end) { if (e->canary != SMEM_PRIVATE_CANARY) { dev_err(smem->dev, - "Found invalid canary in host %d partition\n", - host); + "Found invalid canary in host %d:%d partition\n", + phdr->host0, phdr->host1); return ERR_PTR(-EINVAL); } if (le16_to_cpu(e->item) == item) { - if (size != NULL) - *size = le32_to_cpu(e->size) - - le16_to_cpu(e->padding_data); - - return entry_to_item(e); + if (size != NULL) { + e_size = le32_to_cpu(e->size); + padding_data = le16_to_cpu(e->padding_data); + + if (e_size < partition_size + && padding_data < e_size) + *size = e_size - padding_data; + else + return ERR_PTR(-EINVAL); + } + + item_ptr = entry_to_item(e); + if (WARN_ON(item_ptr > p_end)) + return ERR_PTR(-EINVAL); + + return item_ptr; } e = private_entry_next(e); } + if (WARN_ON((void *)e > p_end)) + return ERR_PTR(-EINVAL); return ERR_PTR(-ENOENT); } @@ -496,6 +545,7 @@ static void *qcom_smem_get_private(struct qcom_smem *smem, */ void *qcom_smem_get(unsigned host, unsigned item, size_t *size) { + struct smem_ptable_entry *entry; unsigned long flags; int ret; void *ptr = ERR_PTR(-EPROBE_DEFER); @@ -509,11 +559,12 @@ void *qcom_smem_get(unsigned host, unsigned item, size_t *size) if (ret) return ERR_PTR(ret); - if (host < SMEM_HOST_COUNT && __smem->partitions[host]) - ptr = qcom_smem_get_private(__smem, host, item, size); - else + if (host < SMEM_HOST_COUNT && __smem->ptable_entries[host]) { + entry = __smem->ptable_entries[host]; + ptr = qcom_smem_get_private(__smem, entry, item, size); + } else { ptr = qcom_smem_get_global(__smem, item, size); - + } hwspin_unlock_irqrestore(__smem->hwlock, &flags); return ptr; @@ -531,19 +582,28 @@ EXPORT_SYMBOL(qcom_smem_get); int qcom_smem_get_free_space(unsigned host) { struct smem_partition_header *phdr; + struct smem_ptable_entry *entry; struct smem_header *header; unsigned ret; if (!__smem) return -EPROBE_DEFER; - if (host < SMEM_HOST_COUNT && __smem->partitions[host]) { - phdr = __smem->partitions[host]; + if (host < SMEM_HOST_COUNT && __smem->ptable_entries[host]) { + entry = __smem->ptable_entries[host]; + phdr = ptable_entry_to_phdr(entry); + ret = le32_to_cpu(phdr->offset_free_cached) - le32_to_cpu(phdr->offset_free_uncached); + + if (ret > le32_to_cpu(entry->size)) + return -EINVAL; } else { header = __smem->regions[0].virt_base; ret = le32_to_cpu(header->available); + + if (ret > __smem->regions[0].size) + return -EINVAL; } return ret; @@ -616,7 +676,7 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, return -EINVAL; } - if (smem->partitions[remote_host]) { + if (smem->ptable_entries[remote_host]) { dev_err(smem->dev, "Already found a partition for host %d\n", remote_host); @@ -658,7 +718,7 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, return -EINVAL; } - smem->partitions[remote_host] = header; + smem->ptable_entries[remote_host] = entry; } return 0; From 6bab9bee57f46fa155ac269b0e12e94b5832abc7 Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Wed, 29 May 2019 12:30:47 +0800 Subject: [PATCH 038/281] sched: fair: Add strict skip buddy support Skip buddy i.e task called yield() is always skipped and the next entity is selected to run irrespective of the unfairness. Change-Id: Ia9b9fbe46917152b58dc6406c718eb1cfb3b0fb2 Signed-off-by: Maria Yu --- kernel/sched/fair.c | 3 ++- kernel/sched/features.h | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 3f863a11879a..a4215a6d1deb 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3939,7 +3939,8 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr) second = curr; } - if (second && wakeup_preempt_entity(second, left) < 1) + if (second && (sched_feat(STRICT_SKIP_BUDDY) || + wakeup_preempt_entity(second, left) < 1)) se = second; } diff --git a/kernel/sched/features.h b/kernel/sched/features.h index ef52be469284..9f012ea5a3fc 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -25,6 +25,12 @@ SCHED_FEAT(NEXT_BUDDY, false) */ SCHED_FEAT(LAST_BUDDY, true) +/* + * skip buddy i.e task called yield() is always skipped and the + * next entity is selected to run irrespective of the vruntime + */ +SCHED_FEAT(STRICT_SKIP_BUDDY, true) + /* * Consider buddies to be cache hot, decreases the likelyness of a * cache buddy being migrated away, increases cache locality. From a396ef7cd0e337c109fda339288c703c51604349 Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Thu, 27 Jun 2019 14:43:16 +0800 Subject: [PATCH 039/281] sched: core: Clear walt rq request in cpu starting Clear walt rq request in cpu starting. Change-Id: Id3004337f3924984b8b812151a6ba01c6f1c013e Signed-off-by: Maria Yu --- kernel/sched/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 531adb8a5c3b..5f10aebeda28 100755 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -8104,6 +8104,7 @@ int sched_cpu_starting(unsigned int cpu) { set_cpu_rq_start_time(cpu); sched_rq_cpu_starting(cpu); + clear_walt_request(cpu); return 0; } From 6b447866f6c92df130fe83b35bcf3890304f7caa Mon Sep 17 00:00:00 2001 From: Sandeep Singh Date: Tue, 25 Jun 2019 19:02:39 +0530 Subject: [PATCH 040/281] wcnss: Read multiple SMD Packet from SMD Channel It observe that sometime, there are multiple SMD packets in SMD channel. In current scenario, driver reading one packet at single event. Reading all SMD packets to avoid any packets miss. Change-Id: Id7ef388af6200891b17bbe1456cc2fffa580a3d3 Signed-off-by: Sandeep Singh --- drivers/soc/qcom/wcnss/wcnss_wlan.c | 43 +++++++++++++++++++---------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/drivers/soc/qcom/wcnss/wcnss_wlan.c b/drivers/soc/qcom/wcnss/wcnss_wlan.c index 08bd78b55364..1634373096a9 100644 --- a/drivers/soc/qcom/wcnss/wcnss_wlan.c +++ b/drivers/soc/qcom/wcnss/wcnss_wlan.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, 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 @@ -2229,9 +2229,8 @@ void extract_cal_data(int len) wcnss_send_cal_rsp(fw_status); } -static void wcnssctrl_rx_handler(struct work_struct *worker) +static void wcnss_process_smd_msg(int len) { - int len = 0; int rc = 0; unsigned char buf[sizeof(struct wcnss_version)]; unsigned char build[WCNSS_MAX_BUILD_VER_LEN + 1]; @@ -2241,17 +2240,6 @@ static void wcnssctrl_rx_handler(struct work_struct *worker) int hw_type; unsigned char fw_status = 0; - len = smd_read_avail(penv->smd_ch); - if (len > WCNSS_MAX_FRAME_SIZE) { - wcnss_log(ERR, "frame larger than the allowed size\n"); - smd_read(penv->smd_ch, NULL, len); - return; - } - if (len < sizeof(struct smd_msg_hdr)) { - wcnss_log(DBG, "incomplete header available len = %d\n", len); - return; - } - rc = smd_read(penv->smd_ch, buf, sizeof(struct smd_msg_hdr)); if (rc < sizeof(struct smd_msg_hdr)) { wcnss_log(ERR, "incomplete header read from smd\n"); @@ -2362,6 +2350,33 @@ static void wcnssctrl_rx_handler(struct work_struct *worker) } } +static void wcnssctrl_rx_handler(struct work_struct *worker) +{ + int len; + + while (1) { + len = smd_read_avail(penv->smd_ch); + if (len == 0) { + pr_debug("wcnss: No more data to be read\n"); + return; + } + + if (len > WCNSS_MAX_FRAME_SIZE) { + pr_err("wcnss: frame larger than the allowed size\n"); + smd_read(penv->smd_ch, NULL, len); + return; + } + + if (len < sizeof(struct smd_msg_hdr)) { + pr_err("wcnss: incomplete header available len = %d\n", + len); + return; + } + + wcnss_process_smd_msg(len); + } +} + static void wcnss_send_version_req(struct work_struct *worker) { struct smd_msg_hdr smd_msg; From 9b91470de55cd79db4edc8c32a9aa8e482c76d91 Mon Sep 17 00:00:00 2001 From: Baochu Xu Date: Thu, 27 Jun 2019 16:43:24 +0800 Subject: [PATCH 041/281] ASoC: aw8896: Keep dev name for aw8896 SmartPA Keep dev name no change for aw8896 SmartPA. This is to fix the firmware loading failure. Change-Id: I5848a7f95e4c0ee63d06d03cd9d96ae0cec4c473 Signed-off-by: Baochu Xu --- sound/soc/codecs/aw8896.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sound/soc/codecs/aw8896.c b/sound/soc/codecs/aw8896.c index 23d2485239d5..dbc7cd8cfbff 100644 --- a/sound/soc/codecs/aw8896.c +++ b/sound/soc/codecs/aw8896.c @@ -927,9 +927,6 @@ static int aw8896_probe(struct snd_soc_codec *codec) aw8896->codec = codec; aw8896_add_codec_controls(aw8896); - if (codec->dev->of_node) - dev_set_name(codec->dev, "%s", "aw8896_smartpa"); - return ret; } @@ -1404,12 +1401,6 @@ static int aw8896_i2c_probe(struct i2c_client *i2c, goto err_id; } - if (i2c->dev.of_node) - dev_set_name(&i2c->dev, "%s", "aw8896_smartpa"); - else - dev_err(&i2c->dev, "%s failed to set device name: %d\n", - __func__, ret); - /* register codec */ dai = devm_kzalloc(&i2c->dev, sizeof(aw8896_dai), GFP_KERNEL); if (!dai) From 8111d698a7148e57efea05e18147db5c33b45a38 Mon Sep 17 00:00:00 2001 From: Manu Gautam Date: Fri, 24 May 2019 16:38:59 +0530 Subject: [PATCH 042/281] usb: dwc3-msm: Enable EP events only after GSI doorbell is updated USB GSI hardware wrapper monitors USB interrupters for any events on GSI EPs and rings GSI_DBL if there is any event. Since, GSI doorbell can be enabled/disabled for all endpoints at a time and not per endpoint, there is always a possibility of GSI wrapper getting enabled before DBL_ADDR is programmed for all GSI_EPs. Consider a case when there are multiple GSI functions present in the composition (e.g. ADPL and RNDIS/RMNET) and ADPL function's data_path_enable happens first which enables GSI wrapper. And if for some reason there is a delay between RNDIS/RMNET EPs' start_xfer and doorbell address update (and GSI wrapper is already enabled by ADPL) then hardware may try to ring GSI_DBL with address-0 on receiving XFER_IN_PROGRESS event. This can be avoided by deferring enable of USB GSI EP's endpoint events until doorbell address is programmed. It requires not enabling EP events as part of EP_CONFIG on INIT and instead issuing MODIFY EP_CONFIG command later for GSI EPs. Similar issue exists for function suspend/resume when dealing with more than one GSI interfaces in a composition. In that case when all interfaces have disabled or blocked doorbell on its function suspend, function resume of first interface unblocks doorbell for all endpoint and can result in issues as corresponding xdci channel might still be in suspended state. Fix this by also disabling EP events when blocking doorbell so that unless EP events are enabled again, hardware shouldn't access doorbell. Change-Id: Ibe857fd04de7c6f1b4e74b4b1e55d711d73af2cc Signed-off-by: Manu Gautam Signed-off-by: Ajay Agarwal --- drivers/usb/dwc3/core.h | 28 ++++++----- drivers/usb/dwc3/dwc3-msm.c | 75 +++++++++++++++++++++++++++-- drivers/usb/gadget/function/f_gsi.c | 53 +++++++++++++------- 3 files changed, 121 insertions(+), 35 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5983b2d89257..13e62cd402b5 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -516,6 +516,19 @@ struct dwc3_trb; +/** + * struct dwc3_gadget_ep_cmd_params - representation of endpoint command + * parameters + * @param2: third parameter + * @param1: second parameter + * @param0: first parameter + */ +struct dwc3_gadget_ep_cmd_params { + u32 param2; + u32 param1; + u32 param0; +}; + /** * struct dwc3_event_buffer - Software event buffer representation * @buf: _THE_ buffer @@ -606,6 +619,7 @@ struct dwc3_ep_events { * @dbg_ep_events_diff: differential events counter for endpoint * @dbg_ep_events_ts: timestamp for previous event counters * @fifo_depth: allocated TXFIFO depth + * @ep_cfg_init_params: Used by GSI EP to save EP_CFG init_cmd params */ struct dwc3_ep { struct usb_ep endpoint; @@ -661,6 +675,7 @@ struct dwc3_ep { struct dwc3_ep_events dbg_ep_events_diff; struct timespec dbg_ep_events_ts; int fifo_depth; + struct dwc3_gadget_ep_cmd_params ep_cfg_init_params; }; enum dwc3_phy { @@ -1305,19 +1320,6 @@ union dwc3_event { struct dwc3_event_gevt gevt; }; -/** - * struct dwc3_gadget_ep_cmd_params - representation of endpoint command - * parameters - * @param2: third parameter - * @param1: second parameter - * @param0: first parameter - */ -struct dwc3_gadget_ep_cmd_params { - u32 param2; - u32 param1; - u32 param0; -}; - /* * DWC3 Features to be used as Driver Data */ diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 7751b029d807..24b9422c7e95 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1232,6 +1232,7 @@ static void gsi_free_trbs(struct usb_ep *ep, struct usb_gsi_request *req) } sg_free_table(&req->sgt_trb_xfer_ring); } + /* * Configures GSI EPs. For GSI EPs we need to set interrupter numbers. * @@ -1274,10 +1275,8 @@ static void gsi_configure_ep(struct usb_ep *ep, struct usb_gsi_request *request) /* Set interrupter number for GSI endpoints */ params.param1 |= DWC3_DEPCFG_INT_NUM(ep->ep_intr_num); - /* Enable XferInProgress and XferComplete Interrupts */ - params.param1 |= DWC3_DEPCFG_XFER_COMPLETE_EN; - params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN; - params.param1 |= DWC3_DEPCFG_FIFO_ERROR_EN; + /* EP Events are enabled later once DBL_ADDR is updated */ + /* * We must use the lower 16 TX FIFOs even though * HW might have more @@ -1289,7 +1288,10 @@ static void gsi_configure_ep(struct usb_ep *ep, struct usb_gsi_request *request) params.param0 |= DWC3_DEPCFG_ACTION_INIT; dev_dbg(mdwc->dev, "Set EP config to params = %x %x %x, for %s\n", - params.param0, params.param1, params.param2, dep->name); + params.param0, params.param1, params.param2, dep->name); + + /* params are used later when EP_CONFIG is modified to enable events */ + dep->ep_cfg_init_params = params; dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, ¶ms); @@ -1315,6 +1317,57 @@ static void gsi_configure_ep(struct usb_ep *ep, struct usb_gsi_request *request) } +/* + * Enables events for GSI EPs. Modify EP_CONFIG to enable EP events + * after GSI wrapper is initialized for the endpoint. + * + * @usb_ep - pointer to usb_ep instance. + */ +static void gsi_enable_ep_events(struct usb_ep *ep) +{ + struct dwc3_ep *dep = to_dwc3_ep(ep); + struct dwc3_msm *mdwc = dev_get_drvdata(dep->dwc->dev->parent); + struct dwc3_gadget_ep_cmd_params params; + + /* EP is already configured, just update params to enable events */ + params = dep->ep_cfg_init_params; + + /* Enable XferInProgress and XferComplete Interrupts */ + params.param1 |= DWC3_DEPCFG_XFER_COMPLETE_EN; + params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN; + params.param1 |= DWC3_DEPCFG_FIFO_ERROR_EN; + + params.param0 |= DWC3_DEPCFG_ACTION_MODIFY; + + dev_dbg(mdwc->dev, "Modify EP config to params = %x %x %x, for %s\n", + params.param0, params.param1, params.param2, dep->name); + + dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, ¶ms); +} + +/* + * Disables events for GSI EPs. Modify EP_CONFIG to disable EP events + * to prevent USB GSI wrapper from ringing any doorbell. + * + * @usb_ep - pointer to usb_ep instance. + */ +static void gsi_disable_ep_events(struct usb_ep *ep) +{ + struct dwc3_ep *dep = to_dwc3_ep(ep); + struct dwc3_msm *mdwc = dev_get_drvdata(dep->dwc->dev->parent); + struct dwc3_gadget_ep_cmd_params params; + + /* EP is already enabled, just restore init_params to disable events */ + params = dep->ep_cfg_init_params; + + params.param0 |= DWC3_DEPCFG_ACTION_MODIFY; + + dev_dbg(mdwc->dev, "Modify EP config to params = %x %x %x, for %s\n", + params.param0, params.param1, params.param2, dep->name); + + dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, ¶ms); +} + /* * Enables USB wrapper for GSI * @@ -1352,6 +1405,16 @@ static void gsi_set_clear_dbell(struct usb_ep *ep, struct dwc3 *dwc = dep->dwc; struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); + /* + * Disable EP events if doorbell needs to be blocked to avoid issues + * due to another GSI interface endpoint enabling doorbell say on resume + * as there is no control of doorbell per endpoint. + */ + if (block_db) + gsi_disable_ep_events(ep); + else + gsi_enable_ep_events(ep); + dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, BLOCK_GSI_WR_GO_MASK, block_db); } @@ -1462,7 +1525,9 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep, break; case GSI_EP_OP_SET_CLR_BLOCK_DBL: block_db = *((bool *)op_data); + spin_lock_irqsave(&dwc->lock, flags); gsi_set_clear_dbell(ep, block_db); + spin_unlock_irqrestore(&dwc->lock, flags); break; case GSI_EP_OP_CHECK_FOR_SUSPEND: ret = gsi_check_ready_to_suspend(mdwc); diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index b497457f41f4..97c50d06b0cb 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -746,32 +746,33 @@ static void ipa_data_path_enable(struct gsi_data_port *d_port) bool block_db = false; log_event_dbg("IN: db_reg_phs_addr_lsb = %x", - gsi->d_port.in_request.db_reg_phs_addr_lsb); - usb_gsi_ep_op(gsi->d_port.in_ep, - &gsi->d_port.in_request, + d_port->in_request.db_reg_phs_addr_lsb); + usb_gsi_ep_op(d_port->in_ep, &d_port->in_request, GSI_EP_OP_STORE_DBL_INFO); - if (gsi->d_port.out_ep) { + if (d_port->out_ep) { log_event_dbg("OUT: db_reg_phs_addr_lsb = %x", - gsi->d_port.out_request.db_reg_phs_addr_lsb); - usb_gsi_ep_op(gsi->d_port.out_ep, - &gsi->d_port.out_request, + d_port->out_request.db_reg_phs_addr_lsb); + usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, GSI_EP_OP_STORE_DBL_INFO); } - usb_gsi_ep_op(gsi->d_port.in_ep, &gsi->d_port.in_request, + usb_gsi_ep_op(d_port->in_ep, &d_port->in_request, GSI_EP_OP_ENABLE_GSI); /* Unblock doorbell to GSI */ usb_gsi_ep_op(d_port->in_ep, (void *)&block_db, GSI_EP_OP_SET_CLR_BLOCK_DBL); - usb_gsi_ep_op(gsi->d_port.in_ep, &gsi->d_port.in_request, - GSI_EP_OP_RING_DB); + usb_gsi_ep_op(d_port->in_ep, &d_port->in_request, + GSI_EP_OP_RING_DB); - if (gsi->d_port.out_ep) - usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request, - GSI_EP_OP_RING_DB); + if (d_port->out_ep) { + usb_gsi_ep_op(d_port->out_ep, (void *)&block_db, + GSI_EP_OP_SET_CLR_BLOCK_DBL); + usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, + GSI_EP_OP_RING_DB); + } } static void ipa_disconnect_handler(struct gsi_data_port *d_port) @@ -792,9 +793,12 @@ static void ipa_disconnect_handler(struct gsi_data_port *d_port) &gsi->d_port.in_request, GSI_EP_OP_DISABLE); } - if (gsi->d_port.out_ep) + if (gsi->d_port.out_ep) { + usb_gsi_ep_op(d_port->out_ep, (void *)&block_db, + GSI_EP_OP_SET_CLR_BLOCK_DBL); usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request, GSI_EP_OP_DISABLE); + } gsi->d_port.net_ready_trigger = false; } @@ -845,7 +849,11 @@ static int ipa_suspend_work_handler(struct gsi_data_port *d_port) ret = -EFAULT; block_db = false; usb_gsi_ep_op(d_port->in_ep, (void *)&block_db, - GSI_EP_OP_SET_CLR_BLOCK_DBL); + GSI_EP_OP_SET_CLR_BLOCK_DBL); + if (d_port->out_ep) + usb_gsi_ep_op(d_port->out_ep, (void *)&block_db, + GSI_EP_OP_SET_CLR_BLOCK_DBL); + goto done; } @@ -863,7 +871,10 @@ static int ipa_suspend_work_handler(struct gsi_data_port *d_port) if (ret == -EFAULT) { block_db = false; usb_gsi_ep_op(d_port->in_ep, (void *)&block_db, - GSI_EP_OP_SET_CLR_BLOCK_DBL); + GSI_EP_OP_SET_CLR_BLOCK_DBL); + if (d_port->out_ep) + usb_gsi_ep_op(d_port->out_ep, (void *)&block_db, + GSI_EP_OP_SET_CLR_BLOCK_DBL); gsi_wakeup_host(gsi); } else if (ret == -EINPROGRESS) { d_port->sm_state = STATE_SUSPEND_IN_PROGRESS; @@ -895,6 +906,9 @@ static void ipa_resume_work_handler(struct gsi_data_port *d_port) block_db = false; usb_gsi_ep_op(d_port->in_ep, (void *)&block_db, GSI_EP_OP_SET_CLR_BLOCK_DBL); + if (d_port->out_ep) + usb_gsi_ep_op(d_port->out_ep, (void *)&block_db, + GSI_EP_OP_SET_CLR_BLOCK_DBL); } static void ipa_work_handler(struct work_struct *w) @@ -1059,9 +1073,11 @@ static void ipa_work_handler(struct work_struct *w) log_event_dbg("%s: ST_CON_HOST_NRDY\n", __func__); block_db = true; - /* stop USB ringing doorbell to GSI(OUT_EP) */ + /* stop USB ringing doorbell to GSI(both EPs) */ usb_gsi_ep_op(d_port->in_ep, (void *)&block_db, GSI_EP_OP_SET_CLR_BLOCK_DBL); + usb_gsi_ep_op(d_port->out_ep, (void *)&block_db, + GSI_EP_OP_SET_CLR_BLOCK_DBL); gsi_rndis_ipa_reset_trigger(d_port); usb_gsi_ep_op(d_port->in_ep, NULL, GSI_EP_OP_ENDXFER); @@ -2637,6 +2653,9 @@ static void gsi_suspend(struct usb_function *f) block_db = true; usb_gsi_ep_op(gsi->d_port.in_ep, (void *)&block_db, GSI_EP_OP_SET_CLR_BLOCK_DBL); + if (gsi->d_port.out_ep) + usb_gsi_ep_op(gsi->d_port.out_ep, (void *)&block_db, + GSI_EP_OP_SET_CLR_BLOCK_DBL); post_event(&gsi->d_port, EVT_SUSPEND); queue_work(gsi->d_port.ipa_usb_wq, &gsi->d_port.usb_ipa_w); log_event_dbg("gsi suspended"); From 2a4e16cb80329be4bd2cfa5ba698d92f50e0722b Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Thu, 27 Jun 2019 12:02:48 +0530 Subject: [PATCH 043/281] iio: qcom-rradc: Set batt_id settling time to 80MS Set batt_id settling time to maximum possible value of 80MS to ensure enough time for ADC reading to settle to correct value. Change-Id: I40fb280ce4b34ab93abe40ddfe10d0fff71de12b Signed-off-by: Jishnu Prakash --- drivers/iio/adc/qcom-rradc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c index 0e6de1ea4f5f..6c86d7df5502 100644 --- a/drivers/iio/adc/qcom-rradc.c +++ b/drivers/iio/adc/qcom-rradc.c @@ -199,6 +199,8 @@ #define FG_RR_TP_REV_VERSION2 29 #define FG_RR_TP_REV_VERSION3 32 +#define BATT_ID_SETTLE_DELAY_80_MS 0xE0 + /* * The channel number is not a physical index in hardware, * rather it's a list of supported channels and an index to @@ -861,6 +863,13 @@ static int rradc_do_batt_id_conversion(struct rradc_chip *chip, return rc; } + rc = rradc_masked_write(chip, FG_ADC_RR_BATT_ID_CFG, + BATT_ID_SETTLE_DELAY_80_MS, BATT_ID_SETTLE_DELAY_80_MS); + if (rc < 0) { + pr_err("BATT_ID settling time config failed:%d\n", rc); + ret = rc; + } + rc = rradc_masked_write(chip, FG_ADC_RR_BATT_ID_TRIGGER, FG_ADC_RR_BATT_ID_TRIGGER_CTL, FG_ADC_RR_BATT_ID_TRIGGER_CTL); From 779b5e0a3ffded401f788609534ca065bb90c1fc Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Wed, 19 Jun 2019 20:53:52 +0530 Subject: [PATCH 044/281] msm: kgsl: Add missing check for snapshot IB dump During ringbuffer parsing, same IB can exist multiple times but size validation happens only for the first time. This leads to out of bound access if the subsequent sizes are greater than the allocated size. Add a check to make sure that requested size is within the allocated range. Change-Id: Ie5d3c02c1669de2e6188821399e985f0991aa57c Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/adreno_snapshot.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c index b93ee9c02824..1b43282ef6d7 100644 --- a/drivers/gpu/msm/adreno_snapshot.c +++ b/drivers/gpu/msm/adreno_snapshot.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019 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 @@ -70,6 +70,19 @@ void kgsl_snapshot_push_object(struct kgsl_process_private *process, for (index = 0; index < objbufptr; index++) { if (objbuf[index].gpuaddr == gpuaddr && objbuf[index].entry->priv == process) { + /* + * Check if newly requested size is within the + * allocated range or not, otherwise continue + * with previous size. + */ + if (!kgsl_gpuaddr_in_memdesc( + &objbuf[index].entry->memdesc, + gpuaddr, dwords << 2)) { + KGSL_CORE_ERR( + "snapshot: IB 0x%016llx size is not within the memdesc range\n", + gpuaddr); + return; + } objbuf[index].size = max_t(uint64_t, objbuf[index].size, From 9152db483cc11141eaff01bd2e0867415980365f Mon Sep 17 00:00:00 2001 From: Protik Biswas Date: Wed, 26 Jun 2019 16:28:03 +0530 Subject: [PATCH 045/281] soc: qcom: bgrsb: Remove BGRSB_STATE_LDO15_ENABLED This state is redundant and never used. Change-Id: I8728cd7eaebe92ecf7f74fa762fcf894b56ae0e1 Signed-off-by: Protik Biswas --- drivers/soc/qcom/bg_rsb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/soc/qcom/bg_rsb.c b/drivers/soc/qcom/bg_rsb.c index 3e338f24f6bc..05fb9ab019c2 100644 --- a/drivers/soc/qcom/bg_rsb.c +++ b/drivers/soc/qcom/bg_rsb.c @@ -71,7 +71,6 @@ enum bgrsb_state { BGRSB_STATE_INIT, BGRSB_STATE_LDO11_ENABLED, BGRSB_STATE_RSB_CONFIGURED, - BGRSB_STATE_LDO15_ENABLED, BGRSB_STATE_RSB_ENABLED }; From b523dd1f20be20672e269801a9adfeb13ff705cc Mon Sep 17 00:00:00 2001 From: Trishansh Bhardwaj Date: Fri, 5 Oct 2018 14:42:20 +0530 Subject: [PATCH 046/281] msm: camera: cpas: new soc id for SDM712 target New soc id is assigned for sdm712 target. Add support for the same. Change-Id: If89ead70045a5009d9ac29062840326edbb68d82 Signed-off-by: Trishansh Bhardwaj --- .../msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c | 10 ++++++---- .../media/platform/msm/camera/cam_utils/cam_soc_util.h | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c b/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c index f8687cf555a3..7ea1ec2e28d5 100644 --- a/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c +++ b/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cam_cpastop_hw.c @@ -525,9 +525,10 @@ static int cam_cpastop_poweron(struct cam_hw_info *cpas_hw) } } - if ((soc_private && ((soc_private->soc_id == SDM710_SOC_ID) || + if (soc_private && ((soc_private->soc_id == SDM710_SOC_ID) || + (soc_private->soc_id == SDM712_SOC_ID) || ((soc_private->soc_id == SDM670_SOC_ID) && - (soc_private->hw_rev == SDM670_V1_1))))) { + (soc_private->hw_rev == SDM670_V1_1)))) { struct cam_cpas_reg *reg_info; int tcsr_index; @@ -585,9 +586,10 @@ static int cam_cpastop_poweroff(struct cam_hw_info *cpas_hw) } } - if ((soc_private && ((soc_private->soc_id == SDM710_SOC_ID) + if (soc_private && ((soc_private->soc_id == SDM710_SOC_ID) + || (soc_private->soc_id == SDM712_SOC_ID) || ((soc_private->soc_id == SDM670_SOC_ID) && - (soc_private->hw_rev == SDM670_V1_1))))) { + (soc_private->hw_rev == SDM670_V1_1)))) { struct cam_cpas_reg *reg_info; int tcsr_index; diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h index d7432d9b75b1..d628fd1a31c6 100644 --- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h +++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h @@ -44,6 +44,7 @@ /* soc id */ #define SDM670_SOC_ID 336 #define SDM710_SOC_ID 360 +#define SDM712_SOC_ID 393 /* Minor Version */ #define SDM670_V1_1 0x1 From 7c143465dbf6986602f9bf1caf9c2576b85ea369 Mon Sep 17 00:00:00 2001 From: Naman Padhiar Date: Mon, 1 Jul 2019 12:10:47 +0530 Subject: [PATCH 047/281] ARM: dts: msm: Enable thermal mitigation support in WLAN Add cooling device cells property in icnss node to enable thermal mitigation support in WLAN. Change-Id: I28152e3a6c06ece7bb4235feae5b439348cc64b1 Signed-off-by: Naman Padhiar --- arch/arm64/boot/dts/qcom/sdm670.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi index 112b30a1b054..021549cf5cac 100644 --- a/arch/arm64/boot/dts/qcom/sdm670.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi @@ -2615,6 +2615,7 @@ qcom,gpio-force-fatal-error = <&smp2pgpio_wlan_1_in 0 0>; qcom,gpio-early-crash-ind = <&smp2pgpio_wlan_1_in 1 0>; qcom,smmu-s1-bypass; + #cooling-cells = <2>; }; cpubw: qcom,cpubw { From 1e16ab2c8b2b0535238155c534a0ceb14d24c59b Mon Sep 17 00:00:00 2001 From: Jim Blackler Date: Thu, 13 Jun 2019 11:54:36 +0100 Subject: [PATCH 048/281] ANDROID: Avoid taking multiple locks in handle_lmk_event Conflicting lock events have been reported resulting from rcu_read_lock, mmap_sem (in get_cmdline) and lmk_event_lock. This CL avoids the possibility of these conditions by moving handle_lmk_event outside rcu_read_lock and invoking get_cmdline before lmk_event_lock is taken. Bug: 133479338, 133829075 Signed-off-by: Jim Blackler Change-Id: Ib3c32587472bd972e3ac108798e2af3f4a5c329a Git-commit: bee613dd183bd50f25762589b5a94a4ab2416732 Git-repo: https://android.googlesource.com/kernel/common/ [spathi@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Srinivasarao P --- drivers/staging/android/lowmemorykiller.c | 29 +++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index b62bff717543..a098685daa15 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -127,6 +127,7 @@ void handle_lmk_event(struct task_struct *selected, short min_score_adj) struct lmk_event *event; int res; long rss_in_pages = -1; + char taskname[MAX_TASKNAME]; struct mm_struct *mm = get_task_mm(selected); if (mm) { @@ -134,6 +135,17 @@ void handle_lmk_event(struct task_struct *selected, short min_score_adj) mmput(mm); } + res = get_cmdline(selected, taskname, MAX_TASKNAME - 1); + + /* No valid process name means this is definitely not associated with a + * userspace activity. + */ + + if (res <= 0 || res >= MAX_TASKNAME) + return; + + taskname[res] = '\0'; + spin_lock(&lmk_event_lock); head = event_buffer.head; @@ -148,18 +160,8 @@ void handle_lmk_event(struct task_struct *selected, short min_score_adj) events = (struct lmk_event *) event_buffer.buf; event = &events[head]; - res = get_cmdline(selected, event->taskname, MAX_TASKNAME - 1); + memcpy(event->taskname, taskname, res + 1); - /* No valid process name means this is definitely not associated with a - * userspace activity. - */ - - if (res <= 0 || res >= MAX_TASKNAME) { - spin_unlock(&lmk_event_lock); - return; - } - - event->taskname[res] = '\0'; event->pid = selected->pid; event->uid = from_kuid_munged(current_user_ns(), task_uid(selected)); if (selected->group_leader) @@ -785,7 +787,6 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) lowmem_deathpending_timeout = jiffies + HZ; rem += selected_tasksize; - handle_lmk_event(selected, min_score_adj); rcu_read_unlock(); /* give the system time to free up the memory */ msleep_interruptible(20); @@ -800,6 +801,10 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) lowmem_print(4, "lowmem_scan %lu, %x, return %lu\n", sc->nr_to_scan, sc->gfp_mask, rem); mutex_unlock(&scan_mutex); + + if (selected) + handle_lmk_event(selected, min_score_adj); + return rem; } From 744fed9ad6240ee8b76b55c3002479939c2c6d35 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Thu, 27 Jun 2019 12:17:52 +0530 Subject: [PATCH 049/281] power: qpnp-smb2: Add a DT property to disable USB power-delivery (PD) Platforms where the USB PHY is not enabled to support USB PD, the PD support from PMIC can be disabled. Change-Id: Ibc69700642c48d17c0dc54361fb1e0c011d572ae Signed-off-by: Kiran Gunda --- .../devicetree/bindings/power/supply/qcom/qpnp-smb2.txt | 5 +++++ drivers/power/supply/qcom/qpnp-smb2.c | 7 ++++++- drivers/power/supply/qcom/smb-lib.c | 2 +- drivers/power/supply/qcom/smb-lib.h | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt index 452fff9ef89b..f8c79d4c1ae6 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt @@ -168,6 +168,11 @@ Charger specific properties: Definition: Specifies the deglitch interval for OTG detection. If the value is not present, 50 msec is used as default. +- qcom,pd-not-supported + Usage: optional + Value type: bool + Definition: Option to indicate if the platform supports USB PD (power delivery). + - qcom,step-charging-enable Usage: optional Value type: bool diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 855901b18500..049ee4453abb 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -170,6 +170,7 @@ struct smb_dt_props { bool hvdcp_disable; bool auto_recharge_soc; int wd_bark_time; + bool no_pd; }; struct smb2 { @@ -234,6 +235,9 @@ static int smb2_parse_dt(struct smb2 *chip) chip->dt.no_battery = of_property_read_bool(node, "qcom,batteryless-platform"); + chip->dt.no_pd = of_property_read_bool(node, + "qcom,pd-not-supported"); + rc = of_property_read_u32(node, "qcom,fcc-max-ua", &chg->batt_profile_fcc_ua); if (rc < 0) @@ -1644,7 +1648,8 @@ static int smb2_init_hw(struct smb2 *chip) true, 0); vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, true, 0); - + vote(chg->pd_disallowed_votable_indirect, PD_NOT_SUPPORTED_VOTER, + chip->dt.no_pd, 0); /* * AICL configuration: * start from min and AICL ADC disable diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 3885fbfa378f..5ec38eb5d4d0 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -2947,7 +2947,7 @@ static int __smblib_set_prop_pd_active(struct smb_charger *chg, bool pd_active) hvdcp = stat & QC_CHARGER_BIT; vote(chg->apsd_disable_votable, PD_VOTER, false, 0); - vote(chg->pd_allowed_votable, PD_VOTER, true, 0); + vote(chg->pd_allowed_votable, PD_VOTER, false, 0); vote(chg->usb_irq_enable_votable, PD_VOTER, false, 0); vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER, false, 0); diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index 87a83037459c..490bb38c03e0 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -73,6 +73,7 @@ enum print_reason { #define OV_VOTER "OV_VOTER" #define FG_ESR_VOTER "FG_ESR_VOTER" #define FCC_STEPPER_VOTER "FCC_STEPPER_VOTER" +#define PD_NOT_SUPPORTED_VOTER "PD_NOT_SUPPORTED_VOTER" #define VCONN_MAX_ATTEMPTS 3 #define OTG_MAX_ATTEMPTS 3 From b8e40bd449e6897edbdf45a7364adb198a5e3d23 Mon Sep 17 00:00:00 2001 From: Manu Gautam Date: Thu, 6 Jun 2019 14:29:39 +0530 Subject: [PATCH 050/281] usb: dwc3-msm: Use dummy buffer as doorbell until GSI is ready USB GSI wrapper can try to access IPA GSI Doorbell as soon as endpoint is enabled and transfers are started. However there is always going to be some delay when transfers are started and GSI doorbell address is updated. This may result in USB GSI wrapper accessing address-0. Prevent this by using some dummy buffer as doorbell until IPA GSI connections are setup. At that stage driver will override doorbell address with valid one. Change-Id: I477602d33737a994992c5394c6c08d63744e525f Signed-off-by: Manu Gautam --- drivers/usb/dwc3/dwc3-msm.c | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 24b9422c7e95..af704b7228d5 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -309,6 +309,9 @@ struct dwc3_msm { struct mutex suspend_resume_mutex; enum usb_device_speed override_usb_speed; + + u64 dummy_gsi_db; + dma_addr_t dummy_gsi_db_dma; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ @@ -974,6 +977,12 @@ static void gsi_store_ringbase_dbl_info(struct usb_ep *ep, ep->name, request->db_reg_phs_addr_lsb, (unsigned long long)request->mapped_db_reg_phs_addr_lsb); + /* + * Replace dummy doorbell address with real one as IPA connection + * is setup now and GSI must be ready to handle doorbell updates. + */ + dwc3_msm_write_reg(mdwc->base, GSI_DBL_ADDR_H(n), 0x0); + dwc3_msm_write_reg(mdwc->base, GSI_DBL_ADDR_L(n), (u32)request->mapped_db_reg_phs_addr_lsb); dev_dbg(mdwc->dev, "Ring Base Addr %d: %x (LSB)\n", n, @@ -1247,9 +1256,20 @@ static void gsi_configure_ep(struct usb_ep *ep, struct usb_gsi_request *request) struct dwc3_gadget_ep_cmd_params params; const struct usb_endpoint_descriptor *desc = ep->desc; const struct usb_ss_ep_comp_descriptor *comp_desc = ep->comp_desc; + int n = ep->ep_intr_num - 1; u32 reg; int ret; + /* setup dummy doorbell as IPA connection isn't setup yet */ + dwc3_msm_write_reg(mdwc->base, GSI_DBL_ADDR_H(n), + (u32)((u64)mdwc->dummy_gsi_db_dma >> 32)); + + dwc3_msm_write_reg(mdwc->base, GSI_DBL_ADDR_L(n), + (u32)mdwc->dummy_gsi_db_dma); + dev_dbg(mdwc->dev, "Dummy DB Addr %pK: %llx %x (LSB)\n", + &mdwc->dummy_gsi_db, (unsigned long long)mdwc->dummy_gsi_db_dma, + (u32)mdwc->dummy_gsi_db_dma); + memset(¶ms, 0x00, sizeof(params)); /* Configure GSI EP */ @@ -2032,6 +2052,19 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, } mdwc->gsi_ev_buff[i] = evt; } + /* + * Set-up dummy buffer to use as doorbell while IPA GSI + * connection is in progress. + */ + mdwc->dummy_gsi_db_dma = dma_map_single(dwc->sysdev, + &mdwc->dummy_gsi_db, + sizeof(mdwc->dummy_gsi_db), + DMA_FROM_DEVICE); + + if (dma_mapping_error(dwc->sysdev, mdwc->dummy_gsi_db_dma)) { + dev_err(dwc->dev, "failed to map dummy doorbell buffer\n"); + mdwc->dummy_gsi_db_dma = (dma_addr_t)NULL; + } break; case DWC3_GSI_EVT_BUF_SETUP: dev_dbg(mdwc->dev, "DWC3_GSI_EVT_BUF_SETUP\n"); @@ -2105,6 +2138,12 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma); } + if (mdwc->dummy_gsi_db_dma) { + dma_unmap_single(dwc->sysdev, mdwc->dummy_gsi_db_dma, + sizeof(mdwc->dummy_gsi_db), + DMA_FROM_DEVICE); + mdwc->dummy_gsi_db_dma = (dma_addr_t)NULL; + } break; case DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER: dwc3_msm_dbm_disable_updxfer(dwc, value); From 53f4444461ccc15de3b0b4c55abc1ab5298053ff Mon Sep 17 00:00:00 2001 From: Baochu Xu Date: Mon, 1 Jul 2019 16:06:13 +0800 Subject: [PATCH 051/281] ARM: dts: msm: Config smart PA pinctl for SDM429W Config smart PA pinctl for SDM429W Change-Id: I634188c81c730abd2a4759d811465c3b6e41c943 Signed-off-by: Baochu Xu --- .../boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi index 3c70102b2557..fe431596049f 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi @@ -491,6 +491,36 @@ }; }; + smart_pa_int { + pa_int_default: pa_int_default { + mux { + pins = "gpio73", "gpio73"; + function = "gpio"; + }; + + config { + pins = "gpio73", "gpio73"; + drive-strength = <4>; + bias-disable; + }; + }; + }; + + smart_pa_rst { + pa_rst_default: pa_rst_default { + mux { + pins = "gpio68", "gpio68"; + function = "gpio"; + }; + + config { + pins = "gpio68", "gpio68"; + drive-strength = <4>; + bias-disable; + }; + }; + }; + }; &modem_mem { @@ -545,6 +575,9 @@ pinctrl-3 = <&quat_mi2s_active &quat_mi2s_din_active &cdc_dmic0_clk_act &cdc_dmic0_data_act>; /delete-property/qcom,cdc-us-euro-gpios; + /delete-property/qcom,pri-mi2s-gpios; + /delete-property/qcom,cdc-us-eu-gpios; + asoc-codec = <&stub_codec>, <&msm_dig_codec>; asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec"; @@ -596,11 +629,26 @@ status = "disabled"; }; +&cdc_us_euro_sw { + status = "disabled"; +}; + +&cdc_pri_mi2s_gpios { + status = "disabled"; +}; + +&cdc_quin_mi2s_gpios { + status = "disabled"; +}; + &i2c_2 { aw8896_smartpa@34 { compatible = "awinic,aw8896_smartpa"; reg = <0x34>; reset-gpio = <&tlmm 68 0>; + irq-gpio = <&tlmm 73 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pa_int_default &pa_rst_default>; status = "okay"; }; }; From 5c526199cfeba88be1e2ada458c19fc045791045 Mon Sep 17 00:00:00 2001 From: Kavya Nunna Date: Mon, 24 Jun 2019 16:38:24 +0530 Subject: [PATCH 052/281] arm: dts: msm: Add overlay/non-overlay support for SDM450 no-pmi config Add dts files for both overlay and non-overlay NO-PMI configuration for SDM450. While at it, remove the board-id configuration from the soc NO-PMI file. Change-Id: I9ad8f6b2a5fc030d206c97f081c8fd58a0f26af8 Signed-off-by: Kavya Nunna --- arch/arm64/boot/dts/qcom/Makefile | 6 +- .../dts/qcom/sdm450-no-pmi-mtp-overlay.dts | 21 ++++++ .../arm64/boot/dts/qcom/sdm450-no-pmi-mtp.dts | 69 +++++++++++++++++++ arch/arm64/boot/dts/qcom/sdm450-no-pmi.dts | 1 - arch/arm64/boot/dts/qcom/sdm450-pmi632.dts | 1 - 5 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/sdm450-no-pmi-mtp-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/sdm450-no-pmi-mtp.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index b932dab70dbd..ebde8c4efe97 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -373,7 +373,7 @@ dtbo-$(CONFIG_ARCH_SDM450) += msm8953-mtp-overlay.dtbo \ sdm450-cdp-s2-overlay.dtbo \ sdm450-mtp-s3-overlay.dtbo \ sdm450-qrd-sku4-overlay.dtbo\ - sdm450-no-pmi-overlay.dtbo + sdm450-no-pmi-mtp-overlay.dtbo dtbo-$(CONFIG_ARCH_SDM632) += sdm632-rumi-overlay.dtbo \ sdm450-cdp-s2-overlay.dtbo \ @@ -481,7 +481,7 @@ sdm450-qrd-sku4-overlay.dtbo-base := sdm450-pmi632.dtb \ sdm632.dtb \ sdm632-pm8004.dtb -sdm450-no-pmi-overlay.dtbo-base := sdm450-no-pmi.dtb +sdm450-no-pmi-mtp-overlay.dtbo-base := sdm450-no-pmi.dtb sdm632-rumi-overlay.dtbo-base := sdm632.dtb sdm632-ext-codec-cdp-s3-overlay.dtbo-base := sdm632.dtb \ @@ -612,7 +612,7 @@ dtb-$(CONFIG_ARCH_SDM450) += sdm450-rcm.dtb \ sdm450-pmi632-mtp-s3.dtb \ sda450-pmi632-cdp-s2.dtb \ sda450-pmi632-mtp-s3.dtb \ - sdm450-no-pmi.dtb + sdm450-no-pmi-mtp.dtb dtb-$(CONFIG_ARCH_SDM632) += sdm632-rumi.dtb \ sdm632-cdp-s2.dtb \ diff --git a/arch/arm64/boot/dts/qcom/sdm450-no-pmi-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm450-no-pmi-mtp-overlay.dts new file mode 100644 index 000000000000..cd78c2c5a4f2 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm450-no-pmi-mtp-overlay.dts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2019, 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/; +/plugin/; + +/ { + model = " SDM450 NOPMI MTP"; + qcom,board-id = <8 3>; +}; + diff --git a/arch/arm64/boot/dts/qcom/sdm450-no-pmi-mtp.dts b/arch/arm64/boot/dts/qcom/sdm450-no-pmi-mtp.dts new file mode 100644 index 000000000000..71a9eeffecb3 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm450-no-pmi-mtp.dts @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, 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 "sdm450.dtsi" +#include "msm8953-mtp.dtsi" +/ { + model = "Qualcomm Technologies, Inc. SDM450 + NO PMI MTP S3"; + compatible = "qcom,sdm450-mtp", "qcom,sdm450", "qcom,mtp"; + qcom,board-id = <8 3>; + qcom,pmic-id = <0x010016 0x0 0x0 0x0>; +}; + +&eeprom0 { + cam_vdig-supply = <&pm8953_l23>; +}; + +&camera0 { + cam_vdig-supply = <&pm8953_l23>; +}; + +&pm8953_gpios { + bklt_en { + bklt_en_default: bklt_en_default { + pins = "gpio4"; + function = "normal"; + power-source = <0>; + output-high; + }; + }; +}; + +&pm8953_pwm { + status = "ok"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_hx8399c_truly_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active &bklt_en_default>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-bklight-en-gpio = <&pm8953_gpios 4 0>; + +}; + +&dsi_truly_1080_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm"; + qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>; + qcom,mdss-dsi-bl-pmic-bank-select = <0>; + qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>; +}; + +&dsi_hx8399c_truly_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm"; + qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>; + qcom,mdss-dsi-bl-pmic-bank-select = <0>; + qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm450-no-pmi.dts b/arch/arm64/boot/dts/qcom/sdm450-no-pmi.dts index 71a9eeffecb3..afb35543c23f 100644 --- a/arch/arm64/boot/dts/qcom/sdm450-no-pmi.dts +++ b/arch/arm64/boot/dts/qcom/sdm450-no-pmi.dts @@ -18,7 +18,6 @@ / { model = "Qualcomm Technologies, Inc. SDM450 + NO PMI MTP S3"; compatible = "qcom,sdm450-mtp", "qcom,sdm450", "qcom,mtp"; - qcom,board-id = <8 3>; qcom,pmic-id = <0x010016 0x0 0x0 0x0>; }; diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dts b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dts index 5f9b0464aa48..cb01d3917aac 100644 --- a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dts +++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dts @@ -19,7 +19,6 @@ / { model = "Qualcomm Technologies, Inc. SDM450 + PMI632 SOC"; compatible = "qcom,sdm450"; - qcom,board-id = <8 3>; qcom,pmic-id = <0x16 0x25 0x0 0x0>; qcom,pmic-name = "PMI632"; }; From 687c0f64c59d10bfcc14643376f3f34beb655344 Mon Sep 17 00:00:00 2001 From: Jim Blackler Date: Thu, 13 Jun 2019 11:54:36 +0100 Subject: [PATCH 053/281] ANDROID: Avoid taking multiple locks in handle_lmk_event Conflicting lock events have been reported resulting from rcu_read_lock, mmap_sem (in get_cmdline) and lmk_event_lock. This CL avoids the possibility of these conditions by moving handle_lmk_event outside rcu_read_lock and invoking get_cmdline before lmk_event_lock is taken. Bug: 133479338, 133829075 Signed-off-by: Jim Blackler Change-Id: Ib3c32587472bd972e3ac108798e2af3f4a5c329a Git-commit: bee613dd183bd50f25762589b5a94a4ab2416732 Git-repo: https://android.googlesource.com/kernel/common/ [spathi@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Srinivasarao P --- drivers/staging/android/lowmemorykiller.c | 29 +++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index b62bff717543..a098685daa15 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -127,6 +127,7 @@ void handle_lmk_event(struct task_struct *selected, short min_score_adj) struct lmk_event *event; int res; long rss_in_pages = -1; + char taskname[MAX_TASKNAME]; struct mm_struct *mm = get_task_mm(selected); if (mm) { @@ -134,6 +135,17 @@ void handle_lmk_event(struct task_struct *selected, short min_score_adj) mmput(mm); } + res = get_cmdline(selected, taskname, MAX_TASKNAME - 1); + + /* No valid process name means this is definitely not associated with a + * userspace activity. + */ + + if (res <= 0 || res >= MAX_TASKNAME) + return; + + taskname[res] = '\0'; + spin_lock(&lmk_event_lock); head = event_buffer.head; @@ -148,18 +160,8 @@ void handle_lmk_event(struct task_struct *selected, short min_score_adj) events = (struct lmk_event *) event_buffer.buf; event = &events[head]; - res = get_cmdline(selected, event->taskname, MAX_TASKNAME - 1); + memcpy(event->taskname, taskname, res + 1); - /* No valid process name means this is definitely not associated with a - * userspace activity. - */ - - if (res <= 0 || res >= MAX_TASKNAME) { - spin_unlock(&lmk_event_lock); - return; - } - - event->taskname[res] = '\0'; event->pid = selected->pid; event->uid = from_kuid_munged(current_user_ns(), task_uid(selected)); if (selected->group_leader) @@ -785,7 +787,6 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) lowmem_deathpending_timeout = jiffies + HZ; rem += selected_tasksize; - handle_lmk_event(selected, min_score_adj); rcu_read_unlock(); /* give the system time to free up the memory */ msleep_interruptible(20); @@ -800,6 +801,10 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) lowmem_print(4, "lowmem_scan %lu, %x, return %lu\n", sc->nr_to_scan, sc->gfp_mask, rem); mutex_unlock(&scan_mutex); + + if (selected) + handle_lmk_event(selected, min_score_adj); + return rem; } From e96bc193ceb1d52ee3710440176e291b70633eda Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Wed, 3 Apr 2019 18:26:21 +0800 Subject: [PATCH 054/281] sched/fair: Avoid cpu idle to deep sleep when have active balance Avoid cpu idle to deep sleep when have active balance task to be coming. Change-Id: Ie1c0f7fe0ff3da38d0a8f5ebe974080a52b7e6f4 Signed-off-by: Maria Yu --- kernel/sched/fair.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index a4215a6d1deb..39c1a0087512 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -10288,6 +10288,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, busiest->active_balance = 1; busiest->push_cpu = this_cpu; active_balance = 1; + mark_reserved(this_cpu); } raw_spin_unlock_irqrestore(&busiest->lock, flags); @@ -10612,6 +10613,7 @@ static int active_load_balance_cpu_stop(void *data) busiest_rq->active_balance = 0; push_task = busiest_rq->push_task; target_cpu = busiest_rq->push_cpu; + clear_reserved(target_cpu); if (push_task) busiest_rq->push_task = NULL; @@ -10622,7 +10624,6 @@ static int active_load_balance_cpu_stop(void *data) if (push_task_detached) attach_one_task(target_rq, push_task); put_task_struct(push_task); - clear_reserved(target_cpu); } if (p) From 3b85e99591ac231123191d6a8ab89e5c14dcfeb8 Mon Sep 17 00:00:00 2001 From: Mohammed Siddiq Date: Tue, 2 Jul 2019 17:49:34 +0530 Subject: [PATCH 055/281] icnss: Reduce the shutdown timeout from 50sec to 15sec Sub-system shutdown timeout is 20 seconds. In wlan platform driver, modem block shutdown timeout should be less than sub-system timeout. Hence, change block shutdown timeout to 15 seconds. Change-Id: I936e0c462858727b86b35b924dd124a5d1434780 Signed-off-by: Mohammed Siddiq --- drivers/soc/qcom/icnss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index ac36b27ada7c..a2cbfd83a70d 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -77,7 +77,7 @@ module_param(qmi_timeout, ulong, 0600); #define ICNSS_MAX_PROBE_CNT 2 -#define PROBE_TIMEOUT 5000 +#define PROBE_TIMEOUT 15000 #define icnss_ipc_log_string(_x...) do { \ if (icnss_ipc_log_context) \ @@ -2864,8 +2864,8 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) { if (!wait_for_completion_timeout(&priv->unblock_shutdown, - PROBE_TIMEOUT)) - icnss_pr_err("wlan driver probe timeout\n"); + msecs_to_jiffies(PROBE_TIMEOUT))) + icnss_pr_err("modem block shutdown timeout\n"); } if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) { From de270245295fb7ea205b363ae1e6988d55cfd11e Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Tue, 25 Jun 2019 10:30:53 -0700 Subject: [PATCH 056/281] ARM: dts: msm: Enable IPC over MHI for SA415M CCARD Enable the IPC router over MHI_DEV configuration for SA415M CCARD boards. Change-Id: Ib79783b734f6b77b01e59efcd05aaa2ca65efe7f Signed-off-by: Gustavo Solaira --- arch/arm/boot/dts/qcom/sdxpoorwills-ccard-pcie-ep.dts | 4 ++++ arch/arm/boot/dts/qcom/sdxpoorwills.dtsi | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard-pcie-ep.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-ccard-pcie-ep.dts index 0e712a1f55a4..c7bf2bd31c35 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard-pcie-ep.dts +++ b/arch/arm/boot/dts/qcom/sdxpoorwills-ccard-pcie-ep.dts @@ -48,3 +48,7 @@ &restart_pshold { qcom,force-warm-reboot; }; + +&ipc_router_mhi_dev_xprt { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi index fa37005d1c5d..bd66b290f43c 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi @@ -510,7 +510,7 @@ status = "disabled"; }; - qcom,ipc_router_mhi_dev_xprt { + ipc_router_mhi_dev_xprt: qcom,ipc_router_mhi_dev_xprt { compatible = "qcom,ipc-router-mhi-dev-xprt"; qcom,out-chan-id = <20>; qcom,in-chan-id = <21>; From 0d740507311810f6fd4f28e55627274573809831 Mon Sep 17 00:00:00 2001 From: Venu Raidu Date: Tue, 2 Apr 2019 18:45:27 +0530 Subject: [PATCH 057/281] msm: jpeg: Add support for SMMU fault handler Support SMMU fault handler for JPEG module Change-Id: I592a140705be21097c298c99f0af5b67dd68bbc9 Signed-off-by: Venu Raidu Signed-off-by: Sumalatha Malothu --- .../msm/camera_v2/jpeg_10/msm_jpeg_sync.c | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c index 3daee21325c4..0335c406a7ad 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c +++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 2018-2019, 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 @@ -1536,6 +1536,46 @@ long __msm_jpeg_ioctl(struct msm_jpeg_device *pgmn_dev, return rc; } +static void msm_jpeg_iommu_fault_handler (struct iommu_domain *domain, + struct device *dev, unsigned long iova, int flags, void *token) +{ + struct msm_jpeg_device *pgmn_dev; + + if (token) { + pgmn_dev = token; + JPEG_PR_ERR("%s: core type %d addr 0x%lx\n", + __func__, pgmn_dev->core_type, iova); + JPEG_PR_ERR("%s: FE ion_fd %d y_addr 0x%x y_len %d\n", + __func__, + pgmn_dev->fe_pingpong_buf.buf[1].ion_fd, + pgmn_dev->fe_pingpong_buf.buf[1].y_buffer_addr, + pgmn_dev->fe_pingpong_buf.buf[1].y_len); + JPEG_PR_ERR("%s: FE cbcr_addr %x cbcr_len %d\n", + __func__, + pgmn_dev->fe_pingpong_buf.buf[1].cbcr_buffer_addr, + pgmn_dev->fe_pingpong_buf.buf[1].cbcr_len); + JPEG_PR_ERR("%s: FE pln2_addr %x pln2_len %d frame_len %d\n", + __func__, + pgmn_dev->fe_pingpong_buf.buf[1].pln2_addr, + pgmn_dev->fe_pingpong_buf.buf[1].pln2_len, + pgmn_dev->fe_pingpong_buf.buf[1].framedone_len); + JPEG_PR_ERR("%s: WE ion_fd %d y_addr 0x%x y_len %d\n", + __func__, + pgmn_dev->we_pingpong_buf.buf[0].ion_fd, + pgmn_dev->we_pingpong_buf.buf[0].y_buffer_addr, + pgmn_dev->we_pingpong_buf.buf[0].y_len); + JPEG_PR_ERR("%s: WE cbcr_addr %x cbcr_len %d\n", + __func__, + pgmn_dev->we_pingpong_buf.buf[0].cbcr_buffer_addr, + pgmn_dev->we_pingpong_buf.buf[0].cbcr_len); + JPEG_PR_ERR("%s: WE pln2_addr %x pln2_len %d frame_len %d\n", + __func__, + pgmn_dev->we_pingpong_buf.buf[0].pln2_addr, + pgmn_dev->we_pingpong_buf.buf[0].pln2_len, + pgmn_dev->we_pingpong_buf.buf[0].framedone_len); + } +} + int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev) { int rc = 0; @@ -1569,6 +1609,12 @@ int __msm_jpeg_init(struct msm_jpeg_device *pgmn_dev) goto err_smmu; } + cam_smmu_reg_client_page_fault_handler( + pgmn_dev->iommu_hdl, + msm_jpeg_iommu_fault_handler, + NULL, + pgmn_dev); + /* setup all the resources for the jpeg driver */ rc = msm_jpeg_platform_setup(pgmn_dev); if (rc < 0) { From 7dce559453373445da72075e8bf56138e847f0e1 Mon Sep 17 00:00:00 2001 From: Fei Date: Tue, 25 Jun 2019 15:58:01 +0800 Subject: [PATCH 058/281] input: touchscreen: cyttsp5: add code copyright Add Linux Linux Foundation copyright because original source code doesn't have a lastest copyright. Change-Id: I6cb02b1d943db68c083126b4efa78799b1af520a Signed-off-by: Fei --- drivers/input/touchscreen/cyttsp5/cyttsp5_btn.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_core.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_debug.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_devtree.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_i2c.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_loader.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_mta.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_mtb.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_platform.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_proximity.c | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h | 3 ++- drivers/input/touchscreen/cyttsp5/cyttsp5_spi.c | 3 ++- .../input/touchscreen/cyttsp5/cyttsp5_test_device_access_api.c | 3 ++- 15 files changed, 30 insertions(+), 15 deletions(-) diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_btn.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_btn.c index 0150990c9d0b..83d2e821492e 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_btn.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_btn.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c index ef4bf38d32f2..899d1bb299db 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_debug.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_debug.c index 698a144c77ab..bfacde331d7e 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_debug.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_debug.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c index 59bf31a8bf17..14dcdb572db4 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c @@ -10,7 +10,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_devtree.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_devtree.c index 783082a309b2..c6e55963fd50 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_devtree.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_devtree.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2013-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_i2c.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_i2c.c index 930741166252..5479487070a7 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_i2c.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_i2c.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_loader.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_loader.c index b548489ac31b..9f3f586467cc 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_loader.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_loader.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor, Inc. * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c index 62f92c34ba0f..0375093c2e5e 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_mta.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_mta.c index 25089dbaf4dc..931ad18958f6 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_mta.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_mta.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_mtb.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_mtb.c index 5846d6e2dc21..286eb326355a 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_mtb.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_mtb.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_platform.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_platform.c index 9e305354b9d5..308ac0c8d7c0 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_platform.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_platform.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2013-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_proximity.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_proximity.c index 8704b038a617..18b9baa51fe4 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_proximity.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_proximity.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2013-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h b/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h index 4fb6ae3cc55a..e7b16db91b1f 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_spi.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_spi.c index 3cbfecc52a1b..70df0cd58d56 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_spi.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_spi.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_test_device_access_api.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_test_device_access_api.c index f7ee817fc587..dc9a29bfaf3a 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_test_device_access_api.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_test_device_access_api.c @@ -9,7 +9,8 @@ * CYTT21XXX * CYTT31XXX * - * Copyright (C) 2015-2019 Parade Technologies + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Parade Technologies * Copyright (C) 2012-2015 Cypress Semiconductor * * This program is free software; you can redistribute it and/or From 57f37b059fbce2ff4918e8ace49f835686775cf1 Mon Sep 17 00:00:00 2001 From: daopingl Date: Tue, 2 Jul 2019 22:27:55 +0800 Subject: [PATCH 059/281] ARM:dts:msm: Add new camera dtsi file for sdm845 rb3 device currently RB3 project is using the same dtsi as MTP device but actually the RB3 device have many diffirent from MTP devices in camera side, such as camera control pins. in order to avoid the confliction with MTP device when camera sensor bring up, add new camera dtsi file for RB3 device. Change-Id: I491ec598257b841cdd36390e663edabd2997a24f Signed-off-by: Daoping Lin --- .../dts/qcom/sdm845-camera-sensor-rb3.dtsi | 465 +++++++++++++++ arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi | 28 + arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi | 543 ++++++++++++++++++ arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi | 2 +- 4 files changed, 1037 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi create mode 100644 arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi new file mode 100644 index 000000000000..4a870e960330 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi @@ -0,0 +1,465 @@ +/* + * Copyright (c) 2019, 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 { + led_flash_rear: qcom,camera-flash@0 { + cell-index = <0>; + reg = <0x00 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pmi8998_flash0 &pmi8998_flash1>; + torch-source = <&pmi8998_torch0 &pmi8998_torch1>; + switch-source = <&pmi8998_switch0>; + status = "ok"; + }; + + led_flash_rear_aux: qcom,camera-flash@1 { + cell-index = <1>; + reg = <0x01 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pmi8998_flash0 &pmi8998_flash1>; + torch-source = <&pmi8998_torch0 &pmi8998_torch1>; + switch-source = <&pmi8998_switch0>; + status = "ok"; + }; + + led_flash_front: qcom,camera-flash@2 { + cell-index = <2>; + reg = <0x02 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pmi8998_flash2>; + torch-source = <&pmi8998_torch2>; + switch-source = <&pmi8998_switch1>; + status = "ok"; + }; + + led_flash_iris: qcom,camera-flash@3 { + cell-index = <3>; + reg = <0x03 0x00>; + compatible = "qcom,camera-flash"; + flash-source = <&pmi8998_flash2>; + torch-source = <&pmi8998_torch2>; + switch-source = <&pmi8998_switch2>; + status = "ok"; + }; + + actuator_regulator: gpio-regulator@0 { + compatible = "regulator-fixed"; + reg = <0x00 0x00>; + regulator-name = "actuator_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <100>; + enable-active-high; + gpio = <&tlmm 27 0>; + vin-supply = <&pmi8998_bob>; + }; + + camera_rear_ldo: gpio-regulator@1 { + compatible = "regulator-fixed"; + reg = <0x01 0x00>; + regulator-name = "camera_rear_ldo"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-enable-ramp-delay = <135>; + enable-active-high; + gpio = <&pm8998_gpios 12 0>; + pinctrl-names = "default"; + pinctrl-0 = <&camera_rear_dvdd_en_default>; + vin-supply = <&pm8998_s3>; + }; + + camera_ldo: gpio-regulator@2 { + compatible = "regulator-fixed"; + reg = <0x02 0x00>; + regulator-name = "camera_ldo"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-enable-ramp-delay = <233>; + enable-active-high; + gpio = <&pm8998_gpios 9 0>; + pinctrl-names = "default"; + pinctrl-0 = <&camera_dvdd_en_default>; + vin-supply = <&pm8998_s3>; + }; + + camera_vana_ldo: gpio-regulator@4 { + compatible = "regulator-fixed"; + reg = <0x04 0x00>; + regulator-name = "camera_vana_ldo"; + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + regulator-enable-ramp-delay = <233>; + enable-active-high; + gpio = <&tlmm 10 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cam_sensor_rear_vana>; + vin-supply = <&pmi8998_bob>; + }; +}; + +&cam_cci { + qcom,cam-res-mgr { + compatible = "qcom,cam-res-mgr"; + status = "ok"; + }; + + actuator_rear: qcom,actuator@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,actuator"; + cci-master = <0>; + cam_vaf-supply = <&actuator_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + actuator_rear_aux: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + cci-master = <1>; + cam_vaf-supply = <&actuator_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + actuator_front: qcom,actuator@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,actuator"; + cci-master = <1>; + cam_vaf-supply = <&actuator_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + }; + + ois_rear: qcom,ois@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,ois"; + cci-master = <0>; + cam_vaf-supply = <&actuator_regulator>; + regulator-names = "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <2800000>; + rgltr-max-voltage = <2800000>; + rgltr-load-current = <0>; + status = "ok"; + }; + + eeprom_rear: qcom,eeprom@0 { + cell-index = <0>; + reg = <0>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&camera_rear_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + cam_vaf-supply = <&actuator_regulator>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <0 3312000 1050000 0 2800000>; + rgltr-max-voltage = <0 3600000 1050000 0 2800000>; + rgltr-load-current = <0 80000 105000 0 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_rear_suspend>; + gpios = <&tlmm 13 0>, + <&tlmm 80 0>, + <&tlmm 79 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VANA0"; + sensor-position = <0>; + sensor-mode = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + + eeprom_tof: qcom,eeprom@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,eeprom"; + slave-addr = <0xac>; + num-blocks = <1>; + i2c-freq-mode = <1>; + + page0 = <0 0x0 2 0x0 1 0>; + poll0 = <0 0x0 2 0x0 1 0>; + mem0 = <0x870 0x0 2 0x0 1 0>; + + cam_vio-supply = <&pm8998_lvs1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <0 0>; + rgltr-max-voltage = <0 0>; + rgltr-load-current = <0 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_tof_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_tof_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 8 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK1","CAM_RESET1"; + cci-master = <0>; + + qcom,cam-power-seq-type ="cam_reset","cam_vio", + "cam_clk","cam_reset"; + qcom,cam-power-seq-val = "cam_reset","cam_vio", + "cam_mclk","cam_reset"; + qcom,cam-power-seq-cfg-val = <0 1 24000000 1>; + qcom,cam-power-seq-delay = <1 0 1 18>; + + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + + eeprom_front: qcom,eeprom@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&camera_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + cam_vaf-supply = <&actuator_regulator>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk", "cam_vaf"; + rgltr-cntrl-support; + rgltr-min-voltage = <0 3312000 1050000 0 2800000>; + rgltr-max-voltage = <0 3600000 1050000 0 2800000>; + rgltr-load-current = <0 80000 105000 0 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_front_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 28 0>, + <&tlmm 8 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VANA2"; + sensor-position = <1>; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + + qcom,cam-sensor@0 { + cell-index = <0>; + compatible = "qcom,cam-sensor"; + reg = <0x0>; + csiphy-sd-index = <0>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + led-flash-src = <&led_flash_rear>; + actuator-src = <&actuator_rear>; + ois-src = <&ois_rear>; + eeprom-src = <&eeprom_rear>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&camera_rear_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <0 3312000 1050000 0>; + rgltr-max-voltage = <0 3600000 1050000 0>; + rgltr-load-current = <0 80000 105000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_rear_suspend>; + gpios = <&tlmm 13 0>, + <&tlmm 80 0>, + <&tlmm 79 0>; + gpio-reset = <1>; + gpio-vana = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VANA"; + sensor-mode = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + + qcom,cam-sensor@1 { + cell-index = <1>; + compatible = "qcom,cam-sensor"; + reg = <0x1>; + csiphy-sd-index = <1>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + eeprom-src = <&eeprom_tof>; + cam_vio-supply = <&pm8998_lvs1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <0 0>; + rgltr-max-voltage = <0 0>; + rgltr-load-current = <0 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_tof_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_tof_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 8 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK1","CAM_RESET1"; + sensor-mode = <0>; + cci-master = <0>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + + qcom,cam-sensor@2 { + cell-index = <2>; + compatible = "qcom,cam-sensor"; + reg = <0x02>; + csiphy-sd-index = <2>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <0>; + eeprom-src = <&eeprom_front>; + actuator-src = <&actuator_front>; + led-flash-src = <&led_flash_front>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&camera_vana_ldo>; + cam_vdig-supply = <&camera_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <0 2850000 1050000 0>; + rgltr-max-voltage = <0 2850000 1050000 0>; + rgltr-load-current = <0 80000 105000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_front_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 28 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + + qcom,cam-sensor@3 { + cell-index = <3>; + compatible = "qcom,cam-sensor"; + reg = <0x03>; + csiphy-sd-index = <3>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <0>; + led-flash-src = <&led_flash_iris>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&camera_vana_ldo>; + cam_vdig-supply = <&camera_ldo>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_vana", "cam_vdig", + "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <0 2850000 1050000 0>; + rgltr-max-voltage = <0 2850000 1050000 0>; + rgltr-load-current = <0 80000 105000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_iris_active>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_iris_suspend>; + gpios = <&tlmm 16 0>, + <&tlmm 9 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi index a02cb579f27a..31f9b13cdeef 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi @@ -3407,6 +3407,34 @@ }; }; + cam_sensor_tof_active: cam_sensor_tof_active { + /* RESET*/ + mux { + pins = "gpio8"; + function = "gpio"; + }; + + config { + pins = "gpio8"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_tof_suspend: cam_sensor_tof_suspend { + /* RESET*/ + mux { + pins = "gpio8"; + function = "gpio"; + }; + + config { + pins = "gpio8"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; trigout_a: trigout_a { mux { diff --git a/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi new file mode 100644 index 000000000000..720173203613 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi @@ -0,0 +1,543 @@ +/* Copyright (c) 2019, 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 +#include "sdm845-pmic-overlay.dtsi" +#include "sdm845-pinctrl-overlay.dtsi" +#include "sdm845-camera-sensor-rb3.dtsi" + +&qupv3_se10_i2c { +#include "smb1355.dtsi" +}; + +&vendor { + bluetooth: bt_wcn3990 { + compatible = "qca,wcn3990"; + qca,bt-vdd-io-supply = <&pm8998_s3>; + qca,bt-vdd-xtal-supply = <&pm8998_s5>; + qca,bt-vdd-core-supply = <&pm8998_l7>; + qca,bt-vdd-pa-supply = <&pm8998_l17>; + qca,bt-vdd-ldo-supply = <&pm8998_l25>; + + qca,bt-vdd-io-voltage-level = <1352000 1352000>; + qca,bt-vdd-xtal-voltage-level = <2040000 2040000>; + qca,bt-vdd-core-voltage-level = <1800000 1800000>; + qca,bt-vdd-pa-voltage-level = <1304000 1304000>; + qca,bt-vdd-ldo-voltage-level = <3312000 3312000>; + + qca,bt-vdd-io-current-level = <1>; /* LPM/PFM */ + qca,bt-vdd-xtal-current-level = <1>; /* LPM/PFM */ + qca,bt-vdd-core-current-level = <1>; /* LPM/PFM */ + qca,bt-vdd-pa-current-level = <1>; /* LPM/PFM */ + qca,bt-vdd-ldo-current-level = <1>; /* LPM/PFM */ + }; +}; + +&soc { + gpio_keys { + compatible = "gpio-keys"; + label = "gpio-keys"; + + pinctrl-names = "default"; + pinctrl-0 = <&key_vol_up_default + &key_cam_snapshot_default + &key_cam_focus_default>; + + vol_up { + label = "volume_up"; + gpios = <&pm8998_gpios 6 GPIO_ACTIVE_LOW>; + linux,input-type = <1>; + linux,code = <115>; + gpio-key,wakeup; + debounce-interval = <15>; + linux,can-disable; + }; + + cam_snapshot { + label = "cam_snapshot"; + gpios = <&pm8998_gpios 7 GPIO_ACTIVE_LOW>; + linux,input-type = <1>; + linux,code = <766>; + gpio-key,wakeup; + debounce-interval = <15>; + linux,can-disable; + }; + + cam_focus { + label = "cam_focus"; + gpios = <&pm8998_gpios 8 GPIO_ACTIVE_LOW>; + linux,input-type = <1>; + linux,code = <528>; + gpio-key,wakeup; + debounce-interval = <15>; + linux,can-disable; + }; + }; +}; + +&labibb { + status = "ok"; + qcom,qpnp-labibb-mode = "lcd"; +}; + +&dsi_dual_nt35597_truly_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + 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-mode-gpio = <&tlmm 52 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_nt35597_truly_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + 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-mode-gpio = <&tlmm 52 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; + qcom,platform-te-gpio = <&tlmm 10 0>; +}; + +&dsi_nt35597_truly_dsc_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + 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 = "single_port"; + qcom,panel-mode-gpio = <&tlmm 52 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_nt35597_truly_dsc_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + 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 = "single_port"; + qcom,panel-mode-gpio = <&tlmm 52 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; + qcom,platform-te-gpio = <&tlmm 10 0>; +}; + +&dsi_sim_vid { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_sim_vid { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sim_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_sim_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_sim_dsc_375_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_sim_dsc_375_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_nt35597_video { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + 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-mode-gpio = <&tlmm 52 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; +}; + +&dsi_dual_nt35597_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + 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-mode-gpio = <&tlmm 52 0>; + qcom,platform-reset-gpio = <&tlmm 6 0>; + qcom,platform-te-gpio = <&tlmm 10 0>; +}; + +&dsi_nt35597_truly_dsc_cmd_display { + qcom,dsi-display-active; +}; + +&pmi8998_wled { + status = "okay"; + qcom,led-strings-list = [01 02]; +}; + +&pmi8998_haptics { + qcom,vmax-mv = <2400>; + qcom,lra-auto-mode; + status = "okay"; +}; + +&mdss_mdp { + #cooling-cells = <2>; +}; + +&ufsphy_mem { + compatible = "qcom,ufs-phy-qmp-v3"; + + vdda-phy-supply = <&pm8998_l1>; /* 0.88v */ + vdda-pll-supply = <&pm8998_l26>; /* 1.2v */ + vdda-phy-max-microamp = <62900>; + vdda-pll-max-microamp = <18300>; + + status = "ok"; +}; + +&ufshc_mem { + vdd-hba-supply = <&ufs_phy_gdsc>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8998_l20>; + vcc-voltage-level = <2950000 2960000>; + vccq2-supply = <&pm8998_s4>; + vcc-max-microamp = <600000>; + vccq2-max-microamp = <600000>; + + qcom,vddp-ref-clk-supply = <&pm8998_l2>; + qcom,vddp-ref-clk-max-microamp = <100>; + + status = "ok"; +}; + +&sdhc_2 { + vdd-supply = <&pm8998_l21>; + qcom,vdd-voltage-level = <2950000 2960000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8998_l13>; + qcom,vdd-io-voltage-level = <1808000 2960000>; + qcom,vdd-io-current-level = <200 22000>; + + pinctrl-names = "active", "sleep", "ds_400KHz", + "ds_50MHz", "ds_100MHz", "ds_200MHz"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &storage_cd>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &storage_cd>; + pinctrl-2 = <&sdc2_clk_ds_400KHz + &sdc2_cmd_ds_400KHz &sdc2_data_ds_400KHz>; + pinctrl-3 = <&sdc2_clk_ds_50MHz + &sdc2_cmd_ds_50MHz &sdc2_data_ds_50MHz>; + pinctrl-4 = <&sdc2_clk_ds_100MHz + &sdc2_cmd_ds_100MHz &sdc2_data_ds_100MHz>; + pinctrl-5 = <&sdc2_clk_ds_200MHz + &sdc2_cmd_ds_200MHz &sdc2_data_ds_200MHz>; + + cd-gpios = <&tlmm 126 GPIO_ACTIVE_LOW>; + + status = "ok"; +}; + +&pmi8998_switch1 { + pinctrl-names = "led_enable", "led_disable"; + pinctrl-0 = <&flash_led3_front_en>; + pinctrl-1 = <&flash_led3_front_dis>; +}; + +&pmi8998_switch2 { + pinctrl-names = "led_enable", "led_disable"; + pinctrl-0 = <&flash_led3_iris_en>; + pinctrl-1 = <&flash_led3_iris_dis>; +}; + +&vendor { + mtp_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + #include "fg-gen3-batterydata-itech-3000mah.dtsi" + #include "fg-gen3-batterydata-ascent-3450mah.dtsi" + #include "fg-gen3-batterydata-demo-6000mah.dtsi" + }; + + extcon_usb1: extcon_usb1 { + compatible = "linux,extcon-usb-gpio"; + vbus-gpio = <&pmi8998_gpios 8 GPIO_ACTIVE_HIGH>; + + pinctrl-names = "default"; + pinctrl-0 = <&usb2_vbus_det_default>; + }; +}; + +&pmi8998_fg { + qcom,battery-data = <&mtp_batterydata>; +}; + +&smb1355_charger_0 { + status = "ok"; + qcom,disable-ctm; +}; + +&smb1355_charger_1 { + status = "ok"; + qcom,disable-ctm; +}; + +&qupv3_se9_2uart { + status = "ok"; +}; + +&qupv3_se8_spi { + status = "ok"; +}; + +&qupv3_se3_i2c { + status = "ok"; + nq@28 { + compatible = "qcom,nq-nci"; + reg = <0x28>; + qcom,nq-irq = <&tlmm 63 0x00>; + qcom,nq-ven = <&tlmm 12 0x00>; + qcom,nq-firm = <&tlmm 62 0x00>; + qcom,nq-clkreq = <&pm8998_gpios 21 0x00>; + qcom,nq-esepwr = <&tlmm 116 0x00>; + interrupt-parent = <&tlmm>; + interrupts = <63 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active", "nfc_suspend"; + pinctrl-0 = <&nfc_int_active + &nfc_enable_active + &nfc_clk_default>; + pinctrl-1 = <&nfc_int_suspend &nfc_enable_suspend>; + }; +}; + +&qupv3_se10_i2c { + status = "ok"; +}; + +&qupv3_se6_4uart { + status = "ok"; +}; + +&usb1 { + extcon = <&extcon_usb1>; +}; + +&ext_5v_boost { + status = "ok"; +}; + +&pm8998_vadc { + chan@83 { + label = "vph_pwr"; + reg = <0x83>; + qcom,decimation = <2>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@85 { + label = "vcoin"; + reg = <0x85>; + qcom,decimation = <2>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@4c { + label = "xo_therm"; + reg = <0x4c>; + qcom,decimation = <2>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <4>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@4d { + label = "msm_therm"; + reg = <0x4d>; + qcom,decimation = <2>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@4f { + label = "pa_therm1"; + reg = <0x4f>; + qcom,decimation = <2>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@51 { + label = "quiet_therm"; + reg = <0x51>; + qcom,decimation = <2>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; +}; + +&pm8998_adc_tm { + chan@83 { + label = "vph_pwr"; + reg = <0x83>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,btm-channel-number = <0x60>; + }; + + chan@4c { + label = "xo_therm"; + reg = <0x4c>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <4>; + qcom,hw-settle-time = <2>; + qcom,btm-channel-number = <0x68>; + qcom,thermal-node; + }; + + chan@4d { + label = "msm_therm"; + reg = <0x4d>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,btm-channel-number = <0x70>; + qcom,thermal-node; + }; + + chan@4f { + label = "pa_therm1"; + reg = <0x4f>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,btm-channel-number = <0x78>; + qcom,thermal-node; + }; + + chan@51 { + label = "quiet_therm"; + reg = <0x51>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,btm-channel-number = <0x80>; + qcom,thermal-node; + }; +}; + +&thermal_zones { + xo-therm-adc { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&pm8998_adc_tm 0x4c>; + wake-capable-sensor; + thermal-governor = "user_space"; + + trips { + active-config0 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + msm-therm-adc { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&pm8998_adc_tm 0x4d>; + wake-capable-sensor; + thermal-governor = "user_space"; + + trips { + active-config0 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + pa-therm1-adc { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&pm8998_adc_tm 0x4f>; + wake-capable-sensor; + thermal-governor = "user_space"; + + trips { + active-config0 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + quiet-therm-adc { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&pm8998_adc_tm 0x51>; + wake-capable-sensor; + thermal-governor = "user_space"; + + trips { + active-config0 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; +}; + +&wil6210 { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi index eebc565e5d4f..b58d637fff3d 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi @@ -18,7 +18,7 @@ #include "sda845-v2.1.dtsi" #include "sdm845-sde-display.dtsi" -#include "sdm845-mtp.dtsi" +#include "sdm845-rb3.dtsi" #include "sdm845-audio-overlay.dtsi" &labibb { From 55a5722c0e065af57fa5c3dc2f303540a7abf416 Mon Sep 17 00:00:00 2001 From: Ziyu Jian Date: Tue, 18 Jun 2019 16:26:40 +0800 Subject: [PATCH 060/281] ARM: dts: msm: add camera sensor support for sdm845 rb3 device This change will enable cam-sensor@3 & cam-sensor@4 & cam-sensor@5 for sdm845 rb3 device. Change-Id: I3d1715e7569cdd86538f8f4d60a04f78a98a7956 Signed-off-by: Ziyu Jian --- .../dts/qcom/sdm845-camera-sensor-rb3.dtsi | 162 +++++++++++++++--- arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi | 29 ---- arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi | 2 +- arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dts | 1 + arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi | 88 ++++++++++ 5 files changed, 226 insertions(+), 56 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi index 4a870e960330..f71c28331e97 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi @@ -64,20 +64,6 @@ vin-supply = <&pmi8998_bob>; }; - camera_rear_ldo: gpio-regulator@1 { - compatible = "regulator-fixed"; - reg = <0x01 0x00>; - regulator-name = "camera_rear_ldo"; - regulator-min-microvolt = <1050000>; - regulator-max-microvolt = <1050000>; - regulator-enable-ramp-delay = <135>; - enable-active-high; - gpio = <&pm8998_gpios 12 0>; - pinctrl-names = "default"; - pinctrl-0 = <&camera_rear_dvdd_en_default>; - vin-supply = <&pm8998_s3>; - }; - camera_ldo: gpio-regulator@2 { compatible = "regulator-fixed"; reg = <0x02 0x00>; @@ -172,7 +158,7 @@ compatible = "qcom,eeprom"; cam_vio-supply = <&pm8998_lvs1>; cam_vana-supply = <&pmi8998_bob>; - cam_vdig-supply = <&camera_rear_ldo>; + cam_vdig-supply = <&camera_ldo>; cam_clk-supply = <&titan_top_gdsc>; cam_vaf-supply = <&actuator_regulator>; regulator-names = "cam_vio", "cam_vana", "cam_vdig", @@ -295,6 +281,45 @@ clock-rates = <24000000>; }; + eeprom_back: qcom,eeprom@3 { + cell-index = <3>; + reg = <0x3>; + compatible = "qcom,eeprom"; + cam_vana-supply = <>; + cam_vdig-supply = <>; + cam_vio-supply = <&pm8998_lvs1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <80000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_rear4_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_rear4_suspend>; + gpios = <&tlmm 13 0>, + <&tlmm 12 0>, + <&tlmm 69 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET4", + "CAM_CUSTOM4"; + sensor-position = <0>; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + qcom,cam-sensor@0 { cell-index = <0>; compatible = "qcom,cam-sensor"; @@ -309,7 +334,7 @@ eeprom-src = <&eeprom_rear>; cam_vio-supply = <&pm8998_lvs1>; cam_vana-supply = <&pmi8998_bob>; - cam_vdig-supply = <&camera_rear_ldo>; + cam_vdig-supply = <&camera_ldo>; cam_clk-supply = <&titan_top_gdsc>; regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk"; @@ -430,7 +455,92 @@ sensor-position-roll = <270>; sensor-position-pitch = <0>; sensor-position-yaw = <0>; - led-flash-src = <&led_flash_iris>; + led-flash-src = <>; + cam_vdig-supply = <>; + cam_vana-supply = <>; + cam_vio-supply = <&pm8998_lvs1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <100000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_tracking_active>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_tracking_suspend>; + gpios = <&tlmm 16 0>, + <&tlmm 21 0>; + gpio-reset = <1>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; + gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + + qcom,cam-sensor@4 { + cell-index = <4>; + compatible = "qcom,cam-sensor"; + reg = <0x4>; + csiphy-sd-index = <2>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <180>; + actuator-src = <>; + led-flash-src = <>; + eeprom-src = <&eeprom_back>; + cam_vdig-supply = <>; + cam_vana-supply = <>; + cam_vio-supply = <&pm8998_lvs1>; + cam_clk-supply = <&titan_top_gdsc>; + regulator-names = "cam_vio", "cam_clk"; + rgltr-cntrl-support; + rgltr-min-voltage = <1800000 0>; + rgltr-max-voltage = <1800000 0>; + rgltr-load-current = <80000 0>; + gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_rear4_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_rear4_suspend>; + gpios = <&tlmm 13 0>, + <&tlmm 12 0>, + <&tlmm 69 0>; + gpio-reset = <1>; + gpio-custom1 = <2>; + gpio-req-tbl-num = <0 1 2>; + gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET4", + "CAM_CUSTOM4"; + sensor-mode = <0>; + cci-master = <1>; + status = "ok"; + clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clock-names = "cam_clk"; + clock-cntl-level = "turbo"; + clock-rates = <24000000>; + }; + + qcom,cam-sensor@5 { + cell-index = <5>; + compatible = "qcom,cam-sensor"; + reg = <0x05>; + csiphy-sd-index = <1>; + sensor-position-roll = <270>; + sensor-position-pitch = <0>; + sensor-position-yaw = <0>; + led-flash-src = <>; cam_vio-supply = <&pm8998_lvs1>; cam_vana-supply = <&camera_vana_ldo>; cam_vdig-supply = <&camera_ldo>; @@ -443,21 +553,21 @@ rgltr-load-current = <0 80000 105000 0>; gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk3_active - &cam_sensor_iris_active>; - pinctrl-1 = <&cam_sensor_mclk3_suspend - &cam_sensor_iris_suspend>; - gpios = <&tlmm 16 0>, - <&tlmm 9 0>; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_front_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 28 0>; gpio-reset = <1>; gpio-req-tbl-num = <0 1>; gpio-req-tbl-flags = <1 0>; - gpio-req-tbl-label = "CAMIF_MCLK3", - "CAM_RESET3"; + gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2"; sensor-mode = <0>; cci-master = <1>; status = "ok"; - clocks = <&clock_camcc CAM_CC_MCLK3_CLK>; + clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; clock-names = "cam_clk"; clock-cntl-level = "turbo"; clock-rates = <24000000>; diff --git a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi index 31f9b13cdeef..9e5e6c651f01 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi @@ -3407,35 +3407,6 @@ }; }; - cam_sensor_tof_active: cam_sensor_tof_active { - /* RESET*/ - mux { - pins = "gpio8"; - function = "gpio"; - }; - - config { - pins = "gpio8"; - bias-disable; /* No PULL */ - drive-strength = <2>; /* 2 MA */ - }; - }; - - cam_sensor_tof_suspend: cam_sensor_tof_suspend { - /* RESET*/ - mux { - pins = "gpio8"; - function = "gpio"; - }; - - config { - pins = "gpio8"; - bias-pull-down; /* PULL DOWN */ - drive-strength = <2>; /* 2 MA */ - output-low; - }; - }; - trigout_a: trigout_a { mux { pins = "gpio90"; diff --git a/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi index 720173203613..2955610cc5f1 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi @@ -13,7 +13,6 @@ #include #include "sdm845-pmic-overlay.dtsi" #include "sdm845-pinctrl-overlay.dtsi" -#include "sdm845-camera-sensor-rb3.dtsi" &qupv3_se10_i2c { #include "smb1355.dtsi" @@ -329,6 +328,7 @@ &nfc_enable_active &nfc_clk_default>; pinctrl-1 = <&nfc_int_suspend &nfc_enable_suspend>; + status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dts b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dts index bec2638fd713..f8d0a34ed4bc 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "sdm845-v2.1-rb3.dtsi" +#include "sdm845-camera-sensor-rb3.dtsi" / { model = "Qualcomm Technologies, Inc. sda845 v2.1 TurboX-SOM_V01"; diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi index b58d637fff3d..13910803eb00 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi @@ -105,3 +105,91 @@ status = "disabled"; }; +&tlmm { + cam_sensor_tof_active: cam_sensor_tof_active { + /* RESET*/ + mux { + pins = "gpio8"; + function = "gpio"; + }; + + config { + pins = "gpio8"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_tof_suspend: cam_sensor_tof_suspend { + /* RESET*/ + mux { + pins = "gpio8"; + function = "gpio"; + }; + + config { + pins = "gpio8"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_tracking_active: cam_sensor_tracking_active { + /* RESET */ + mux { + pins = "gpio21"; + function = "gpio"; + }; + + config { + pins = "gpio21"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_tracking_suspend: cam_sensor_tracking_suspend { + /* RESET */ + mux { + pins = "gpio21"; + function = "gpio"; + }; + + config { + pins = "gpio21"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; + + cam_sensor_rear4_active: cam_sensor_rear4_active { + /* RESET */ + mux { + pins = "gpio12","gpio69"; + function = "gpio"; + }; + + config { + pins = "gpio12","gpio69"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_rear4_suspend: cam_sensor_rear4_suspend { + /* RESET */ + mux { + pins = "gpio12","gpio69"; + function = "gpio"; + }; + + config { + pins = "gpio12","gpio69"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + output-low; + }; + }; +}; From cb214351b8387f82bf1ba836dbcc49ed45aba080 Mon Sep 17 00:00:00 2001 From: Fei Date: Wed, 3 Jul 2019 15:34:43 +0800 Subject: [PATCH 061/281] input: touchscreen: cyttsp5: more FB event notifier Support more FB event notifier callback, so wake the device in DOZE mode, too. Change-Id: Ic767a442a593932b61f5b0db4695e452a9b8d72c Signed-off-by: Fei --- drivers/input/touchscreen/cyttsp5/cyttsp5_core.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c index ef4bf38d32f2..372ea943a8dc 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c @@ -5995,7 +5995,9 @@ static int fb_notifier_callback(struct notifier_block *self, goto exit; blank = evdata->data; - if (*blank == FB_BLANK_UNBLANK) { + + switch (*blank) { + case FB_BLANK_UNBLANK: dev_dbg(cd->dev, "%s: UNBLANK!\n", __func__); if (cd->fb_state != FB_ON) { #ifdef USE_FB_SUSPEND_RESUME @@ -6005,7 +6007,12 @@ static int fb_notifier_callback(struct notifier_block *self, call_atten_cb(cd, CY_ATTEN_RESUME, 0); cd->fb_state = FB_ON; } - } else if (*blank == FB_BLANK_POWERDOWN) { + break; + + case FB_BLANK_POWERDOWN: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_NORMAL: dev_dbg(cd->dev, "%s: POWERDOWN!\n", __func__); if (cd->fb_state != FB_OFF) { #ifdef USE_FB_SUSPEND_RESUME @@ -6014,6 +6021,9 @@ static int fb_notifier_callback(struct notifier_block *self, call_atten_cb(cd, CY_ATTEN_SUSPEND, 0); cd->fb_state = FB_OFF; } + break; + default: + break; } exit: From c28f039041ce1e095519ad6187acf9d71db87ace Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Wed, 15 May 2019 11:45:50 +0800 Subject: [PATCH 062/281] sched/fair: Consider others if target cpu overutilized If target cpu overutilized, it's better to consider other group cpu. It can avoid unnecessary waiting on overutilized cpu and wait until load balance for task to be run. Change-Id: I6f8bccb611d2f11471254cf2795fb5bf3f122292 Signed-off-by: Maria Yu --- kernel/sched/fair.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 3f863a11879a..281a261a7280 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6213,6 +6213,12 @@ static inline bool task_fits_max(struct task_struct *p, int cpu) return __task_fits(p, cpu, 0); } +static inline bool cpu_check_overutil_condition(int cpu, + unsigned long util) +{ + return (capacity_orig_of(cpu) * 1024) < (util * capacity_margin); +} + bool __cpu_overutilized(int cpu, int delta) { return (capacity_orig_of(cpu) * 1024) < @@ -7062,7 +7068,7 @@ static inline int find_best_target(struct task_struct *p, int *backup_cpu, */ min_capped_util = max(new_util, capacity_min_of(i)); - if (new_util > capacity_orig) + if (cpu_check_overutil_condition(i, new_util)) continue; /* From 58f639e41aa84e6201a2c23477c7dd4be18777a4 Mon Sep 17 00:00:00 2001 From: Veerabhadrarao Badiganti Date: Mon, 1 Jul 2019 19:35:01 +0530 Subject: [PATCH 063/281] mmc: sdhci-msm: Don't update CDR settings with HSR values Don't update CDR settings with HSR values. HSR values are causing issues in HS400 non strobe mode. Change-Id: I408c3ebfff03f51a89792f8aa8c7dcf9182bdc83 Signed-off-by: Veerabhadrarao Badiganti --- drivers/mmc/host/sdhci-msm.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 9ed60c892930..959f8eece329 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -540,13 +540,11 @@ static int msm_config_cm_dll_phase(struct sdhci_host *host, u8 phase) * Write the selected DLL clock output phase (0 ... 15) * to CDR_SELEXT bit field of DLL_CONFIG register. */ - if (msm_host->dll_hsr->dll_config & (0xF << 20)) { - writel_relaxed(((readl_relaxed(host->ioaddr + - msm_host_offset->CORE_DLL_CONFIG) - & ~(0xF << 20)) - | (grey_coded_phase_table[phase] << 20)), - host->ioaddr + msm_host_offset->CORE_DLL_CONFIG); - } + writel_relaxed(((readl_relaxed(host->ioaddr + + msm_host_offset->CORE_DLL_CONFIG) + & ~(0xF << 20)) + | (grey_coded_phase_table[phase] << 20)), + host->ioaddr + msm_host_offset->CORE_DLL_CONFIG); /* Set CK_OUT_EN bit of DLL_CONFIG register to 1. */ writel_relaxed((readl_relaxed(host->ioaddr + @@ -1162,13 +1160,11 @@ static int sdhci_msm_hs400_dll_calibration(struct sdhci_host *host) ret = msm_config_cm_dll_phase(host, msm_host->saved_tuning_phase); if (ret) goto out; - if (msm_host->dll_hsr->dll_config & CORE_CMD_DAT_TRACK_SEL) { - /* Write 1 to CMD_DAT_TRACK_SEL field in DLL_CONFIG */ - writel_relaxed((readl_relaxed(host->ioaddr + - msm_host_offset->CORE_DLL_CONFIG) - | CORE_CMD_DAT_TRACK_SEL), host->ioaddr + - msm_host_offset->CORE_DLL_CONFIG); - } + /* Write 1 to CMD_DAT_TRACK_SEL field in DLL_CONFIG */ + writel_relaxed((readl_relaxed(host->ioaddr + + msm_host_offset->CORE_DLL_CONFIG) + | CORE_CMD_DAT_TRACK_SEL), host->ioaddr + + msm_host_offset->CORE_DLL_CONFIG); if (msm_host->use_cdclp533) /* Calibrate CDCLP533 DLL HW */ From 96a84c5c7d615d1c2c92155f0c87354ecca3946a Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Wed, 3 Jul 2019 20:53:10 +0530 Subject: [PATCH 064/281] diag: Switch to correct logging mode after mdlog exit Mdlog in multimode when exits is not switching to required USB or PCIE mode. Adding missing check handles switching to proper logging mode when mdlog exits. Change-Id: I7c7bc23c463cc809765b4774fa5147c7245d8c50 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diagchar_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index e2382a306dc2..ec63680524d4 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1591,7 +1591,8 @@ static int diag_md_session_check(int curr_mode, int req_mode, *change_mode = 1; return 0; } else if ((req_mode == DIAG_USB_MODE || req_mode == DIAG_PCIE_MODE) - && curr_mode == DIAG_MEMORY_DEVICE_MODE) { + && (curr_mode == DIAG_MEMORY_DEVICE_MODE || + curr_mode == DIAG_MULTI_MODE)) { mutex_lock(&driver->md_session_lock); if (driver->md_session_mode == DIAG_MD_NONE && driver->md_session_mask == 0 && driver->logging_mask) { From 9d3b23c4600a2b0fa648e1c494a839293f968f73 Mon Sep 17 00:00:00 2001 From: "Joel Fernandes (Google)" Date: Fri, 26 Apr 2019 15:04:29 -0400 Subject: [PATCH 065/281] BACKPORT: Provide in-kernel headers to make extending kernel easier Introduce in-kernel headers which are made available as an archive through proc (/proc/kheaders.tar.xz file). This archive makes it possible to run eBPF and other tracing programs that need to extend the kernel for tracing purposes without any dependency on the file system having headers. A github PR is sent for the corresponding BCC patch at: https://github.com/iovisor/bcc/pull/2312 On Android and embedded systems, it is common to switch kernels but not have kernel headers available on the file system. Further once a different kernel is booted, any headers stored on the file system will no longer be useful. This is an issue even well known to distros. By storing the headers as a compressed archive within the kernel, we can avoid these issues that have been a hindrance for a long time. The best way to use this feature is by building it in. Several users have a need for this, when they switch debug kernels, they do not want to update the filesystem or worry about it where to store the headers on it. However, the feature is also buildable as a module in case the user desires it not being part of the kernel image. This makes it possible to load and unload the headers from memory on demand. A tracing program can load the module, do its operations, and then unload the module to save kernel memory. The total memory needed is 3.3MB. By having the archive available at a fixed location independent of filesystem dependencies and conventions, all debugging tools can directly refer to the fixed location for the archive, without concerning with where the headers on a typical filesystem which significantly simplifies tooling that needs kernel headers. The code to read the headers is based on /proc/config.gz code and uses the same technique to embed the headers. Other approaches were discussed such as having an in-memory mountable filesystem, but that has drawbacks such as requiring an in-kernel xz decompressor which we don't have today, and requiring usage of 42 MB of kernel memory to host the decompressed headers at anytime. Also this approach is simpler than such approaches. (Resolved minor conflicts in Makefile) (cherry picked from commit 43d8ce9d65a54846d378545770991e65838981e0) Bug: 78013494 Change-Id: Id40724018c0c68d5ea159822c269e23897d43826 Reviewed-by: Masahiro Yamada Signed-off-by: Joel Fernandes (Google) Signed-off-by: Greg Kroah-Hartman --- init/Kconfig | 10 +++++ kernel/.gitignore | 1 + kernel/Makefile | 10 +++++ kernel/gen_ikh_data.sh | 89 ++++++++++++++++++++++++++++++++++++++++++ kernel/kheaders.c | 74 +++++++++++++++++++++++++++++++++++ 5 files changed, 184 insertions(+) create mode 100755 kernel/gen_ikh_data.sh create mode 100644 kernel/kheaders.c diff --git a/init/Kconfig b/init/Kconfig index d505d9067c89..15279b7e3909 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -868,6 +868,16 @@ config IKCONFIG_PROC This option enables access to the kernel configuration file through /proc/config.gz. +config IKHEADERS_PROC + tristate "Enable kernel header artifacts through /proc/kheaders.tar.xz" + depends on PROC_FS + help + This option enables access to the kernel header and other artifacts that + are generated during the build process. These can be used to build eBPF + tracing programs, or similar programs. If you build the headers as a + module, a module called kheaders.ko is built which can be loaded on-demand + to get access to the headers. + config LOG_BUF_SHIFT int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" range 12 25 diff --git a/kernel/.gitignore b/kernel/.gitignore index b3097bde4e9c..084572ac1290 100644 --- a/kernel/.gitignore +++ b/kernel/.gitignore @@ -3,5 +3,6 @@ # config_data.h config_data.gz +kheaders.md5 timeconst.h hz.bc diff --git a/kernel/Makefile b/kernel/Makefile index ca3c5d3a5d5d..26250c0510e9 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_UTS_NS) += utsname.o obj-$(CONFIG_USER_NS) += user_namespace.o obj-$(CONFIG_PID_NS) += pid_namespace.o obj-$(CONFIG_IKCONFIG) += configs.o +obj-$(CONFIG_IKHEADERS_PROC) += kheaders.o obj-$(CONFIG_SMP) += stop_machine.o obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o obj-$(CONFIG_AUDIT) += audit.o auditfilter.o @@ -131,3 +132,12 @@ $(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE targets += config_data.h $(obj)/config_data.h: $(obj)/config_data.gz FORCE $(call filechk,ikconfiggz) + +$(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz + +quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz +cmd_genikh = $(srctree)/kernel/gen_ikh_data.sh $@ +$(obj)/kheaders_data.tar.xz: FORCE + $(call cmd,genikh) + +clean-files := kheaders_data.tar.xz kheaders.md5 diff --git a/kernel/gen_ikh_data.sh b/kernel/gen_ikh_data.sh new file mode 100755 index 000000000000..591a94f7b387 --- /dev/null +++ b/kernel/gen_ikh_data.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# This script generates an archive consisting of kernel headers +# for CONFIG_IKHEADERS_PROC. +set -e +spath="$(dirname "$(readlink -f "$0")")" +kroot="$spath/.." +outdir="$(pwd)" +tarfile=$1 +cpio_dir=$outdir/$tarfile.tmp + +# Script filename relative to the kernel source root +# We add it to the archive because it is small and any changes +# to this script will also cause a rebuild of the archive. +sfile="$(realpath --relative-to $kroot "$(readlink -f "$0")")" + +src_file_list=" +include/ +arch/$SRCARCH/include/ +$sfile +" + +obj_file_list=" +include/ +arch/$SRCARCH/include/ +" + +# Support incremental builds by skipping archive generation +# if timestamps of files being archived are not changed. + +# This block is useful for debugging the incremental builds. +# Uncomment it for debugging. +# iter=1 +# if [ ! -f /tmp/iter ]; then echo 1 > /tmp/iter; +# else; iter=$(($(cat /tmp/iter) + 1)); fi +# find $src_file_list -type f | xargs ls -lR > /tmp/src-ls-$iter +# find $obj_file_list -type f | xargs ls -lR > /tmp/obj-ls-$iter + +# include/generated/compile.h is ignored because it is touched even when none +# of the source files changed. This causes pointless regeneration, so let us +# ignore them for md5 calculation. +pushd $kroot > /dev/null +src_files_md5="$(find $src_file_list -type f | + grep -v "include/generated/compile.h" | + xargs ls -lR | md5sum | cut -d ' ' -f1)" +popd > /dev/null +obj_files_md5="$(find $obj_file_list -type f | + grep -v "include/generated/compile.h" | + xargs ls -lR | md5sum | cut -d ' ' -f1)" + +if [ -f $tarfile ]; then tarfile_md5="$(md5sum $tarfile | cut -d ' ' -f1)"; fi +if [ -f kernel/kheaders.md5 ] && + [ "$(cat kernel/kheaders.md5|head -1)" == "$src_files_md5" ] && + [ "$(cat kernel/kheaders.md5|head -2|tail -1)" == "$obj_files_md5" ] && + [ "$(cat kernel/kheaders.md5|tail -1)" == "$tarfile_md5" ]; then + exit +fi + +if [ "${quiet}" != "silent_" ]; then + echo " GEN $tarfile" +fi + +rm -rf $cpio_dir +mkdir $cpio_dir + +pushd $kroot > /dev/null +for f in $src_file_list; + do find "$f" ! -name "*.cmd" ! -name ".*"; +done | cpio --quiet -pd $cpio_dir +popd > /dev/null + +# The second CPIO can complain if files already exist which can +# happen with out of tree builds. Just silence CPIO for now. +for f in $obj_file_list; + do find "$f" ! -name "*.cmd" ! -name ".*"; +done | cpio --quiet -pd $cpio_dir >/dev/null 2>&1 + +# Remove comments except SDPX lines +find $cpio_dir -type f -print0 | + xargs -0 -P8 -n1 perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;' + +tar -Jcf $tarfile -C $cpio_dir/ . > /dev/null + +echo "$src_files_md5" > kernel/kheaders.md5 +echo "$obj_files_md5" >> kernel/kheaders.md5 +echo "$(md5sum $tarfile | cut -d ' ' -f1)" >> kernel/kheaders.md5 + +rm -rf $cpio_dir diff --git a/kernel/kheaders.c b/kernel/kheaders.c new file mode 100644 index 000000000000..70ae6052920d --- /dev/null +++ b/kernel/kheaders.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Provide kernel headers useful to build tracing programs + * such as for running eBPF tracing tools. + * + * (Borrowed code from kernel/configs.c) + */ + +#include +#include +#include +#include +#include + +/* + * Define kernel_headers_data and kernel_headers_data_end, within which the + * compressed kernel headers are stored. The file is first compressed with xz. + */ + +asm ( +" .pushsection .rodata, \"a\" \n" +" .global kernel_headers_data \n" +"kernel_headers_data: \n" +" .incbin \"kernel/kheaders_data.tar.xz\" \n" +" .global kernel_headers_data_end \n" +"kernel_headers_data_end: \n" +" .popsection \n" +); + +extern char kernel_headers_data; +extern char kernel_headers_data_end; + +static ssize_t +ikheaders_read_current(struct file *file, char __user *buf, + size_t len, loff_t *offset) +{ + return simple_read_from_buffer(buf, len, offset, + &kernel_headers_data, + &kernel_headers_data_end - + &kernel_headers_data); +} + +static const struct file_operations ikheaders_file_ops = { + .read = ikheaders_read_current, + .llseek = default_llseek, +}; + +static int __init ikheaders_init(void) +{ + struct proc_dir_entry *entry; + + /* create the current headers file */ + entry = proc_create("kheaders.tar.xz", S_IRUGO, NULL, + &ikheaders_file_ops); + if (!entry) + return -ENOMEM; + + proc_set_size(entry, + &kernel_headers_data_end - + &kernel_headers_data); + return 0; +} + +static void __exit ikheaders_cleanup(void) +{ + remove_proc_entry("kheaders.tar.xz", NULL); +} + +module_init(ikheaders_init); +module_exit(ikheaders_cleanup); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Joel Fernandes"); +MODULE_DESCRIPTION("Echo the kernel header artifacts used to build the kernel"); From 59d642e923ab49abc8843aa7bf0277e0cd429f30 Mon Sep 17 00:00:00 2001 From: "Joel Fernandes (Google)" Date: Wed, 15 May 2019 17:35:51 -0400 Subject: [PATCH 066/281] BACKPORT: kheaders: Move from proc to sysfs The kheaders archive consisting of the kernel headers used for compiling bpf programs is in /proc. However there is concern that moving it here will make it permanent. Let us move it to /sys/kernel as discussed [1]. [1] https://lore.kernel.org/patchwork/patch/1067310/#1265969 (cherry picked from commit f7b101d33046a837c2aa4526cef28a3c785d7af2) Bug: 78013494 Suggested-by: Steven Rostedt Signed-off-by: Joel Fernandes (Google) Signed-off-by: Greg Kroah-Hartman Change-Id: I3bf86d0b0f2b73094c2ed29bfda1a57436f9d956 --- init/Kconfig | 15 ++++---- kernel/Makefile | 4 +-- kernel/{gen_ikh_data.sh => gen_kheaders.sh} | 2 +- kernel/kheaders.c | 40 +++++++++------------ 4 files changed, 26 insertions(+), 35 deletions(-) rename kernel/{gen_ikh_data.sh => gen_kheaders.sh} (98%) diff --git a/init/Kconfig b/init/Kconfig index 15279b7e3909..28261a37ec6f 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -868,15 +868,14 @@ config IKCONFIG_PROC This option enables access to the kernel configuration file through /proc/config.gz. -config IKHEADERS_PROC - tristate "Enable kernel header artifacts through /proc/kheaders.tar.xz" - depends on PROC_FS +config IKHEADERS + tristate "Enable kernel headers through /sys/kernel/kheaders.tar.xz" + depends on SYSFS help - This option enables access to the kernel header and other artifacts that - are generated during the build process. These can be used to build eBPF - tracing programs, or similar programs. If you build the headers as a - module, a module called kheaders.ko is built which can be loaded on-demand - to get access to the headers. + This option enables access to the in-kernel headers that are generated during + the build process. These can be used to build eBPF tracing programs, + or similar programs. If you build the headers as a module, a module called + kheaders.ko is built which can be loaded on-demand to get access to headers. config LOG_BUF_SHIFT int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" diff --git a/kernel/Makefile b/kernel/Makefile index 26250c0510e9..29071ac3c66b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -76,7 +76,7 @@ obj-$(CONFIG_UTS_NS) += utsname.o obj-$(CONFIG_USER_NS) += user_namespace.o obj-$(CONFIG_PID_NS) += pid_namespace.o obj-$(CONFIG_IKCONFIG) += configs.o -obj-$(CONFIG_IKHEADERS_PROC) += kheaders.o +obj-$(CONFIG_IKHEADERS) += kheaders.o obj-$(CONFIG_SMP) += stop_machine.o obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o obj-$(CONFIG_AUDIT) += audit.o auditfilter.o @@ -136,7 +136,7 @@ $(obj)/config_data.h: $(obj)/config_data.gz FORCE $(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz -cmd_genikh = $(srctree)/kernel/gen_ikh_data.sh $@ +cmd_genikh = $(CONFIG_SHELL) $(srctree)/kernel/gen_kheaders.sh $@ $(obj)/kheaders_data.tar.xz: FORCE $(call cmd,genikh) diff --git a/kernel/gen_ikh_data.sh b/kernel/gen_kheaders.sh similarity index 98% rename from kernel/gen_ikh_data.sh rename to kernel/gen_kheaders.sh index 591a94f7b387..581b83534587 100755 --- a/kernel/gen_ikh_data.sh +++ b/kernel/gen_kheaders.sh @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-2.0 # This script generates an archive consisting of kernel headers -# for CONFIG_IKHEADERS_PROC. +# for CONFIG_IKHEADERS. set -e spath="$(dirname "$(readlink -f "$0")")" kroot="$spath/.." diff --git a/kernel/kheaders.c b/kernel/kheaders.c index 70ae6052920d..8f69772af77b 100644 --- a/kernel/kheaders.c +++ b/kernel/kheaders.c @@ -8,9 +8,8 @@ #include #include -#include +#include #include -#include /* * Define kernel_headers_data and kernel_headers_data_end, within which the @@ -31,39 +30,32 @@ extern char kernel_headers_data; extern char kernel_headers_data_end; static ssize_t -ikheaders_read_current(struct file *file, char __user *buf, - size_t len, loff_t *offset) +ikheaders_read(struct file *file, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t len) { - return simple_read_from_buffer(buf, len, offset, - &kernel_headers_data, - &kernel_headers_data_end - - &kernel_headers_data); + memcpy(buf, &kernel_headers_data + off, len); + return len; } -static const struct file_operations ikheaders_file_ops = { - .read = ikheaders_read_current, - .llseek = default_llseek, +static struct bin_attribute kheaders_attr __ro_after_init = { + .attr = { + .name = "kheaders.tar.xz", + .mode = 0444, + }, + .read = &ikheaders_read, }; static int __init ikheaders_init(void) { - struct proc_dir_entry *entry; - - /* create the current headers file */ - entry = proc_create("kheaders.tar.xz", S_IRUGO, NULL, - &ikheaders_file_ops); - if (!entry) - return -ENOMEM; - - proc_set_size(entry, - &kernel_headers_data_end - - &kernel_headers_data); - return 0; + kheaders_attr.size = (&kernel_headers_data_end - + &kernel_headers_data); + return sysfs_create_bin_file(kernel_kobj, &kheaders_attr); } static void __exit ikheaders_cleanup(void) { - remove_proc_entry("kheaders.tar.xz", NULL); + sysfs_remove_bin_file(kernel_kobj, &kheaders_attr); } module_init(ikheaders_init); From 414b55194dcdd8b656fbcc4c94e822f57230412f Mon Sep 17 00:00:00 2001 From: "Joel Fernandes (Google)" Date: Wed, 15 May 2019 17:35:52 -0400 Subject: [PATCH 067/281] BACKPORT: kheaders: Do not regenerate archive if config is not changed Linus reported an issue that doing an allmodconfig was causing the kheaders archive to be regenerated even though the config is the same. This patch fixes the issue by ignoring the config-related header files for "knowing when to regenerate based on timestamps". Instead, if the CONFIG_X_Y option really changes, then we there are the include/config/X/Y.h which will already tells us "if a config really changed". So we don't really need these files for regeneration detection anyway, and ignoring them fixes Linus's issue. (cherry picked from commit 1457dc9ed8da871fbbc0a2ebdaed0405eeeed0cf) Bug: 78013494 Reported-by: Linus Torvalds Signed-off-by: Joel Fernandes (Google) Signed-off-by: Greg Kroah-Hartman Change-Id: Ieab28efee4218660acaa79f914c0e33dbfd7bb15 --- kernel/gen_kheaders.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh index 581b83534587..9a34e1d9bd7f 100755 --- a/kernel/gen_kheaders.sh +++ b/kernel/gen_kheaders.sh @@ -31,9 +31,8 @@ arch/$SRCARCH/include/ # This block is useful for debugging the incremental builds. # Uncomment it for debugging. -# iter=1 -# if [ ! -f /tmp/iter ]; then echo 1 > /tmp/iter; -# else; iter=$(($(cat /tmp/iter) + 1)); fi +# if [ ! -f /tmp/iter ]; then iter=1; echo 1 > /tmp/iter; +# else iter=$(($(cat /tmp/iter) + 1)); echo $iter > /tmp/iter; fi # find $src_file_list -type f | xargs ls -lR > /tmp/src-ls-$iter # find $obj_file_list -type f | xargs ls -lR > /tmp/obj-ls-$iter @@ -43,10 +42,18 @@ arch/$SRCARCH/include/ pushd $kroot > /dev/null src_files_md5="$(find $src_file_list -type f | grep -v "include/generated/compile.h" | + grep -v "include/generated/autoconf.h" | + grep -v "include/config/auto.conf" | + grep -v "include/config/auto.conf.cmd" | + grep -v "include/config/tristate.conf" | xargs ls -lR | md5sum | cut -d ' ' -f1)" popd > /dev/null obj_files_md5="$(find $obj_file_list -type f | grep -v "include/generated/compile.h" | + grep -v "include/generated/autoconf.h" | + grep -v "include/config/auto.conf" | + grep -v "include/config/auto.conf.cmd" | + grep -v "include/config/tristate.conf" | xargs ls -lR | md5sum | cut -d ' ' -f1)" if [ -f $tarfile ]; then tarfile_md5="$(md5sum $tarfile | cut -d ' ' -f1)"; fi @@ -82,7 +89,7 @@ find $cpio_dir -type f -print0 | tar -Jcf $tarfile -C $cpio_dir/ . > /dev/null -echo "$src_files_md5" > kernel/kheaders.md5 +echo "$src_files_md5" > kernel/kheaders.md5 echo "$obj_files_md5" >> kernel/kheaders.md5 echo "$(md5sum $tarfile | cut -d ' ' -f1)" >> kernel/kheaders.md5 From e03b321549ee2a63c4dbf10f34816ef82d61bc9f Mon Sep 17 00:00:00 2001 From: taojiang Date: Thu, 4 Jul 2019 10:29:12 +0800 Subject: [PATCH 068/281] ARM: dts: msm: update eeprom for s5k3p9sx04 update gpio and ldo for spyro device,enable eeprom for camera0 Change-Id: Ic9674470dbd3c95d24e5ac0f2e73fe97ff219c38 Signed-off-by: taojiang --- .../dts/qcom/sdm429w-camera-sensor-spyro.dtsi | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi index 1106d331eb76..45756f77791a 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi @@ -79,21 +79,26 @@ qcom,cam-vreg-op-mode = <80000 0 200000 100000>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk0_default - &cam_sensor_rear_reset - &cam_sensor_rear_vana>; + &cam_sensor_rear_reset + &cam_sensor_rear_vana + &cam_sensor_rear_standby>; pinctrl-1 = <&cam_sensor_mclk0_sleep - &cam_sensor_rear_reset_sleep - &cam_sensor_rear_vana_sleep>; + &cam_sensor_rear_reset_sleep + &cam_sensor_rear_vana_sleep + &cam_sensor_rear_standby_sleep>; gpios = <&tlmm 26 0>, <&tlmm 36 0>, - <&tlmm 35 0>; + <&tlmm 58 0>, + <&tlmm 92 0>; qcom,gpio-reset = <1>; qcom,gpio-vana = <2>; - qcom,gpio-req-tbl-num = <0 1 2>; - qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-standby = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK0", "CAM_RESET0", - "CAM_VANA"; + "CAM_VANA", + "CAM_STANDBY"; status = "ok"; clocks = <&clock_gcc clk_mclk0_clk_src>, <&clock_gcc clk_gcc_camss_mclk0_clk>; @@ -190,7 +195,7 @@ qcom,csid-sd-index = <0>; qcom,mount-angle = <90>; //qcom,led-flash-src = <&led_flash0>; - //qcom,eeprom-src = <&eeprom_spyro0>; + qcom,eeprom-src = <&eeprom_spyro0>; qcom,actuator-src = <&actuator_spyro0>; cam_vio-supply = <&pm660_l14>; cam_vaf-supply = <&L19A>; From 95ab71823671f355362a84a4efd57e94c30a89c6 Mon Sep 17 00:00:00 2001 From: Rahul Shahare Date: Wed, 26 Jun 2019 15:45:29 +0530 Subject: [PATCH 069/281] AndroidKernel: Building dtb.img to support header version 2 The dtb.img is made by concatenating all the compiled dtbs after the kernel is compiled. This dtb.img is then added to be a part of the boot.img. Change-Id: I6d8247cf5de99886f4514b5ce52711462aaf7e1c Signed-off-by: Rahul Shahare --- AndroidKernel.mk | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/AndroidKernel.mk b/AndroidKernel.mk index ceb7bcb35511..790e713c42f5 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -118,8 +118,15 @@ endif ifeq ($(TARGET_KERNEL_APPEND_DTB), true) $(info Using appended DTB) TARGET_PREBUILT_INT_KERNEL_ := $(TARGET_PREBUILT_INT_KERNEL_)-dtb +else +$(info Using DTB Image) +INSTALLED_DTBIMAGE_TARGET := $(PRODUCT_OUT)/dtb.img endif +# Creating a dtb.img once the kernel is compiled if TARGET_KERNEL_APPEND_DTB is set to be false +$(INSTALLED_DTBIMAGE_TARGET): $(INSTALLED_KERNEL_TARGET) + cat $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts/qcom/*.dtb > $@ + KERNEL_HEADERS_INSTALL := $(KERNEL_OUT)/usr KERNEL_MODULES_INSTALL ?= system KERNEL_MODULES_OUT ?= $(PRODUCT_OUT)/$(KERNEL_MODULES_INSTALL)/lib/modules From 9be09edc646cd835c9426b5091e417d041d369ff Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Tue, 5 Dec 2017 09:48:14 +0530 Subject: [PATCH 070/281] drivers: mailbox: Use high priority tasklet The normal tasklets are deferred to ksoftirqd task context when a RT task is active on the CPU where tasklet is raised. Use high priority tasklet to avoid the delays. Change-Id: I955f524a4a01b968adc131efe301d1d66d802e8c Signed-off-by: Pavankumar Kondeti --- drivers/mailbox/qcom-rpmh-mailbox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mailbox/qcom-rpmh-mailbox.c b/drivers/mailbox/qcom-rpmh-mailbox.c index 16afda7e3e08..ad0842daf1ce 100644 --- a/drivers/mailbox/qcom-rpmh-mailbox.c +++ b/drivers/mailbox/qcom-rpmh-mailbox.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -404,7 +404,7 @@ static inline void send_tcs_response(struct tcs_response *resp) list_add_tail(&resp->list, &drv->response_pending); spin_unlock_irqrestore(&drv->drv_lock, flags); - tasklet_schedule(&drv->tasklet); + tasklet_hi_schedule(&drv->tasklet); } static inline void enable_tcs_irq(struct rsc_drv *drv, int m, bool enable) From c97c71eb2f1d52302a86b03ad403a920da84303b Mon Sep 17 00:00:00 2001 From: Ramesh V Date: Wed, 17 Apr 2019 10:50:13 +0530 Subject: [PATCH 071/281] msm: camera_v2: isp: handle frame drop in error case when isp tasklet get delayed due to scheduling, recover pingpong mismatch from both isp and send back buffer to framework to avoid framedrop. Change-Id: If7357d7b2669f99eb45c364288f09954b9f0a710 Signed-off-by: Ramesh V Signed-off-by: Sumalatha Malothu --- .../msm/camera_v2/isp/msm_isp_axi_util.c | 63 +++++++++++++++---- 1 file changed, 52 insertions(+), 11 deletions(-) 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 fbf16d1963f4..d60982e53867 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 @@ -2097,6 +2097,8 @@ static int msm_isp_cfg_ping_pong_address( if (!buf) { msm_isp_cfg_stream_scratch(stream_info, pingpong_status); + if (stream_info->controllable_output) + return 1; return 0; } @@ -2775,7 +2777,11 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev, struct msm_isp_timestamp timestamp; struct msm_vfe_frame_request_queue *queue_req; unsigned long flags; + uint32_t pingpong_status; int vfe_idx; + uint32_t pingpong_bit = 0; + uint32_t frame_id = 0; + struct timeval *time_stamp; if (!reset_cmd) { pr_err("%s: NULL pointer reset cmd %pK\n", __func__, reset_cmd); @@ -2784,6 +2790,7 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev, } msm_isp_get_timestamp(×tamp, vfe_dev); + time_stamp = ×tamp.buf_time; for (i = 0; i < VFE_AXI_SRC_MAX; i++) { stream_info = msm_isp_get_stream_common_data( @@ -2806,6 +2813,28 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev, /* set ping pong to scratch before flush */ spin_lock_irqsave(&stream_info->lock, flags); + frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; + if (stream_info->controllable_output && + stream_info->undelivered_request_cnt > 0) { + pingpong_status = VFE_PING_FLAG; + pingpong_bit = (~(pingpong_status >> + stream_info->wm[0][0]) & 0x1); + if (stream_info->buf[pingpong_bit] != NULL) { + msm_isp_process_done_buf(vfe_dev, stream_info, + stream_info->buf[pingpong_bit], + time_stamp, + frame_id); + } + pingpong_status = VFE_PONG_FLAG; + pingpong_bit = (~(pingpong_status >> + stream_info->wm[0][0]) & 0x1); + if (stream_info->buf[pingpong_bit] != NULL) { + msm_isp_process_done_buf(vfe_dev, stream_info, + stream_info->buf[pingpong_bit], + time_stamp, + frame_id); + } + } msm_isp_cfg_stream_scratch(stream_info, VFE_PING_FLAG); msm_isp_cfg_stream_scratch(stream_info, @@ -3313,9 +3342,8 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev_ioctl, msm_isp_reset_framedrop(vfe_dev_ioctl, stream_info); rc = msm_isp_init_stream_ping_pong_reg(stream_info); if (rc < 0) { - pr_err("%s: No buffer for stream%d\n", __func__, - HANDLE_TO_IDX( - stream_cfg_cmd->stream_handle[i])); + pr_err("%s: No buffer for stream%x\n", __func__, + stream_info->stream_id); spin_unlock_irqrestore(&stream_info->lock, flags); mutex_unlock(&vfe_dev_ioctl->buf_mgr->lock); goto error; @@ -3764,11 +3792,16 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, if (rc) { spin_unlock_irqrestore(&stream_info->lock, flags); stream_info->undelivered_request_cnt--; - pr_err_ratelimited("%s:%d fail to cfg HAL buffer\n", - __func__, __LINE__); - queue_req->cmd_used = 0; - list_del(&queue_req->list); - stream_info->request_q_cnt--; + queue_req = list_first_entry_or_null( + &stream_info->request_q, + struct msm_vfe_frame_request_queue, list); + if (queue_req) { + queue_req->cmd_used = 0; + list_del(&queue_req->list); + stream_info->request_q_cnt--; + } + pr_err_ratelimited("%s:%d fail to cfg HAL buffer stream %x\n", + __func__, __LINE__, stream_info->stream_id); return rc; } @@ -3803,11 +3836,16 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, stream_info->undelivered_request_cnt--; spin_unlock_irqrestore(&stream_info->lock, flags); + queue_req = list_first_entry_or_null( + &stream_info->request_q, + struct msm_vfe_frame_request_queue, list); + if (queue_req) { + queue_req->cmd_used = 0; + list_del(&queue_req->list); + stream_info->request_q_cnt--; + } pr_err_ratelimited("%s:%d fail to cfg HAL buffer\n", __func__, __LINE__); - queue_req->cmd_used = 0; - list_del(&queue_req->list); - stream_info->request_q_cnt--; return rc; } } else { @@ -4410,7 +4448,10 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev, frame_id_diff = vfe_dev->irq_sof_id - frame_id; if (stream_info->controllable_output && frame_id_diff > 1) { + pr_err_ratelimited("%s: scheduling problem do recovery irq_sof_id %d frame_id %d\n", + __func__, vfe_dev->irq_sof_id, frame_id); /* scheduling problem need to do recovery */ + stream_info->buf[pingpong_bit] = done_buf; spin_unlock_irqrestore(&stream_info->lock, flags); msm_isp_halt_send_error(vfe_dev, ISP_EVENT_PING_PONG_MISMATCH); From 477ca2439ba8178ac472b7a7b35732a3cbd2356e Mon Sep 17 00:00:00 2001 From: Raja Mallik Date: Fri, 21 Jun 2019 14:23:32 +0530 Subject: [PATCH 072/281] Merge remote-tracking branch 'dev/msm-4.14' into msm-4.9 06/12 * commit '6e4bb1a37af305e7d4d1aa4eb124140133cf6fc0': msm: camera: sensor: Increase the eeprom map buffer count msm: camera: reqmgr: Reset previous skipped slot if valid request msm: camera: crm: Increasing the device handles to 128 msm: camera: Adding device type to track device handles msm: camera: isp: Add support for initial frame drop msm: camera: cpas: Check the HW state before accessing register msm: camera: cci: Add rd_done to handle read done operation msm: camera: crm: Increase the device handles to 128 msm: camera: fd: Remove duplicate "qcom,fd501" property msm: camera: reqmgr: Fix CRM shift one req issue msm: camera: icp: Mapping fw error numbers with error names msm: camera: csiphy: correct DPHY bring up sequence (Merged) msm: camera: Fix cpas axi clk rate overflow (Merged) msm: camera: reqmgr: Skip reset if no request from UMD msm: camera: sync: Dump fence info in case of fence exhaust msm: camera: Add uapi changes for axi bw voting v2 msm: camera: isp: Handle Dual VFE incase of event mismatch msm: camera: icp: Get GDSC control prior to IPE/BPS reset Change-Id: I813060ef4d332f8d782b60b1beac81a638855da3 Signed-off-by: Raja Mallik --- .../camera_v3/cam_core/cam_context_utils.c | 2 +- .../msm/camera_v3/cam_cpas/cam_cpas_hw.c | 6 +- .../cam_cpas/cpas_top/cam_cpastop_hw.c | 7 + .../cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c | 4 - .../camera_v3/cam_icp/fw_inc/hfi_sys_defs.h | 23 +- .../icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c | 174 +++++++++-- .../msm/camera_v3/cam_isp/cam_isp_context.c | 2 +- .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 98 +++++- .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h | 69 +++-- .../isp_hw/ife_csid_hw/cam_ife_csid_core.c | 281 +++++++++++++++-- .../isp_hw/ife_csid_hw/cam_ife_csid_core.h | 15 + .../isp_hw/include/cam_ife_csid_hw_intf.h | 3 +- .../isp_hw_mgr/isp_hw/include/cam_isp_hw.h | 1 + .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c | 1 + .../vfe_hw/vfe_top/cam_vfe_camif_ver2.c | 37 +++ .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c | 17 ++ .../camera_v3/cam_req_mgr/cam_req_mgr_core.c | 283 ++++++++++++++---- .../camera_v3/cam_req_mgr/cam_req_mgr_core.h | 9 +- .../camera_v3/cam_req_mgr/cam_req_mgr_dev.c | 37 ++- .../camera_v3/cam_req_mgr/cam_req_mgr_util.c | 20 +- .../camera_v3/cam_req_mgr/cam_req_mgr_util.h | 4 +- .../cam_actuator/cam_actuator_core.c | 2 +- .../cam_sensor_module/cam_cci/cam_cci_core.c | 14 +- .../cam_sensor_module/cam_cci/cam_cci_dev.c | 56 +++- .../cam_sensor_module/cam_cci/cam_cci_dev.h | 72 ++--- .../cam_sensor_module/cam_cci/cam_cci_hwreg.h | 8 +- .../cam_sensor_module/cam_cci/cam_cci_soc.c | 12 +- .../cam_csiphy/cam_csiphy_core.c | 2 +- .../cam_csiphy/include/cam_csiphy_1_2_hwreg.h | 16 +- .../cam_eeprom/cam_eeprom_core.c | 2 +- .../cam_eeprom/cam_eeprom_dev.h | 2 +- .../cam_flash/cam_flash_dev.c | 2 +- .../cam_sensor_module/cam_ois/cam_ois_core.c | 2 +- .../cam_sensor/cam_sensor_core.c | 2 +- .../msm/camera_v3/cam_sync/cam_sync.c | 26 +- .../msm/camera_v3/cam_sync/cam_sync_private.h | 4 +- .../msm/camera_v3/cam_utils/cam_soc_util.c | 12 +- .../msm/camera_v3/cam_utils/cam_soc_util.h | 2 +- include/uapi/media/cam_cpas.h | 59 ++++ include/uapi/media/cam_icp.h | 21 ++ include/uapi/media/cam_isp.h | 34 ++- include/uapi/media/cam_req_mgr.h | 16 + 42 files changed, 1227 insertions(+), 232 deletions(-) diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c index 330491256754..7600cbb77cee 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c @@ -574,7 +574,7 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx, req_hdl_param.media_entity_flag = 0; req_hdl_param.priv = ctx; req_hdl_param.ops = ctx->crm_ctx_intf; - + req_hdl_param.dev_id = ctx->dev_id; ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param); if (ctx->dev_hdl <= 0) { rc = -EFAULT; diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c index a05901afba71..4276b356da73 100644 --- a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c +++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c @@ -568,7 +568,7 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate( struct cam_cpas_axi_port *curr_axi_port = NULL; struct cam_cpas_axi_port *temp_axi_port = NULL; uint64_t required_camnoc_bw = 0; - int32_t clk_rate = 0; + int64_t clk_rate = 0; list_for_each_entry_safe(curr_axi_port, temp_axi_port, &cpas_core->axi_ports_list_head, sibling_port) { @@ -596,13 +596,13 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate( clk_rate = required_camnoc_bw / soc_private->camnoc_bus_width; - CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %d", + CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %lld", required_camnoc_bw, clk_rate); rc = cam_soc_util_set_src_clk_rate(soc_info, clk_rate); if (rc) CAM_ERR(CAM_CPAS, - "Failed in setting camnoc axi clk %llu %d %d", + "Failed in setting camnoc axi clk %llu %lld %d", required_camnoc_bw, clk_rate, rc); } diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c index 49774f24ba20..719fb12d7353 100644 --- a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c +++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c @@ -415,6 +415,12 @@ static void cam_cpastop_work(struct work_struct *work) return; } + mutex_lock(&cpas_hw->hw_mutex); + if (cpas_hw->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_CPAS, "CPAS CORE is off"); + mutex_unlock(&cpas_hw->hw_mutex); + return; + } for (i = 0; i < camnoc_info->irq_err_size; i++) { if ((payload->irq_status & camnoc_info->irq_err[i].sbm_port) && (camnoc_info->irq_err[i].enable)) { @@ -460,6 +466,7 @@ static void cam_cpastop_work(struct work_struct *work) ~camnoc_info->irq_err[i].sbm_port; } } + mutex_unlock(&cpas_hw->hw_mutex); atomic_dec(&cpas_core->irq_count); wake_up(&cpas_core->irq_count_wq); CAM_DBG(CAM_CPAS, "irq_count=%d\n", atomic_read(&cpas_core->irq_count)); diff --git a/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c b/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c index d4c9326ed5ab..083041c21dff 100644 --- a/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c @@ -206,10 +206,6 @@ static const struct of_device_id cam_fd_hw_dt_match[] = { .compatible = "qcom,fd501", .data = &cam_fd_wrapper200_core501_info, }, - { - .compatible = "qcom,fd501", - .data = &cam_fd_wrapper200_core501_info, - }, {} }; MODULE_DEVICE_TABLE(of, cam_fd_hw_dt_match); diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h b/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h index 311886ffd6da..d60a25e8b925 100644 --- a/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h +++ b/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -215,6 +215,27 @@ #define HFI_DEV_VERSION_MAX 0x5 +/* General errors and HFI Specific errors. */ +enum hfi_errors { + CAMERAICP_SUCCESS, + CAMERAICP_EFAILED, + CAMERAICP_ENOMEMORY, + CAMERAICP_EBADSTATE, + CAMERAICP_EBADPARM, + CAMERAICP_EBADITEM, + CAMERAICP_EINVALIDFORMAT, + CAMERAICP_EUNSUPPORTED, + CAMERAICP_EOUTOFBOUND, + CAMERAICP_ETIMEDOUT, + CAMERAICP_EABORTED, + CAMERAICP_EHWVIOLATION, + CAMERAICP_ECDMERROR, + CAMERAICP_HFI_ERR_COMMAND_SIZE = 1000, + CAMERAICP_HFI_ERR_MESSAGE_SIZE, + CAMERAICP_HFI_QUEUE_EMPTY, + CAMERAICP_HFI_QUEUE_FULL, +}; + /** * start of sys command packet types * These commands are used to get system level information diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index ca10a3adce5b..2b764d1b97a7 100644 --- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -1293,6 +1293,44 @@ static int cam_icp_mgr_ipe_bps_power_collapse(struct cam_icp_hw_mgr *hw_mgr, return rc; } +static int cam_icp_mgr_ipe_bps_get_gdsc_control( + struct cam_icp_hw_mgr *hw_mgr) +{ + int rc = 0; + struct cam_hw_intf *ipe0_dev_intf = NULL; + struct cam_hw_intf *ipe1_dev_intf = NULL; + struct cam_hw_intf *bps_dev_intf = NULL; + + ipe0_dev_intf = hw_mgr->ipe0_dev_intf; + ipe1_dev_intf = hw_mgr->ipe1_dev_intf; + bps_dev_intf = hw_mgr->bps_dev_intf; + + if ((!ipe0_dev_intf) || (!bps_dev_intf)) { + CAM_ERR(CAM_ICP, "dev intfs are wrong"); + return -EINVAL; + } + + if (icp_hw_mgr.ipe_bps_pc_flag) { + rc = bps_dev_intf->hw_ops.process_cmd( + bps_dev_intf->hw_priv, + CAM_ICP_BPS_CMD_POWER_COLLAPSE, + NULL, 0); + + rc = ipe0_dev_intf->hw_ops.process_cmd( + ipe0_dev_intf->hw_priv, + CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0); + + if (ipe1_dev_intf) { + rc = ipe1_dev_intf->hw_ops.process_cmd( + ipe1_dev_intf->hw_priv, + CAM_ICP_IPE_CMD_POWER_COLLAPSE, + NULL, 0); + } + } + + return rc; +} + static int cam_icp_set_dbg_default_clk(void *data, u64 val) { icp_hw_mgr.icp_debug_clk = val; @@ -1563,7 +1601,69 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag) return 0; } +static const char *cam_icp_error_handle_id_to_type( + uint32_t error_handle) +{ + const char *name = NULL; + switch (error_handle) { + case CAMERAICP_SUCCESS: + name = "SUCCESS"; + break; + case CAMERAICP_EFAILED: + name = "EFAILED"; + break; + case CAMERAICP_ENOMEMORY: + name = "ENOMEMORY"; + break; + case CAMERAICP_EBADSTATE: + name = "EBADSTATE"; + break; + case CAMERAICP_EBADPARM: + name = "EBADPARM"; + break; + case CAMERAICP_EBADITEM: + name = "EBADITEM"; + break; + case CAMERAICP_EINVALIDFORMAT: + name = "EINVALIDFORMAT"; + break; + case CAMERAICP_EUNSUPPORTED: + name = "EUNSUPPORTED"; + break; + case CAMERAICP_EOUTOFBOUND: + name = "EOUTOFBOUND"; + break; + case CAMERAICP_ETIMEDOUT: + name = "ETIMEDOUT"; + break; + case CAMERAICP_EABORTED: + name = "EABORTED"; + break; + case CAMERAICP_EHWVIOLATION: + name = "EHWVIOLATION"; + break; + case CAMERAICP_ECDMERROR: + name = "ECDMERROR"; + break; + case CAMERAICP_HFI_ERR_COMMAND_SIZE: + name = "HFI_ERR_COMMAND_SIZE"; + break; + case CAMERAICP_HFI_ERR_MESSAGE_SIZE: + name = "HFI_ERR_MESSAGE_SIZE"; + break; + case CAMERAICP_HFI_QUEUE_EMPTY: + name = "HFI_QUEUE_EMPTY"; + break; + case CAMERAICP_HFI_QUEUE_FULL: + name = "HFI_QUEUE_FULL"; + break; + default: + name = NULL; + break; + } + return name; +} static int cam_icp_mgr_process_msg_frame_process(uint32_t *msg_ptr) { struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL; @@ -1576,8 +1676,11 @@ static int cam_icp_mgr_process_msg_frame_process(uint32_t *msg_ptr) ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr; if (ioconfig_ack->err_type != HFI_ERR_SYS_NONE) { - CAM_ERR(CAM_ICP, "failed with error : %u", - ioconfig_ack->err_type); + CAM_ERR(CAM_ICP, + "failed with err_no= [%u] err_type= [%s]", + ioconfig_ack->err_type, + cam_icp_error_handle_id_to_type( + ioconfig_ack->err_type)); cam_icp_mgr_handle_frame_process(msg_ptr, ICP_FRAME_PROCESS_FAILURE); return -EIO; @@ -1617,8 +1720,12 @@ static int cam_icp_mgr_process_msg_config_io(uint32_t *msg_ptr) ipe_config_ack = (struct hfi_msg_ipe_config *)(ioconfig_ack->msg_data); if (ipe_config_ack->rc) { - CAM_ERR(CAM_ICP, "rc = %d err = %u", - ipe_config_ack->rc, ioconfig_ack->err_type); + CAM_ERR(CAM_ICP, "rc = %d failed with\n" + "err_no = [%u] err_type = [%s]", + ipe_config_ack->rc, + ioconfig_ack->err_type, + cam_icp_error_handle_id_to_type( + ioconfig_ack->err_type)); return -EIO; } ctx_data = (struct cam_icp_hw_ctx_data *) @@ -1783,9 +1890,13 @@ static int cam_icp_mgr_process_direct_ack_msg(uint32_t *msg_ptr) (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1; if (ctx_data->state != CAM_ICP_CTX_STATE_FREE) complete(&ctx_data->wait_complete); - CAM_DBG(CAM_ICP, - "received IPE/BPS MAP ACK:ctx_state =%d err_status =%u", - ctx_data->state, ioconfig_ack->err_type); + CAM_DBG(CAM_ICP, "received IPE/BPS\n" + "MAP ACK:ctx_state =%d\n" + "failed with err_no = [%u] err_type = [%s]", + ctx_data->state, + ioconfig_ack->err_type, + cam_icp_error_handle_id_to_type( + ioconfig_ack->err_type)); break; case HFI_IPEBPS_CMD_OPCODE_MEM_UNMAP: ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr; @@ -1793,9 +1904,13 @@ static int cam_icp_mgr_process_direct_ack_msg(uint32_t *msg_ptr) (struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1; if (ctx_data->state != CAM_ICP_CTX_STATE_FREE) complete(&ctx_data->wait_complete); - CAM_DBG(CAM_ICP, - "received IPE/BPS UNMAP ACK:ctx_state =%d err_status =%u", - ctx_data->state, ioconfig_ack->err_type); + CAM_DBG(CAM_ICP, + "received IPE/BPS UNMAP ACK:ctx_state =%d\n" + "failed with err_no = [%u] err_type = [%s]", + ctx_data->state, + ioconfig_ack->err_type, + cam_icp_error_handle_id_to_type( + ioconfig_ack->err_type)); break; default: CAM_ERR(CAM_ICP, "Invalid opcode : %u", @@ -1817,27 +1932,31 @@ static int cam_icp_ipebps_reset(struct cam_icp_hw_mgr *hw_mgr) ipe1_dev_intf = hw_mgr->ipe1_dev_intf; bps_dev_intf = hw_mgr->bps_dev_intf; - rc = bps_dev_intf->hw_ops.process_cmd( - bps_dev_intf->hw_priv, - CAM_ICP_BPS_CMD_RESET, - NULL, 0); - if (rc) - CAM_ERR(CAM_ICP, "bps reset failed"); - - rc = ipe0_dev_intf->hw_ops.process_cmd( - ipe0_dev_intf->hw_priv, - CAM_ICP_IPE_CMD_RESET, - NULL, 0); - if (rc) - CAM_ERR(CAM_ICP, "ipe0 reset failed"); + if (hw_mgr->bps_ctxt_cnt) { + rc = bps_dev_intf->hw_ops.process_cmd( + bps_dev_intf->hw_priv, + CAM_ICP_BPS_CMD_RESET, + NULL, 0); + if (rc) + CAM_ERR(CAM_ICP, "bps reset failed"); + } - if (ipe1_dev_intf) { - rc = ipe1_dev_intf->hw_ops.process_cmd( - ipe1_dev_intf->hw_priv, + if (hw_mgr->ipe_ctxt_cnt) { + rc = ipe0_dev_intf->hw_ops.process_cmd( + ipe0_dev_intf->hw_priv, CAM_ICP_IPE_CMD_RESET, NULL, 0); if (rc) - CAM_ERR(CAM_ICP, "ipe1 reset failed"); + CAM_ERR(CAM_ICP, "ipe0 reset failed"); + + if (ipe1_dev_intf) { + rc = ipe1_dev_intf->hw_ops.process_cmd( + ipe1_dev_intf->hw_priv, + CAM_ICP_IPE_CMD_RESET, + NULL, 0); + if (rc) + CAM_ERR(CAM_ICP, "ipe1 reset failed"); + } } return 0; @@ -1858,6 +1977,7 @@ static int cam_icp_mgr_trigger_recovery(struct cam_icp_hw_mgr *hw_mgr) sfr_buffer = (struct sfr_buf *)icp_hw_mgr.hfi_mem.sfr_buf.kva; CAM_WARN(CAM_ICP, "SFR:%s", sfr_buffer->msg); + cam_icp_mgr_ipe_bps_get_gdsc_control(hw_mgr); cam_icp_ipebps_reset(hw_mgr); atomic_set(&hw_mgr->recovery, 1); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c index 2982ce027aa7..57375c4ad50f 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c @@ -2875,7 +2875,7 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, req_hdl_param.media_entity_flag = 0; req_hdl_param.ops = ctx->crm_ctx_intf; req_hdl_param.priv = ctx; - + req_hdl_param.dev_id = CAM_ISP; CAM_DBG(CAM_ISP, "get device handle form bridge"); ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param); if (ctx->dev_hdl <= 0) { diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 177538acd0b0..fe3d2f12a6e2 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -2984,6 +2984,7 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) } } + ctx->dual_ife_irq_mismatch_cnt = 0; /* Start IFE root node: do nothing */ CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index); @@ -3066,6 +3067,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv, ctx->is_rdi_only_context = 0; ctx->cdm_handle = 0; ctx->cdm_ops = NULL; + ctx->dual_ife_irq_mismatch_cnt = 0; atomic_set(&ctx->overflow_pending, 0); for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { ctx->sof_cnt[i] = 0; @@ -3573,6 +3575,38 @@ void fill_res_bitmap(uint32_t resource_type, unsigned long *res_bitmap) } } +static int cam_isp_blob_init_frame_drop( + struct cam_isp_init_frame_drop_config *frame_drop_cfg, + struct cam_hw_prepare_update_args *prepare) +{ + struct cam_ife_hw_mgr_ctx *ctx = NULL; + struct cam_ife_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + uint32_t hw_idx = UINT_MAX; + uint32_t i; + int rc = 0; + + ctx = prepare->ctxt_to_hw_map; + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf->hw_idx == hw_idx) + continue; + + rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv, + CAM_IFE_CSID_SET_INIT_FRAME_DROP, + frame_drop_cfg, + sizeof( + struct cam_isp_init_frame_drop_config *)); + hw_idx = hw_intf->hw_idx; + } + } + return rc; +} + static int cam_isp_packet_generic_blob_handler(void *user_data, uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data) { @@ -3818,7 +3852,22 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "FS Update Failed rc: %d", rc); } break; + case CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP: { + struct cam_isp_init_frame_drop_config *frame_drop_cfg = + (struct cam_isp_init_frame_drop_config *)blob_data; + if (blob_size < sizeof(struct cam_isp_init_frame_drop_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", + blob_size, + sizeof(struct cam_isp_init_frame_drop_config)); + return -EINVAL; + } + + rc = cam_isp_blob_init_frame_drop(frame_drop_cfg, prepare); + if (rc) + CAM_ERR(CAM_ISP, "Init Frame drop Update Failed"); + } + break; default: CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type); break; @@ -4101,6 +4150,36 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet, } } +static void cam_ife_mgr_ctx_irq_dump(struct cam_ife_hw_mgr_ctx *ctx) +{ + struct cam_ife_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + struct cam_isp_hw_get_cmd_update cmd_update; + int i = 0; + + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { + if (hw_mgr_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT) + continue; + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + switch (hw_mgr_res->hw_res[i]->res_id) { + case CAM_ISP_HW_VFE_IN_CAMIF: + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + cmd_update.res = hw_mgr_res->hw_res[i]; + cmd_update.cmd_type = + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP; + hw_intf->hw_ops.process_cmd(hw_intf->hw_priv, + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, + &cmd_update, sizeof(cmd_update)); + break; + default: + break; + } + } + } +} + static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) { int rc = 0; @@ -4771,11 +4850,26 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( (event_cnt[core_idx1] && (event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) { + if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt > 10) { + rc = -1; + return rc; + } + CAM_ERR_RATE_LIMIT(CAM_ISP, "One of the VFE could not generate hw event %d", hw_event_type); - rc = -1; - return rc; + if (event_cnt[core_idx0] >= 2) { + event_cnt[core_idx0]--; + ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++; + } + if (event_cnt[core_idx1] >= 2) { + event_cnt[core_idx1]--; + ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++; + } + + if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt == 1) + cam_ife_mgr_ctx_irq_dump(ife_hw_mgr_ctx); + rc = 0; } CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d", diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h index bf5f1527caa4..0e6d79b75232 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h @@ -102,38 +102,42 @@ struct cam_ife_hw_mgr_debug { /** * struct cam_vfe_hw_mgr_ctx - IFE HW manager Context object * - * @list: used by the ctx list. - * @common: common acquired context data - * @ctx_index: acquired context id. - * @hw_mgr: IFE hw mgr which owns this context - * @ctx_in_use: flag to tell whether context is active - * @res_list_ife_in: Starting resource(TPG,PHY0, PHY1...) Can only be - * one. - * @res_list_csid: CSID resource list - * @res_list_ife_src: IFE input resource list - * @res_list_ife_in_rd IFE input resource list for read path - * @res_list_ife_out: IFE output resoruces array - * @free_res_list: Free resources list for the branch node - * @res_pool: memory storage for the free resource list - * @irq_status0_mask: irq_status0_mask for the context - * @irq_status1_mask: irq_status1_mask for the context - * @base device base index array contain the all IFE HW - * instance associated with this context. - * @num_base number of valid base data in the base array - * @cdm_handle cdm hw acquire handle - * @cdm_ops cdm util operation pointer for building - * cdm commands - * @cdm_cmd cdm base and length request pointer - * @sof_cnt sof count value per core, used for dual VFE - * @epoch_cnt epoch count value per core, used for dual VFE - * @eof_cnt eof count value per core, used for dual VFE - * @overflow_pending flat to specify the overflow is pending for the - * context - * @is_rdi_only_context flag to specify the context has only rdi resource - * @config_done_complete indicator for configuration complete - * @init_done indicate whether init hw is done - * @is_fe_enable indicate whether fetch engine\read path is enabled - * @res_bitmap fill resource bitmap for which rup to be set + * @list: used by the ctx list. + * @common: common acquired context data + * @ctx_index: acquired context id. + * @hw_mgr: IFE hw mgr which owns this context + * @ctx_in_use: flag to tell whether context is active + * @res_list_ife_in: Starting resource(TPG,PHY0, PHY1...) Can only be + * one. + * @res_list_csid: CSID resource list + * @res_list_ife_src: IFE input resource list + * @res_list_ife_in_rd IFE input resource list for read path + * @res_list_ife_out: IFE output resoruces array + * @free_res_list: Free resources list for the branch node + * @res_pool: memory storage for the free resource list + * @irq_status0_mask: irq_status0_mask for the context + * @irq_status1_mask: irq_status1_mask for the context + * @base device base index array contain the all IFE HW + * instance associated with this context. + * @num_base number of valid base data in the base array + * @cdm_handle cdm hw acquire handle + * @cdm_ops cdm util operation pointer for building + * cdm commands + * @cdm_cmd cdm base and length request pointer + * @sof_cnt sof count value per core, used for dual VFE + * @epoch_cnt epoch count value per core, used for dual VFE + * @eof_cnt eof count value per core, used for dual VFE + * @overflow_pending flat to specify the overflow is pending + * for the context + * @is_rdi_only_context flag to specify the context has only rdi + * resource + * @config_done_complete indicator for configuration complete + * @init_done indicate whether init hw is done + * @is_fe_enable indicate whether fetch engine\read path + * is enabled + * @res_bitmap fill resource bitmap for which rup to be set + * @dual_ife_irq_mismatch_cnt irq mismatch count value per core, used for + * dual VFE */ struct cam_ife_hw_mgr_ctx { struct list_head list; @@ -171,6 +175,7 @@ struct cam_ife_hw_mgr_ctx { bool init_done; bool is_fe_enable; unsigned long res_bitmap; + uint32_t dual_ife_irq_mismatch_cnt; }; /** diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index 8fba017cfe27..5610f6d267ff 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -468,6 +468,9 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw) csid_hw->hw_intf->hw_idx, val); csid_hw->error_irq_count = 0; + for (i = 0 ; i < CAM_IFE_PIX_PATH_RES_MAX; i++) + csid_hw->res_sof_cnt[i] = 0; + return rc; } @@ -838,7 +841,6 @@ static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw, return rc; } - static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw, struct cam_csid_hw_reserve_resource_args *reserve) { @@ -953,7 +955,7 @@ static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw, path_data->height = reserve->in_port->height; path_data->start_line = reserve->in_port->line_start; path_data->end_line = reserve->in_port->line_stop; - + path_data->usage_type = reserve->in_port->usage_type; /* Enable RDI crop for single ife use case only */ switch (reserve->res_id) { case CAM_IFE_PIX_PATH_RES_RDI_0: @@ -1119,6 +1121,7 @@ static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw) static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) { int rc = -EINVAL; + uint32_t i; struct cam_hw_soc_info *soc_info; const struct cam_ife_csid_reg_offset *csid_reg; unsigned long flags; @@ -1159,12 +1162,95 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) spin_lock_irqsave(&csid_hw->lock_state, flags); csid_hw->device_enabled = 0; spin_unlock_irqrestore(&csid_hw->lock_state, flags); + for (i = 0; i < CAM_IFE_PIX_PATH_RES_MAX; i++) + csid_hw->res_sof_cnt[i] = 0; + csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; csid_hw->error_irq_count = 0; return rc; } +static int cam_ife_csid_check_path_active(struct cam_ife_csid_hw *csid_hw) +{ + struct cam_hw_soc_info *soc_info; + const struct cam_ife_csid_reg_offset *csid_reg; + uint32_t i, path_status = 1; + + csid_reg = csid_hw->csid_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + /* check the IPP path status */ + if (csid_reg->cmn_reg->num_pix) { + path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->csid_pxl_status_addr); + CAM_DBG(CAM_ISP, "CSID:%d IPP path status:%d", + csid_hw->hw_intf->hw_idx, path_status); + /* if status is 0 then it is active */ + if (!path_status) + goto end; + } + + if (csid_reg->cmn_reg->num_ppp) { + path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ppp_reg->csid_pxl_status_addr); + CAM_DBG(CAM_ISP, "CSID:%d PPP path status:%d", + csid_hw->hw_intf->hw_idx, path_status); + /* if status is 0 then it is active */ + if (!path_status) + goto end; + } + + /* Check the RDI path status */ + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { + path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->csid_rdi_status_addr); + CAM_DBG(CAM_ISP, "CSID:%d RDI:%d path status:%d", + csid_hw->hw_intf->hw_idx, i, path_status); + /* if status is 0 then it is active */ + if (!path_status) + goto end; + } + +end: + return path_status; +} + +static void cam_ife_csid_reset_init_frame_drop( + struct cam_ife_csid_hw *csid_hw) +{ + const struct cam_ife_csid_reg_offset *csid_reg; + uint32_t i = 0; + + /* + * Reset CSID init frame drop value only if all resources are + * released + */ + csid_reg = csid_hw->csid_info->csid_reg; + if (csid_reg->cmn_reg->num_pix) { + if (csid_hw->ipp_res.res_state != + CAM_ISP_RESOURCE_STATE_AVAILABLE) + goto end; + } + + if (csid_reg->cmn_reg->num_ppp) { + if (csid_hw->ppp_res.res_state != + CAM_ISP_RESOURCE_STATE_AVAILABLE) + goto end; + } + + for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { + if (csid_hw->rdi_res[i].res_state != + CAM_ISP_RESOURCE_STATE_AVAILABLE) + goto end; + } + + /* All CSID resources are available reset the init frame drop */ + csid_hw->init_frame_drop = 0; +end: + return; + +} static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw, struct cam_isp_resource_node *res) @@ -1724,7 +1810,7 @@ static int cam_ife_csid_enable_pxl_path( struct cam_ife_csid_path_cfg *path_data; const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL; bool is_ipp; - uint32_t val = 0; + uint32_t val = 0, path_status; path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; @@ -1767,14 +1853,15 @@ static int cam_ife_csid_enable_pxl_path( /* Default is internal halt mode */ val = 0; - /* - * Resume at frame boundary if Master or No Sync. - * Slave will get resume command from Master. - */ - if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER || - path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) - val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY; - + /* Resume at frame boundary */ + path_status = cam_ife_csid_check_path_active(csid_hw); + if (!csid_hw->init_frame_drop || + (csid_hw->init_frame_drop && !path_status)) { + CAM_DBG(CAM_ISP, "start pixel path"); + if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER || + path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) + val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY; + } cam_io_w_mb(val, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_ctrl_addr); @@ -1788,8 +1875,10 @@ static int cam_ife_csid_enable_pxl_path( if (pxl_reg->ccif_violation_en) val |= CSID_PATH_ERROR_CCIF_VIOLATION; - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) + if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) || + (csid_hw->init_frame_drop && path_status)) val |= CSID_PATH_INFO_INPUT_SOF; + if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) val |= CSID_PATH_INFO_INPUT_EOF; @@ -2086,8 +2175,10 @@ static int cam_ife_csid_enable_rdi_path( { const struct cam_ife_csid_reg_offset *csid_reg; struct cam_hw_soc_info *soc_info; - uint32_t id, val; + struct cam_ife_csid_path_cfg *path_data; + uint32_t id, val, path_status; + path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; soc_info = &csid_hw->hw_info->soc_info; id = res->res_id; @@ -2102,19 +2193,28 @@ static int cam_ife_csid_enable_rdi_path( return -EINVAL; } - /*resume at frame boundary */ - cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY, - soc_info->reg_map[0].mem_base + - csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr); + if (path_data->usage_type) + path_data->init_frame_drop = csid_hw->init_frame_drop + 1; + /*resume at frame boundary */ + path_status = cam_ife_csid_check_path_active(csid_hw); + if (!path_data->init_frame_drop || + (path_data->init_frame_drop && !path_status)) { + CAM_DBG(CAM_ISP, "Start RDI:%d path", id); + cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY, + soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr); + } /* Enable the required RDI interrupts */ val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW; if (csid_reg->rdi_reg[id]->ccif_violation_en) val |= CSID_PATH_ERROR_CCIF_VIOLATION; - if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) + if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) || + (path_data->init_frame_drop && path_status)) val |= CSID_PATH_INFO_INPUT_SOF; + if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) val |= CSID_PATH_INFO_INPUT_EOF; @@ -2374,6 +2474,19 @@ static int cam_ife_csid_set_csid_debug(struct cam_ife_csid_hw *csid_hw, return 0; } +static int cam_ife_csid_set_init_frame_drop(struct cam_ife_csid_hw *csid_hw, + void *cmd_args) +{ + struct cam_isp_init_frame_drop_config *frame_drop_cfg; + + frame_drop_cfg = (struct cam_isp_init_frame_drop_config *) cmd_args; + csid_hw->init_frame_drop = frame_drop_cfg->init_frame_drop; + CAM_DBG(CAM_ISP, "CSID:%d set init frame drop:%d", + csid_hw->hw_intf->hw_idx, csid_hw->init_frame_drop); + + return 0; +} + static int cam_ife_csid_get_hw_caps(void *hw_priv, void *get_hw_cap_args, uint32_t arg_size) { @@ -2550,6 +2663,7 @@ static int cam_ife_csid_release(void *hw_priv, break; case CAM_ISP_RESOURCE_PIX_PATH: res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; + cam_ife_csid_reset_init_frame_drop(csid_hw); break; default: CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d", @@ -3014,6 +3128,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv, case CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE: rc = cam_ife_csid_set_csid_clock(csid_hw, cmd_args); break; + case CAM_IFE_CSID_SET_INIT_FRAME_DROP: + rc = cam_ife_csid_set_init_frame_drop(csid_hw, cmd_args); + break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); @@ -3031,6 +3148,9 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) struct cam_hw_soc_info *soc_info; const struct cam_ife_csid_reg_offset *csid_reg; const struct cam_ife_csid_csi2_rx_reg_offset *csi2_reg; + struct cam_ife_csid_path_cfg *path_data; + const struct cam_ife_csid_pxl_reg_offset *pxl_reg; + const struct cam_ife_csid_rdi_reg_offset *rdi_reg; uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0; uint32_t irq_status_rdi[4] = {0, 0, 0, 0}; uint32_t val, irq_status_ppp = 0; @@ -3262,6 +3382,53 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) csid_hw->irq_debug_cnt++; } + if ((irq_status_ipp & CSID_PATH_INFO_INPUT_SOF) && + (csid_hw->init_frame_drop) && + (csid_hw->ipp_res.res_state == + CAM_ISP_RESOURCE_STATE_STREAMING)) { + csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP]++; + CAM_DBG(CAM_ISP, + "CSID:%d IPP SOF cnt:%d init_frame_drop:%d", + csid_hw->hw_intf->hw_idx, + csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP], + csid_hw->init_frame_drop); + if (csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP] == + csid_hw->init_frame_drop) { + pxl_reg = csid_reg->ipp_reg; + path_data = csid_hw->ipp_res.res_priv; + if (path_data->sync_mode == + CAM_ISP_HW_SYNC_MASTER) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + + val |= + CAM_CSID_RESUME_AT_FRAME_BOUNDARY; + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + + } else if (path_data->sync_mode == + CAM_ISP_HW_SYNC_NONE) { + cam_io_w_mb( + CAM_CSID_RESUME_AT_FRAME_BOUNDARY, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + } + + if (!(csid_hw->csid_debug & + CSID_DEBUG_ENABLE_SOF_IRQ)) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_irq_mask_addr); + val &= ~(CSID_PATH_INFO_INPUT_SOF); + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_irq_mask_addr); + } + } + } + if ((irq_status_ipp & CSID_PATH_INFO_INPUT_EOF) && (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)) CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP EOF received", @@ -3297,6 +3464,52 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) csid_hw->irq_debug_cnt++; } + if ((irq_status_ppp & CSID_PATH_INFO_INPUT_SOF) && + (csid_hw->init_frame_drop) && + (csid_hw->ppp_res.res_state == + CAM_ISP_RESOURCE_STATE_STREAMING)) { + csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP]++; + CAM_DBG(CAM_ISP, + "CSID:%d PPP SOF cnt:%d init_frame_drop:%d", + csid_hw->hw_intf->hw_idx, + csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP], + csid_hw->init_frame_drop); + if (csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP] == + csid_hw->init_frame_drop) { + path_data = csid_hw->ppp_res.res_priv; + pxl_reg = csid_reg->ppp_reg; + if (path_data->sync_mode == + CAM_ISP_HW_SYNC_MASTER) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + + val |= + CAM_CSID_RESUME_AT_FRAME_BOUNDARY; + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + } else if (path_data->sync_mode == + CAM_ISP_HW_SYNC_NONE) { + cam_io_w_mb( + CAM_CSID_RESUME_AT_FRAME_BOUNDARY, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + } + + if (!(csid_hw->csid_debug & + CSID_DEBUG_ENABLE_SOF_IRQ)) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_irq_mask_addr); + val &= ~(CSID_PATH_INFO_INPUT_SOF); + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_irq_mask_addr); + } + } + } + if ((irq_status_ppp & CSID_PATH_INFO_INPUT_EOF) && (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)) CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received", @@ -3317,6 +3530,9 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) } for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { + path_data = (struct cam_ife_csid_path_cfg *) + csid_hw->rdi_res[i].res_priv; + rdi_reg = csid_reg->rdi_reg[i]; if (irq_status_rdi[i] & BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) { complete(&csid_hw->csid_rdin_complete[i]); @@ -3330,6 +3546,35 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) csid_hw->irq_debug_cnt++; } + if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_SOF) && + (path_data->init_frame_drop) && + (csid_hw->rdi_res[i].res_state == + CAM_ISP_RESOURCE_STATE_STREAMING)) { + csid_hw->res_sof_cnt[i]++; + CAM_DBG(CAM_ISP, + "CSID:%d RDI:%d SOF cnt:%d init_frame_drop:%d", + csid_hw->hw_intf->hw_idx, i, + csid_hw->res_sof_cnt[i], + path_data->init_frame_drop); + if (csid_hw->res_sof_cnt[i] == + path_data->init_frame_drop) { + cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY, + soc_info->reg_map[0].mem_base + + rdi_reg->csid_rdi_ctrl_addr); + + if (!(csid_hw->csid_debug & + CSID_DEBUG_ENABLE_SOF_IRQ)) { + val = cam_io_r_mb( + soc_info->reg_map[0].mem_base + + rdi_reg->csid_rdi_irq_mask_addr); + val &= ~(CSID_PATH_INFO_INPUT_SOF); + cam_io_w_mb(val, + soc_info->reg_map[0].mem_base + + rdi_reg->csid_rdi_irq_mask_addr); + } + } + } + if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF) && (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)) CAM_INFO_RATE_LIMIT(CAM_ISP, diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h index 3a093d205f59..600deb245f32 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h @@ -419,6 +419,9 @@ struct cam_ife_csid_cid_data { * @master_idx: For Slave reservation, Give master IFE instance Index. * Slave will synchronize with master Start and stop operations * @clk_rate Clock rate + * @usage_type Usage type ie dual or single ife usecase + * @init_frame_drop init frame drop value. In dual ife case rdi need to drop one + * more frame than pix. * */ struct cam_ife_csid_path_cfg { @@ -437,6 +440,8 @@ struct cam_ife_csid_path_cfg { enum cam_isp_hw_sync_mode sync_mode; uint32_t master_idx; uint64_t clk_rate; + uint32_t usage_type; + uint32_t init_frame_drop; }; /** @@ -468,6 +473,13 @@ struct cam_ife_csid_path_cfg { * @irq_debug_cnt: Counter to track sof irq's when above flag is set. * @error_irq_count Error IRQ count, if continuous error irq comes * need to stop the CSID and mask interrupts. + * @device_enabled Device enabled will set once CSID powered on and + * initial configuration are done. + * @lock_state csid spin lock + * @dual_usage usage type, dual ife or single ife + * @init_frame_drop Initial frame drop number + * @res_sof_cnt path resource sof count value. it used for initial + * frame drop * */ struct cam_ife_csid_hw { @@ -496,6 +508,9 @@ struct cam_ife_csid_hw { uint32_t error_irq_count; uint32_t device_enabled; spinlock_t lock_state; + uint32_t dual_usage; + uint32_t init_frame_drop; + uint32_t res_sof_cnt[CAM_IFE_PIX_PATH_RES_MAX]; }; int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h index 58818fbecf67..0c45bd1268b9 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -157,6 +157,7 @@ enum cam_ife_csid_cmd_type { CAM_IFE_CSID_CMD_GET_TIME_STAMP, CAM_IFE_CSID_SET_CSID_DEBUG, CAM_IFE_CSID_SOF_IRQ_DEBUG, + CAM_IFE_CSID_SET_INIT_FRAME_DROP, CAM_IFE_CSID_CMD_MAX, }; diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index 61542566a924..b23014773022 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -104,6 +104,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE, CAM_ISP_HW_CMD_FE_UPDATE_IN_RD, CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD, + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, CAM_ISP_HW_CMD_MAX, }; diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c index 2bd6db9954f1..a26c11264d2c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c @@ -760,6 +760,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_CLOCK_UPDATE: case CAM_ISP_HW_CMD_BW_UPDATE: case CAM_ISP_HW_CMD_BW_CONTROL: + case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: rc = core_info->vfe_top->hw_ops.process_cmd( core_info->vfe_top->top_priv, cmd_type, cmd_args, arg_size); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c index c40936525c73..4e9a97501749 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c @@ -421,6 +421,40 @@ static int cam_vfe_camif_reg_dump_bh( return 0; } +static int cam_vfe_camif_irq_reg_dump( + struct cam_isp_resource_node *camif_res) +{ + struct cam_vfe_mux_camif_data *camif_priv; + struct cam_vfe_soc_private *soc_private; + int rc = 0; + + if (!camif_res) { + CAM_ERR(CAM_ISP, "Error! Invalid input arguments\n"); + return -EINVAL; + } + + if ((camif_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) || + (camif_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)) { + CAM_ERR(CAM_ISP, "Error! Invalid state\n"); + return 0; + } + + camif_priv = (struct cam_vfe_mux_camif_data *)camif_res->res_priv; + soc_private = camif_priv->soc_info->soc_private; + + CAM_INFO(CAM_ISP, + "Core Id =%d Mask reg: offset 0x%x val 0x%x offset 0x%x val 0x%x", + camif_priv->hw_intf->hw_idx, + 0x5c, cam_io_r_mb(camif_priv->mem_base + 0x5c), + 0x60, cam_io_r_mb(camif_priv->mem_base + 0x60)); + CAM_INFO(CAM_ISP, + "Core Id =%d Status reg: offset 0x%x val 0x%x offset 0x%x val 0x%x", + camif_priv->hw_intf->hw_idx, + 0x6c, cam_io_r_mb(camif_priv->mem_base + 0x6c), + 0x70, cam_io_r_mb(camif_priv->mem_base + 0x70)); + return rc; +} + static int cam_vfe_camif_resource_stop( struct cam_isp_resource_node *camif_res) { @@ -508,6 +542,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node, (struct cam_vfe_mux_camif_data *)rsrc_node->res_priv; camif_priv->camif_debug = *((uint32_t *)cmd_args); break; + case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: + rc = cam_vfe_camif_irq_reg_dump(rsrc_node); + break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c index c5acbe5dbd16..b0ac94b895f1 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c @@ -438,6 +438,19 @@ static int cam_vfe_top_mux_get_reg_update( return -EINVAL; } +static int cam_vfe_get_irq_register_dump( + struct cam_vfe_top_ver2_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + struct cam_isp_hw_get_cmd_update *cmd_update = cmd_args; + + if (cmd_update->res->process_cmd) + cmd_update->res->process_cmd(cmd_update->res, + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, cmd_args, arg_size); + + return 0; +} + int cam_vfe_top_get_hw_caps(void *device_priv, void *get_hw_cap_args, uint32_t arg_size) { @@ -723,6 +736,10 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_BW_CONTROL: rc = cam_vfe_top_bw_control(top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: + rc = cam_vfe_get_irq_register_dump(top_priv, + cmd_args, arg_size); + break; default: rc = -EINVAL; CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type); diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c index f1b3ccefe62c..c8e2a023b0d4 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c @@ -348,10 +348,12 @@ static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link, struct cam_req_mgr_req_queue *in_q = link->req.in_q; slot = &in_q->slot[idx]; - CAM_DBG(CAM_CRM, "RESET: idx: %d: slot->status %d", idx, slot->status); + CAM_DBG(CAM_CRM, "RESET: last applied idx %d: idx %d: slot->status %d", + in_q->last_applied_idx, idx, slot->status); /* Check if CSL has already pushed new request*/ - if (slot->status == CRM_SLOT_STATUS_REQ_ADDED) + if (slot->status == CRM_SLOT_STATUS_REQ_ADDED || + in_q->last_applied_idx == idx) return; /* Reset input queue slot */ @@ -512,9 +514,11 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link, } if (link->req.apply_data[pd].skip_idx || link->req.apply_data[pd].req_id < 0) { - CAM_DBG(CAM_CRM, "skip %d req_id %lld", + CAM_DBG(CAM_CRM, + "skip %d req_id %lld pd %d dev_name %s", link->req.apply_data[pd].skip_idx, - link->req.apply_data[pd].req_id); + link->req.apply_data[pd].req_id, + pd, dev->dev_info.name); continue; } if (!(dev->dev_info.trigger & trigger)) @@ -893,6 +897,7 @@ static int __cam_req_mgr_check_sync_req_is_ready( int64_t req_id = 0; int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0; int32_t sync_num_slots = 0; + bool ready = true, sync_ready = true; if (!link->sync_link) { CAM_ERR(CAM_CRM, "Sync link null"); @@ -921,17 +926,7 @@ static int __cam_req_mgr_check_sync_req_is_ready( CAM_DBG(CAM_CRM, "Skip Process Req: %lld on link: %x", req_id, link->link_hdl); - link->sync_link_sof_skip = true; - return rc; - } - - rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true); - if (rc) { - CAM_DBG(CAM_CRM, - "Req: %lld [My link] not ready on link: %x, rc=%d", - req_id, link->link_hdl, rc); - link->sync_link_sof_skip = true; - return rc; + ready = false; } sync_slot_idx = __cam_req_mgr_find_slot_for_req( @@ -939,8 +934,7 @@ static int __cam_req_mgr_check_sync_req_is_ready( if (sync_slot_idx == -1) { CAM_DBG(CAM_CRM, "Req: %lld not found on link: %x [other link]", req_id, sync_link->link_hdl); - link->sync_link_sof_skip = true; - return -EINVAL; + sync_ready = false; } sync_rd_idx = sync_link->req.in_q->rd_idx; @@ -956,14 +950,38 @@ static int __cam_req_mgr_check_sync_req_is_ready( return -EAGAIN; } + rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true); + if (rc) { + CAM_DBG(CAM_CRM, + "Req: %lld [My link] not ready on link: %x, rc=%d", + req_id, link->link_hdl, rc); + ready = false; + } + rc = __cam_req_mgr_check_link_is_ready(sync_link, sync_slot_idx, true); if (rc && (sync_link->req.in_q->slot[sync_slot_idx].status != CRM_SLOT_STATUS_REQ_APPLIED)) { CAM_DBG(CAM_CRM, "Req: %lld not ready on [other link] link: %x, rc=%d", req_id, sync_link->link_hdl, rc); + sync_ready = false; + } + + /* + * If both of them are ready or not ready, then just + * skip this sof and don't skip sync link next SOF. + */ + if (sync_ready != ready) { + CAM_DBG(CAM_CRM, + "Req: %lld ready %d sync_ready %d, ignore sync link next SOF", + req_id, ready, sync_ready); link->sync_link_sof_skip = true; - return rc; + return -EINVAL; + } else if (ready == false) { + CAM_DBG(CAM_CRM, + "Req: %lld not ready on link: %x", + req_id, link->link_hdl); + return -EINVAL; } CAM_DBG(CAM_REQ, @@ -995,7 +1013,7 @@ static int __cam_req_mgr_check_sync_req_is_ready( static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, uint32_t trigger) { - int rc = 0, idx; + int rc = 0, idx, last_app_idx; int reset_step = 0; struct cam_req_mgr_slot *slot = NULL; struct cam_req_mgr_req_queue *in_q; @@ -1129,6 +1147,7 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, slot->req_id, link->link_hdl); idx = in_q->rd_idx; + reset_step = link->max_delay; if (link->sync_link) { if ((link->in_msync_mode) && @@ -1136,6 +1155,25 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, reset_step = link->sync_link->max_delay; } + + /* This is to handle a rare scenario of scheduling + * issue. If ISP sends multiple sofs due to scheduling + * issue, it is required to retain last applied index + * to help recover. + * In this case, ISP goes into Bubble, asking to reapply + * the bubbled request which has already been reset by + * CRM. Below code retains the last applied request. + */ + + if (slot->req_id > 0) { + last_app_idx = in_q->last_applied_idx; + in_q->last_applied_idx = idx; + if (abs(last_app_idx - idx) >= + reset_step + 1) + __cam_req_mgr_reset_req_slot(link, + last_app_idx); + } + __cam_req_mgr_dec_idx( &idx, reset_step + 1, in_q->num_slots); @@ -2359,18 +2397,24 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = { * */ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, - struct cam_req_mgr_link_info *link_info) + struct cam_req_mgr_ver_info *link_info) { - int rc = 0, i = 0; + int rc = 0, i = 0, num_devices = 0; struct cam_req_mgr_core_dev_link_setup link_data; struct cam_req_mgr_connected_device *dev; struct cam_req_mgr_req_tbl *pd_tbl; enum cam_pipeline_delay max_delay; uint32_t subscribe_event = 0; - - if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES) - return -EPERM; - + if (link_info->version == VERSION_1) { + if (link_info->u.link_info_v1.num_devices > + CAM_REQ_MGR_MAX_HANDLES) + return -EPERM; + } + else if (link_info->version == VERSION_2) { + if (link_info->u.link_info_v2.num_devices > + CAM_REQ_MGR_MAX_HANDLES_V2) + return -EPERM; + } mutex_init(&link->req.lock); CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock); link->req.num_tbl = 0; @@ -2380,11 +2424,21 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, return rc; max_delay = CAM_PIPELINE_DELAY_0; - for (i = 0; i < link_info->num_devices; i++) { + if (link_info->version == VERSION_1) + num_devices = link_info->u.link_info_v1.num_devices; + else if (link_info->version == VERSION_2) + num_devices = link_info->u.link_info_v2.num_devices; + for (i = 0; i < num_devices; i++) { dev = &link->l_dev[i]; /* Using dev hdl, get ops ptr to communicate with device */ - dev->ops = (struct cam_req_mgr_kmd_ops *) - cam_get_device_ops(link_info->dev_hdls[i]); + if (link_info->version == VERSION_1) + dev->ops = (struct cam_req_mgr_kmd_ops *) + cam_get_device_ops( + link_info->u.link_info_v1.dev_hdls[i]); + else if (link_info->version == VERSION_2) + dev->ops = (struct cam_req_mgr_kmd_ops *) + cam_get_device_ops( + link_info->u.link_info_v2.dev_hdls[i]); if (!dev->ops || !dev->ops->get_dev_info || !dev->ops->link_setup) { @@ -2392,18 +2446,29 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, rc = -ENXIO; goto error; } - dev->dev_hdl = link_info->dev_hdls[i]; + if (link_info->version == VERSION_1) + dev->dev_hdl = link_info->u.link_info_v1.dev_hdls[i]; + else if (link_info->version == VERSION_2) + dev->dev_hdl = link_info->u.link_info_v2.dev_hdls[i]; dev->parent = (void *)link; dev->dev_info.dev_hdl = dev->dev_hdl; rc = dev->ops->get_dev_info(&dev->dev_info); trace_cam_req_mgr_connect_device(link, &dev->dev_info); - - CAM_DBG(CAM_CRM, - "%x: connected: %s, id %d, delay %d, trigger %x", - link_info->session_hdl, dev->dev_info.name, - dev->dev_info.dev_id, dev->dev_info.p_delay, - dev->dev_info.trigger); + if (link_info->version == VERSION_1) + CAM_DBG(CAM_CRM, + "%x: connected: %s, id %d, delay %d, trigger %x", + link_info->u.link_info_v1.session_hdl, + dev->dev_info.name, + dev->dev_info.dev_id, dev->dev_info.p_delay, + dev->dev_info.trigger); + else if (link_info->version == VERSION_2) + CAM_DBG(CAM_CRM, + "%x: connected: %s, id %d, delay %d, trigger %x", + link_info->u.link_info_v2.session_hdl, + dev->dev_info.name, + dev->dev_info.dev_id, dev->dev_info.p_delay, + dev->dev_info.trigger); if (rc < 0 || dev->dev_info.p_delay >= CAM_PIPELINE_DELAY_MAX || @@ -2412,10 +2477,18 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, CAM_ERR(CAM_CRM, "get device info failed"); goto error; } else { - CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d", - link_info->session_hdl, - dev->dev_info.name, - dev->dev_info.p_delay); + if (link_info->version == VERSION_1) { + CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d", + link_info->u.link_info_v1.session_hdl, + dev->dev_info.name, + dev->dev_info.p_delay); + } + else if (link_info->version == VERSION_2) { + CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d", + link_info->u.link_info_v2.session_hdl, + dev->dev_info.name, + dev->dev_info.p_delay); + } if (dev->dev_info.p_delay > max_delay) max_delay = dev->dev_info.p_delay; @@ -2430,7 +2503,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, link_data.max_delay = max_delay; link_data.subscribe_event = subscribe_event; - for (i = 0; i < link_info->num_devices; i++) { + for (i = 0; i < num_devices; i++) { dev = &link->l_dev[i]; link_data.dev_hdl = dev->dev_hdl; @@ -2473,7 +2546,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, if (link->max_delay < dev->dev_info.p_delay) link->max_delay = dev->dev_info.p_delay; } - link->num_devs = link_info->num_devices; + link->num_devs = num_devices; /* Assign id for pd tables */ __cam_req_mgr_tbl_set_id(link->req.l_tbl, &link->req); @@ -2631,7 +2704,115 @@ int cam_req_mgr_destroy_session( return rc; } -int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) +int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info) +{ + int rc = 0; + int wq_flag = 0; + char buf[128]; + struct cam_create_dev_hdl root_dev; + struct cam_req_mgr_core_session *cam_session; + struct cam_req_mgr_core_link *link; + + if (!link_info) { + CAM_DBG(CAM_CRM, "NULL pointer"); + return -EINVAL; + } + if (link_info->u.link_info_v1.num_devices > CAM_REQ_MGR_MAX_HANDLES) { + CAM_ERR(CAM_CRM, "Invalid num devices %d", + link_info->u.link_info_v1.num_devices); + return -EINVAL; + } + + mutex_lock(&g_crm_core_dev->crm_lock); + + /* session hdl's priv data is cam session struct */ + cam_session = (struct cam_req_mgr_core_session *) + cam_get_device_priv(link_info->u.link_info_v1.session_hdl); + if (!cam_session) { + CAM_DBG(CAM_CRM, "NULL pointer"); + mutex_unlock(&g_crm_core_dev->crm_lock); + return -EINVAL; + } + + /* Allocate link struct and map it with session's request queue */ + link = __cam_req_mgr_reserve_link(cam_session); + if (!link) { + CAM_ERR(CAM_CRM, "failed to reserve new link"); + mutex_unlock(&g_crm_core_dev->crm_lock); + return -EINVAL; + } + CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl); + + memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl)); + root_dev.session_hdl = link_info->u.link_info_v1.session_hdl; + root_dev.priv = (void *)link; + root_dev.dev_id = CAM_CRM; + mutex_lock(&link->lock); + /* Create unique dev handle for link */ + link->link_hdl = cam_create_device_hdl(&root_dev); + if (link->link_hdl < 0) { + CAM_ERR(CAM_CRM, + "Insufficient memory to create new device handle"); + rc = link->link_hdl; + goto link_hdl_fail; + } + link_info->u.link_info_v1.link_hdl = link->link_hdl; + link->last_flush_id = 0; + + /* Allocate memory to hold data of all linked devs */ + rc = __cam_req_mgr_create_subdevs(&link->l_dev, + link_info->u.link_info_v1.num_devices); + if (rc < 0) { + CAM_ERR(CAM_CRM, + "Insufficient memory to create new crm subdevs"); + goto create_subdev_failed; + } + + /* Using device ops query connected devs, prepare request tables */ + rc = __cam_req_mgr_setup_link_info(link, link_info); + if (rc < 0) + goto setup_failed; + + spin_lock_bh(&link->link_state_spin_lock); + link->state = CAM_CRM_LINK_STATE_READY; + spin_unlock_bh(&link->link_state_spin_lock); + + /* Create worker for current link */ + snprintf(buf, sizeof(buf), "%x-%x", + link_info->u.link_info_v1.session_hdl, link->link_hdl); + wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL; + rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS, + &link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag); + if (rc < 0) { + CAM_ERR(CAM_CRM, "FATAL: unable to create worker"); + __cam_req_mgr_destroy_link_info(link); + goto setup_failed; + } + + /* Assign payload to workqueue tasks */ + rc = __cam_req_mgr_setup_payload(link->workq); + if (rc < 0) { + __cam_req_mgr_destroy_link_info(link); + cam_req_mgr_workq_destroy(&link->workq); + goto setup_failed; + } + + mutex_unlock(&link->lock); + mutex_unlock(&g_crm_core_dev->crm_lock); + return rc; +setup_failed: + __cam_req_mgr_destroy_subdev(link->l_dev); +create_subdev_failed: + cam_destroy_device_hdl(link->link_hdl); + link_info->u.link_info_v1.link_hdl = -1; +link_hdl_fail: + mutex_unlock(&link->lock); + __cam_req_mgr_unreserve_link(cam_session, link); + mutex_unlock(&g_crm_core_dev->crm_lock); + return rc; +} + +int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info) { int rc = 0; int wq_flag = 0; @@ -2644,9 +2825,10 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) CAM_DBG(CAM_CRM, "NULL pointer"); return -EINVAL; } - if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES) { + if (link_info->u.link_info_v2.num_devices > + CAM_REQ_MGR_MAX_HANDLES_V2) { CAM_ERR(CAM_CRM, "Invalid num devices %d", - link_info->num_devices); + link_info->u.link_info_v2.num_devices); return -EINVAL; } @@ -2654,7 +2836,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) /* session hdl's priv data is cam session struct */ cam_session = (struct cam_req_mgr_core_session *) - cam_get_device_priv(link_info->session_hdl); + cam_get_device_priv(link_info->u.link_info_v2.session_hdl); if (!cam_session) { CAM_DBG(CAM_CRM, "NULL pointer"); mutex_unlock(&g_crm_core_dev->crm_lock); @@ -2671,7 +2853,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl); memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl)); - root_dev.session_hdl = link_info->session_hdl; + root_dev.session_hdl = link_info->u.link_info_v2.session_hdl; root_dev.priv = (void *)link; mutex_lock(&link->lock); @@ -2683,12 +2865,12 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) rc = link->link_hdl; goto link_hdl_fail; } - link_info->link_hdl = link->link_hdl; + link_info->u.link_info_v2.link_hdl = link->link_hdl; link->last_flush_id = 0; /* Allocate memory to hold data of all linked devs */ rc = __cam_req_mgr_create_subdevs(&link->l_dev, - link_info->num_devices); + link_info->u.link_info_v2.num_devices); if (rc < 0) { CAM_ERR(CAM_CRM, "Insufficient memory to create new crm subdevs"); @@ -2706,7 +2888,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) /* Create worker for current link */ snprintf(buf, sizeof(buf), "%x-%x", - link_info->session_hdl, link->link_hdl); + link_info->u.link_info_v2.session_hdl, link->link_hdl); wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL; rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS, &link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag); @@ -2731,7 +2913,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) __cam_req_mgr_destroy_subdev(link->l_dev); create_subdev_failed: cam_destroy_device_hdl(link->link_hdl); - link_info->link_hdl = -1; + link_info->u.link_info_v2.link_hdl = -1; link_hdl_fail: mutex_unlock(&link->lock); __cam_req_mgr_unreserve_link(cam_session, link); @@ -2739,6 +2921,7 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info) return rc; } + int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info) { int rc = 0; diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h index 9bff66b36ebb..05fe0860bfa0 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h @@ -36,6 +36,9 @@ #define MAXIMUM_LINKS_PER_SESSION 4 +#define VERSION_1 1 +#define VERSION_2 2 + /** * enum crm_workq_task_type * @codes: to identify which type of task is present @@ -233,12 +236,14 @@ struct cam_req_mgr_slot { * @slot : request slot holding incoming request id and bubble info. * @rd_idx : indicates slot index currently in process. * @wr_idx : indicates slot index to hold new upcoming req. + * @last_applied_idx : indicates slot index last applied successfully. */ struct cam_req_mgr_req_queue { int32_t num_slots; struct cam_req_mgr_slot slot[MAX_REQ_SLOTS]; int32_t rd_idx; int32_t wr_idx; + int32_t last_applied_idx; }; /** @@ -411,7 +416,9 @@ int cam_req_mgr_destroy_session(struct cam_req_mgr_session_info *ses_info); * a unique link handle for the link and is specific to a * session. Returns link handle */ -int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info); +int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info); +int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info); + /** * cam_req_mgr_unlink() diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c index 5cf1d844f5e2..31607ac6391f 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -268,27 +268,50 @@ static long cam_private_ioctl(struct file *file, void *fh, break; case CAM_REQ_MGR_LINK: { - struct cam_req_mgr_link_info link_info; + struct cam_req_mgr_ver_info ver_info; - if (k_ioctl->size != sizeof(link_info)) + if (k_ioctl->size != sizeof(ver_info.u.link_info_v1)) return -EINVAL; - if (copy_from_user(&link_info, + if (copy_from_user(&ver_info.u.link_info_v1, u64_to_user_ptr(k_ioctl->handle), sizeof(struct cam_req_mgr_link_info))) { return -EFAULT; } - - rc = cam_req_mgr_link(&link_info); + ver_info.version = VERSION_1; + rc = cam_req_mgr_link(&ver_info); if (!rc) if (copy_to_user( u64_to_user_ptr(k_ioctl->handle), - &link_info, + &ver_info.u.link_info_v1, sizeof(struct cam_req_mgr_link_info))) rc = -EFAULT; } break; + case CAM_REQ_MGR_LINK_V2: { + struct cam_req_mgr_ver_info ver_info; + + if (k_ioctl->size != sizeof(ver_info.u.link_info_v2)) + return -EINVAL; + + if (copy_from_user(&ver_info.u.link_info_v2, + u64_to_user_ptr(k_ioctl->handle), + sizeof(struct cam_req_mgr_link_info_v2))) { + return -EFAULT; + } + ver_info.version = VERSION_2; + rc = cam_req_mgr_link_v2(&ver_info); + if (!rc) + if (copy_to_user( + u64_to_user_ptr(k_ioctl->handle), + &ver_info.u.link_info_v2, + sizeof(struct + cam_req_mgr_link_info_v2))) + rc = -EFAULT; + } + break; + case CAM_REQ_MGR_UNLINK: { struct cam_req_mgr_unlink_info unlink_info; diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c index dda04f8e5164..d531fdcf388b 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -128,6 +128,21 @@ static int32_t cam_get_free_handle_index(void) return idx; } +void cam_dump_tbl_info(void) +{ + int i; + + for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES; i++) + CAM_INFO(CAM_CRM, "session_hdl=%x hdl_value=%x\n" + "type=%d state=%d dev_id=%lld", + hdl_tbl->hdl[i].session_hdl, + hdl_tbl->hdl[i].hdl_value, + hdl_tbl->hdl[i].type, + hdl_tbl->hdl[i].state, + hdl_tbl->hdl[i].dev_id); + +} + int32_t cam_create_session_hdl(void *priv) { int idx; @@ -144,6 +159,7 @@ int32_t cam_create_session_hdl(void *priv) idx = cam_get_free_handle_index(); if (idx < 0) { CAM_ERR(CAM_CRM, "Unable to create session handle"); + cam_dump_tbl_info(); spin_unlock_bh(&hdl_tbl_lock); return idx; } @@ -177,6 +193,7 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) idx = cam_get_free_handle_index(); if (idx < 0) { CAM_ERR(CAM_CRM, "Unable to create device handle"); + cam_dump_tbl_info(); spin_unlock_bh(&hdl_tbl_lock); return idx; } @@ -189,6 +206,7 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) hdl_tbl->hdl[idx].state = HDL_ACTIVE; hdl_tbl->hdl[idx].priv = hdl_data->priv; hdl_tbl->hdl[idx].ops = hdl_data->ops; + hdl_tbl->hdl[idx].dev_id = hdl_data->dev_id; spin_unlock_bh(&hdl_tbl_lock); pr_debug("%s: handle = %x", __func__, handle); diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h index 7b8e3e601ed8..50d6f309da15 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -50,6 +50,7 @@ struct handle { uint32_t hdl_value; enum hdl_type type; enum hdl_state state; + uint64_t dev_id; void *ops; void *priv; }; @@ -80,6 +81,7 @@ struct cam_create_dev_hdl { int32_t v4l2_sub_dev_flag; int32_t media_entity_flag; int32_t reserved; + uint64_t dev_id; void *ops; void *priv; }; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c index 1262db7646dc..3837aac6a2e5 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -786,7 +786,7 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = a_ctrl; - + bridge_params.dev_id = CAM_ACTUATOR; actuator_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c index f41cb4753f39..a06a4c6c6339 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c @@ -1094,7 +1094,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, * RD_DONE exclusively. */ rem_jiffies = wait_for_completion_timeout( - &cci_dev->cci_master_info[master].reset_complete, + &cci_dev->cci_master_info[master].rd_done, CCI_TIMEOUT); if (!rem_jiffies) { rc = -ETIMEDOUT; @@ -1275,10 +1275,11 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, val = 1 << ((master * 2) + queue); cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR); CAM_DBG(CAM_CCI, - "waiting_for_rd_done [exp_words: %d]", exp_words); + "waiting_for_rd_done [exp_words: %d]", + ((read_cfg->num_byte / 4) + 1)); rc = wait_for_completion_timeout( - &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); + &cci_dev->cci_master_info[master].rd_done, CCI_TIMEOUT); if (rc <= 0) { #ifdef DUMP_CCI_REGISTERS cam_cci_dump_registers(cci_dev, master, queue); @@ -1692,14 +1693,19 @@ int32_t cam_cci_core_cfg(struct v4l2_subdev *sd, struct cam_cci_ctrl *cci_ctrl) { int32_t rc = 0; - + struct cci_device *cci_dev = v4l2_get_subdevdata(sd); CAM_DBG(CAM_CCI, "cmd %d", cci_ctrl->cmd); + switch (cci_ctrl->cmd) { case MSM_CCI_INIT: + mutex_lock(&cci_dev->init_mutex); rc = cam_cci_init(sd, cci_ctrl); + mutex_unlock(&cci_dev->init_mutex); break; case MSM_CCI_RELEASE: + mutex_lock(&cci_dev->init_mutex); rc = cam_cci_release(sd); + mutex_unlock(&cci_dev->init_mutex); break; case MSM_CCI_I2C_READ: rc = cam_cci_read_bytes(sd, cci_ctrl); diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c index 7934aa50767c..69b5af002610 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c @@ -71,20 +71,26 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) irq_status0 = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR); irq_status1 = cam_io_r_mb(base + CCI_IRQ_STATUS_1_ADDR); + CAM_DBG(CAM_CCI, "BASE: %pK", base); CAM_DBG(CAM_CCI, "irq0:%x irq1:%x", irq_status0, irq_status1); if (irq_status0 & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) { + struct cam_cci_master_info *cci_master_info; if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) { + cci_master_info = &cci_dev->cci_master_info[MASTER_0]; cci_dev->cci_master_info[MASTER_0].reset_pending = FALSE; - complete( - &cci_dev->cci_master_info[MASTER_0].reset_complete); + if (!cci_master_info->status) + complete(&cci_master_info->reset_complete); + cci_master_info->status = 0; } if (cci_dev->cci_master_info[MASTER_1].reset_pending == TRUE) { + cci_master_info = &cci_dev->cci_master_info[MASTER_1]; cci_dev->cci_master_info[MASTER_1].reset_pending = FALSE; - complete( - &cci_dev->cci_master_info[MASTER_1].reset_complete); + if (!cci_master_info->status) + complete(&cci_master_info->reset_complete); + cci_master_info->status = 0; } } @@ -93,7 +99,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) cci_dev->cci_master_info[MASTER_0].status = 0; rd_done_th_assert = true; complete(&cci_dev->cci_master_info[MASTER_0].th_complete); - complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); + complete(&cci_dev->cci_master_info[MASTER_0].rd_done); } if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) && (!rd_done_th_assert)) { @@ -102,7 +108,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) if (cci_dev->is_burst_read) complete( &cci_dev->cci_master_info[MASTER_0].th_complete); - complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); + complete(&cci_dev->cci_master_info[MASTER_0].rd_done); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) && (!rd_done_th_assert)) { @@ -149,7 +155,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) cci_dev->cci_master_info[MASTER_1].status = 0; rd_done_th_assert = true; complete(&cci_dev->cci_master_info[MASTER_1].th_complete); - complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); + complete(&cci_dev->cci_master_info[MASTER_1].rd_done); } if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) && (!rd_done_th_assert)) { @@ -158,7 +164,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) if (cci_dev->is_burst_read) complete( &cci_dev->cci_master_info[MASTER_1].th_complete); - complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); + complete(&cci_dev->cci_master_info[MASTER_1].rd_done); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) && (!rd_done_th_assert)) { @@ -217,16 +223,33 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) { cci_dev->cci_master_info[MASTER_0].status = -EINVAL; - cam_io_w_mb(CCI_M0_HALT_REQ_RMSK, - base + CCI_HALT_REQ_ADDR); - CAM_DBG(CAM_CCI, "MASTER_0 error 0x%x", irq_status0); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK) + CAM_ERR(CAM_CCI, "Base:%pK, M0 NACK ERROR: 0x%x", + base, irq_status0); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK) + CAM_ERR(CAM_CCI, + "Base:%pK, M0 QUEUE_OVER/UNDER_FLOW OR CMD ERR: 0x%x", + base, irq_status0); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK) + CAM_ERR(CAM_CCI, + "Base: %pK, M0 RD_OVER/UNDER_FLOW ERROR: 0x%x", + base, irq_status0); + cam_io_w_mb(CCI_M0_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR); } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) { cci_dev->cci_master_info[MASTER_1].status = -EINVAL; - cam_io_w_mb(CCI_M1_HALT_REQ_RMSK, - base + CCI_HALT_REQ_ADDR); - CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq_status0); - + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK) + CAM_ERR(CAM_CCI, "Base:%pK, M1 NACK ERROR: 0x%x", + base, irq_status0); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK) + CAM_ERR(CAM_CCI, + "Base:%pK, M1 QUEUE_OVER_UNDER_FLOW OR CMD ERROR:0x%x", + base, irq_status0); + if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK) + CAM_ERR(CAM_CCI, + "Base:%pK, M1 RD_OVER/UNDER_FLOW ERROR: 0x%x", + base, irq_status0); + cam_io_w_mb(CCI_M1_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR); } cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR); @@ -402,7 +425,8 @@ static int cam_cci_platform_probe(struct platform_device *pdev) } g_cci_subdev[soc_info->index] = &new_cci_dev->v4l2_dev_str.sd; - CAM_ERR(CAM_CCI, "Device Type :%d", soc_info->index); + mutex_init(&(new_cci_dev->init_mutex)); + CAM_INFO(CAM_CCI, "Device Type :%d", soc_info->index); cam_register_subdev_fops(&cci_v4l2_subdev_fops); cci_v4l2_subdev_fops.unlocked_ioctl = cam_cci_subdev_fops_ioctl; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h index 349effcc057b..54eed834be07 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h @@ -140,6 +140,7 @@ struct cam_cci_master_info { uint8_t reset_pending; struct mutex mutex; struct completion reset_complete; + struct completion rd_done; struct completion th_complete; struct mutex mutex_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; @@ -171,41 +172,41 @@ enum cam_cci_state_t { }; /** - * struct cci_device - * @pdev: Platform device - * @subdev: V4L2 sub device - * @base: Base address of CCI device - * @hw_version: Hardware version - * @ref_count: Reference Count - * @cci_state: CCI state machine - * @num_clk: Number of CCI clock - * @cci_clk: CCI clock structure - * @cci_clk_info: CCI clock information - * @cam_cci_i2c_queue_info: CCI queue information - * @i2c_freq_mode: I2C frequency of operations - * @cci_clk_params: CCI hw clk params - * @cci_gpio_tbl: CCI GPIO table - * @cci_gpio_tbl_size: GPIO table size - * @cci_pinctrl: Pinctrl structure - * @cci_pinctrl_status: CCI pinctrl status - * @cci_clk_src: CCI clk src rate - * @cci_vreg: CCI regulator structure - * @cci_reg_ptr: CCI individual regulator structure - * @regulator_count: Regulator count - * @support_seq_write: - * Set this flag when sequential write is enabled - * @write_wq: Work queue structure - * @valid_sync: Is it a valid sync with CSID - * @v4l2_dev_str: V4L2 device structure - * @cci_wait_sync_cfg: CCI sync config - * @cycles_per_us: Cycles per micro sec - * @payload_size: CCI packet payload size - * @irq_status1: Store irq_status1 to be cleared after - * draining FIFO buffer for burst read - * @lock_status: to protect changes to irq_status1 - * @is_burst_read: Flag to determine if we are performing - * a burst read operation or not - * @irqs_disabled: Mask for IRQs that are disabled + * @pdev: Platform device + * @subdev: V4L2 sub device + * @base: Base address of CCI device + * @hw_version: Hardware version + * @ref_count: Reference Count + * @cci_state: CCI state machine + * @num_clk: Number of CCI clock + * @cci_clk: CCI clock structure + * @cci_clk_info: CCI clock information + * @cam_cci_i2c_queue_info: CCI queue information + * @i2c_freq_mode: I2C frequency of operations + * @cci_clk_params: CCI hw clk params + * @cci_gpio_tbl: CCI GPIO table + * @cci_gpio_tbl_size: GPIO table size + * @cci_pinctrl: Pinctrl structure + * @cci_pinctrl_status: CCI pinctrl status + * @cci_clk_src: CCI clk src rate + * @cci_vreg: CCI regulator structure + * @cci_reg_ptr: CCI individual regulator structure + * @regulator_count: Regulator count + * @support_seq_write: Set this flag when sequential write is enabled + * @write_wq: Work queue structure + * @valid_sync: Is it a valid sync with CSID + * @v4l2_dev_str: V4L2 device structure + * @cci_wait_sync_cfg: CCI sync config + * @cycles_per_us: Cycles per micro sec + * @payload_size: CCI packet payload size + * @irq_status1: Store irq_status1 to be cleared after + * draining FIFO buffer for burst read + * @lock_status: to protect changes to irq_status1 + * @is_burst_read: Flag to determine if we are performing + * a burst read operation or not + * @irqs_disabled: Mask for IRQs that are disabled + * @init_mutex: Mutex for maintaining refcount for attached + * devices to cci during init/deinit. */ struct cci_device { struct v4l2_subdev subdev; @@ -234,6 +235,7 @@ struct cci_device { spinlock_t lock_status; bool is_burst_read; uint32_t irqs_disabled; + struct mutex init_mutex; }; enum cam_cci_i2c_cmd_type { diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h index 027a0501dcae..ead18afc77ad 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2015, 2017-2019, 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 @@ -61,6 +61,12 @@ #define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK 0x10 #define CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK 0x18000EE6 #define CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK 0x60EE6000 +#define CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK 0x18000000 +#define CCI_IRQ_STATUS_0_I2C_M1_NACK_ERROR_BMSK 0x60000000 +#define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK 0xEE0 +#define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_ERROR_BMSK 0xEE0000 +#define CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK 0x6 +#define CCI_IRQ_STATUS_0_I2C_M1_RD_ERROR_BMSK 0x6000 #define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK 0x1 #define CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD 0x10000 #define CCI_IRQ_STATUS_1_I2C_M0_RD_PAUSE 0x20000 diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c index fa290c0b982c..0181a4d8e2ff 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c @@ -19,7 +19,7 @@ int cam_cci_init(struct v4l2_subdev *sd, uint8_t i = 0, j = 0; int32_t rc = 0; struct cci_device *cci_dev; - enum cci_i2c_master_t master = MASTER_0; + enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master; struct cam_ahb_vote ahb_vote; struct cam_axi_vote axi_vote; struct cam_hw_soc_info *soc_info = NULL; @@ -47,7 +47,6 @@ int cam_cci_init(struct v4l2_subdev *sd, if (cci_dev->ref_count++) { CAM_DBG(CAM_CCI, "ref_count %d", cci_dev->ref_count); - master = c_ctrl->cci_info->cci_i2c_master; CAM_DBG(CAM_CCI, "master %d", master); if (master < MASTER_MAX && master >= 0) { mutex_lock(&cci_dev->cci_master_info[master].mutex); @@ -55,6 +54,8 @@ int cam_cci_init(struct v4l2_subdev *sd, /* Re-initialize the completion */ reinit_completion( &cci_dev->cci_master_info[master].reset_complete); + reinit_completion( + &cci_dev->cci_master_info[master].rd_done); for (i = 0; i < NUM_QUEUES; i++) reinit_completion( &cci_dev->cci_master_info[master].report_q[i]); @@ -93,6 +94,7 @@ int cam_cci_init(struct v4l2_subdev *sd, /* Re-initialize the completion */ reinit_completion(&cci_dev->cci_master_info[master].reset_complete); + reinit_completion(&cci_dev->cci_master_info[master].rd_done); for (i = 0; i < NUM_QUEUES; i++) reinit_completion( &cci_dev->cci_master_info[master].report_q[i]); @@ -128,12 +130,12 @@ int cam_cci_init(struct v4l2_subdev *sd, } } - cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; + cci_dev->cci_master_info[master].reset_pending = TRUE; cam_io_w_mb(CCI_RESET_CMD_RMSK, base + CCI_RESET_CMD_ADDR); cam_io_w_mb(0x1, base + CCI_RESET_CMD_ADDR); rc = wait_for_completion_timeout( - &cci_dev->cci_master_info[MASTER_0].reset_complete, + &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); if (rc <= 0) { CAM_ERR(CAM_CCI, "wait_for_completion_timeout"); @@ -205,6 +207,8 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) &new_cci_dev->cci_master_info[i].reset_complete); init_completion( &new_cci_dev->cci_master_info[i].th_complete); + init_completion( + &new_cci_dev->cci_master_info[i].rd_done); for (j = 0; j < NUM_QUEUES; j++) { mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index 318ea555e98c..8074ecd9112a 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -725,7 +725,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = csiphy_dev; - + bridge_params.dev_id = CAM_CSIPHY; if (csiphy_acq_params.combo_mode >= 2) { CAM_ERR(CAM_CSIPHY, "Invalid combo_mode %d", csiphy_acq_params.combo_mode); diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h index 67653e81fde1..edde07091d9e 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h @@ -21,7 +21,7 @@ struct csiphy_reg_parms_t csiphy_v1_2 = { .mipi_csiphy_glbl_irq_cmd_addr = 0x828, .csiphy_common_array_size = 6, .csiphy_reset_array_size = 5, - .csiphy_2ph_config_array_size = 21, + .csiphy_2ph_config_array_size = 22, .csiphy_3ph_config_array_size = 38, .csiphy_2ph_clock_lane = 0x1, .csiphy_2ph_combo_ck_ln = 0x10, @@ -78,10 +78,11 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0008, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -105,6 +106,7 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -128,6 +130,7 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -151,6 +154,7 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, { {0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -174,6 +178,7 @@ csiphy_reg_t csiphy_2ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = { {0x060c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, }, }; @@ -197,10 +202,11 @@ struct csiphy_reg_t {0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0008, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -224,6 +230,7 @@ struct csiphy_reg_t {0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -247,6 +254,7 @@ struct csiphy_reg_t {0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -270,6 +278,7 @@ struct csiphy_reg_t {0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, { {0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -293,6 +302,7 @@ struct csiphy_reg_t {0x060c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS}, }, }; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index a04d97143592..8f59ca36d5d8 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -357,7 +357,7 @@ static int32_t cam_eeprom_get_dev_handle(struct cam_eeprom_ctrl_t *e_ctrl, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = e_ctrl; - + bridge_params.dev_id = CAM_EEPROM; eeprom_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h index 7ffafc377da6..9c36134a1b8f 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h @@ -35,7 +35,7 @@ #define PROPERTY_MAXSIZE 32 #define MSM_EEPROM_MEMORY_MAP_MAX_SIZE 80 -#define MSM_EEPROM_MAX_MEM_MAP_CNT 8 +#define MSM_EEPROM_MAX_MEM_MAP_CNT 16 #define MSM_EEPROM_MEM_MAP_PROPERTIES_CNT 8 enum cam_eeprom_state { diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c index 1a0edb8d4d02..f4c9d254df7c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -71,7 +71,7 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = fctrl; - + bridge_params.dev_id = CAM_FLASH; flash_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); fctrl->bridge_intf.device_hdl = diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c index a5c7039cc2da..711077cdfdf8 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c @@ -90,7 +90,7 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = o_ctrl; - + bridge_params.dev_id = CAM_OIS; ois_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c index 111f121757c1..a2a738d85714 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -776,7 +776,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = s_ctrl; - + bridge_params.dev_id = CAM_SENSOR; sensor_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle; diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c index d3f62d6a3e20..d4487efbf090 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c +++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c @@ -29,6 +29,20 @@ struct sync_device *sync_dev; */ static bool trigger_cb_without_switch; +void cam_sync_print_fence_table(void) +{ + int cnt; + + for (cnt = 0; cnt < CAM_SYNC_MAX_OBJS; cnt++) { + CAM_INFO(CAM_SYNC, "%d, %s, %d, %d, %d", + sync_dev->sync_table[cnt].sync_id, + sync_dev->sync_table[cnt].name, + sync_dev->sync_table[cnt].type, + sync_dev->sync_table[cnt].state, + atomic_read(&sync_dev->sync_table[cnt].ref_cnt)); + } +} + int cam_sync_create(int32_t *sync_obj, const char *name) { int rc; @@ -37,8 +51,15 @@ int cam_sync_create(int32_t *sync_obj, const char *name) do { idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS); - if (idx >= CAM_SYNC_MAX_OBJS) + if (idx >= CAM_SYNC_MAX_OBJS) { + CAM_ERR(CAM_SYNC, + "Error: Unable to Create Sync Idx = %ld Reached Max!!", + idx); + sync_dev->err_cnt++; + if (sync_dev->err_cnt == 1) + cam_sync_print_fence_table(); return -ENOMEM; + } CAM_DBG(CAM_SYNC, "Index location available at idx: %ld", idx); bit = test_and_set_bit(idx, sync_dev->bitmap); } while (bit); @@ -765,6 +786,7 @@ static int cam_sync_open(struct file *filep) CAM_ERR(CAM_SYNC, "Sync device NULL"); return -ENODEV; } + sync_dev->err_cnt = 0; mutex_lock(&sync_dev->table_lock); if (sync_dev->open_cnt >= 1) { @@ -797,6 +819,7 @@ static int cam_sync_close(struct file *filep) rc = -ENODEV; return rc; } + sync_dev->err_cnt = 0; mutex_lock(&sync_dev->table_lock); sync_dev->open_cnt--; if (!sync_dev->open_cnt) { @@ -972,6 +995,7 @@ static int cam_sync_probe(struct platform_device *pdev) if (!sync_dev) return -ENOMEM; + sync_dev->err_cnt = 0; mutex_init(&sync_dev->table_lock); spin_lock_init(&sync_dev->cam_sync_eventq_lock); diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h index eb2fb34fc33c..c3cb345a13fa 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h +++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -184,6 +184,7 @@ struct cam_signalable_info { * @work_queue : Work queue used for dispatching kernel callbacks * @cam_sync_eventq : Event queue used to dispatch user payloads to user space * @bitmap : Bitmap representation of all sync objects + * @err_cnt : Error counter to dump fence table */ struct sync_device { struct video_device *vdev; @@ -197,6 +198,7 @@ struct sync_device { struct v4l2_fh *cam_sync_eventq; spinlock_t cam_sync_eventq_lock; DECLARE_BITMAP(bitmap, CAM_SYNC_MAX_OBJS); + int err_cnt; }; diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c index f3af61936625..36e6e1ca5410 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c @@ -77,7 +77,7 @@ static char supported_clk_info[256]; static char debugfs_dir_name[64]; static int cam_soc_util_get_clk_level(struct cam_hw_soc_info *soc_info, - int32_t src_clk_idx, int32_t clk_rate) + int32_t src_clk_idx, int64_t clk_rate) { int i; long clk_rate_round; @@ -92,7 +92,7 @@ static int cam_soc_util_get_clk_level(struct cam_hw_soc_info *soc_info, for (i = 0; i < CAM_MAX_VOTE; i++) { if (soc_info->clk_rate[i][src_clk_idx] >= clk_rate_round) { CAM_DBG(CAM_UTIL, - "soc = %d round rate = %ld actual = %d", + "soc = %d round rate = %ld actual = %lld", soc_info->clk_rate[i][src_clk_idx], clk_rate_round, clk_rate); return i; @@ -441,7 +441,7 @@ int cam_soc_util_set_clk_flags(struct cam_hw_soc_info *soc_info, * @return: Success or failure */ static int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name, - int32_t clk_rate) + int64_t clk_rate) { int rc = 0; long clk_rate_round; @@ -449,7 +449,7 @@ static int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name, if (!clk || !clk_name) return -EINVAL; - CAM_DBG(CAM_UTIL, "set %s, rate %d", clk_name, clk_rate); + CAM_DBG(CAM_UTIL, "set %s, rate %lld", clk_name, clk_rate); if (clk_rate > 0) { clk_rate_round = clk_round_rate(clk, clk_rate); CAM_DBG(CAM_UTIL, "new_rate %ld", clk_rate_round); @@ -485,7 +485,7 @@ static int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name, } int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info, - int32_t clk_rate) + int64_t clk_rate) { int32_t src_clk_idx; struct clk *clk = NULL; @@ -506,7 +506,7 @@ int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info, if (soc_info->cam_cx_ipeak_enable && clk_rate >= 0) { apply_level = cam_soc_util_get_clk_level(soc_info, src_clk_idx, clk_rate); - CAM_DBG(CAM_UTIL, "set %s, rate %d dev_name = %s\n" + CAM_DBG(CAM_UTIL, "set %s, rate %lld dev_name = %s\n" "apply level = %d", soc_info->clk_name[src_clk_idx], clk_rate, soc_info->dev_name, apply_level); diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h index ee07f0eb0a5d..859fee7dfd8c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h @@ -397,7 +397,7 @@ int cam_soc_util_set_clk_flags(struct cam_hw_soc_info *soc_info, * @return: success or failure */ int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info, - int32_t clk_rate); + int64_t clk_rate); /** * cam_soc_util_get_option_clk_by_name() diff --git a/include/uapi/media/cam_cpas.h b/include/uapi/media/cam_cpas.h index c5cbac82e71b..371b74c74500 100644 --- a/include/uapi/media/cam_cpas.h +++ b/include/uapi/media/cam_cpas.h @@ -6,6 +6,40 @@ #define CAM_FAMILY_CAMERA_SS 1 #define CAM_FAMILY_CPAS_SS 2 +/* AXI BW Voting Version */ +#define CAM_AXI_BW_VOTING_V2 2 + +/* AXI BW Voting Transaction Type */ +#define CAM_AXI_TRANSACTION_READ 0 +#define CAM_AXI_TRANSACTION_WRITE 1 + +/* AXI BW Voting Path Data Type */ +#define CAM_AXI_PATH_DATA_IFE_START_OFFSET 0 +#define CAM_AXI_PATH_DATA_IFE_LINEAR (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 0) +#define CAM_AXI_PATH_DATA_IFE_VID (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 1) +#define CAM_AXI_PATH_DATA_IFE_DISP (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 2) +#define CAM_AXI_PATH_DATA_IFE_STATS (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 3) +#define CAM_AXI_PATH_DATA_IFE_RDI0 (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 4) +#define CAM_AXI_PATH_DATA_IFE_RDI1 (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 5) +#define CAM_AXI_PATH_DATA_IFE_RDI2 (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 6) +#define CAM_AXI_PATH_DATA_IFE_RDI3 (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 7) +#define CAM_AXI_PATH_DATA_IFE_PDAF (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 8) +#define CAM_AXI_PATH_DATA_IFE_PIXEL_RAW \ + (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 9) +#define CAM_AXI_PATH_DATA_IFE_MAX_OFFSET \ + (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 31) + +#define CAM_AXI_PATH_DATA_IPE_START_OFFSET 32 +#define CAM_AXI_PATH_DATA_IPE_RD_IN (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 0) +#define CAM_AXI_PATH_DATA_IPE_RD_REF (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 1) +#define CAM_AXI_PATH_DATA_IPE_WR_VID (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 2) +#define CAM_AXI_PATH_DATA_IPE_WR_DISP (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 3) +#define CAM_AXI_PATH_DATA_IPE_WR_REF (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 4) +#define CAM_AXI_PATH_DATA_IPE_MAX_OFFSET \ + (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 31) + +#define CAM_AXI_PATH_DATA_ALL 256 + /** * struct cam_cpas_query_cap - CPAS query device capability payload * @@ -22,4 +56,29 @@ struct cam_cpas_query_cap { struct cam_hw_version cpas_version; }; +/** + * struct cam_axi_per_path_bw_vote - Per path bandwidth vote information + * + * @usage_data client usage data (left/right/rdi) + * @transac_type Transaction type on the path (read/write) + * @path_data_type Path for which vote is given (video, display, rdi) + * @reserved Reserved for alignment + * @camnoc_bw CAMNOC bw for this path + * @mnoc_ab_bw MNOC AB bw for this path + * @mnoc_ib_bw MNOC IB bw for this path + * @ddr_ab_bw DDR AB bw for this path + * @ddr_ib_bw DDR IB bw for this path + */ +struct cam_axi_per_path_bw_vote { + uint32_t usage_data; + uint32_t transac_type; + uint32_t path_data_type; + uint32_t reserved; + uint64_t camnoc_bw; + uint64_t mnoc_ab_bw; + uint64_t mnoc_ib_bw; + uint64_t ddr_ab_bw; + uint64_t ddr_ib_bw; +}; + #endif /* __UAPI_CAM_CPAS_H__ */ diff --git a/include/uapi/media/cam_icp.h b/include/uapi/media/cam_icp.h index f2c1c91692d4..5b4a6045d9ce 100644 --- a/include/uapi/media/cam_icp.h +++ b/include/uapi/media/cam_icp.h @@ -2,6 +2,7 @@ #define __UAPI_CAM_ICP_H__ #include "cam_defs.h" +#include "cam_cpas.h" /* icp, ipe, bps, cdm(ipe/bps) are used in querycap */ #define CAM_ICP_DEV_TYPE_A5 1 @@ -66,6 +67,26 @@ #define CAM_ICP_CMD_GENERIC_BLOB_CFG_IO 0x2 #define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_MAP 0x3 #define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_UNMAP 0x4 +#define CAM_ICP_CMD_GENERIC_BLOB_CLK_V2 0x5 + +/** + * struct cam_icp_clk_bw_request_v2 + * + * @budget_ns: Time required to process frame + * @frame_cycles: Frame cycles needed to process the frame + * @rt_flag: Flag to indicate real time stream + * @reserved: For memory alignment + * @num_paths: Number of axi paths in bw request + * @axi_path: Per path vote info for IPE/BPS + */ +struct cam_icp_clk_bw_request_v2 { + uint64_t budget_ns; + uint32_t frame_cycles; + uint32_t rt_flag; + uint32_t reserved; + uint32_t num_paths; + struct cam_axi_per_path_bw_vote axi_path[1]; +}; /** * struct cam_icp_clk_bw_request diff --git a/include/uapi/media/cam_isp.h b/include/uapi/media/cam_isp.h index 995d6ec7e4b2..7489b72031b7 100644 --- a/include/uapi/media/cam_isp.h +++ b/include/uapi/media/cam_isp.h @@ -4,7 +4,7 @@ #include "cam_defs.h" #include "cam_isp_vfe.h" #include "cam_isp_ife.h" - +#include "cam_cpas.h" /* ISP driver name */ #define CAM_ISP_DEV_NAME "cam-isp" @@ -91,6 +91,13 @@ #define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 4 #define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5 #define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 6 +#define CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP 10 + +/* Per Path Usage Data */ +#define CAM_ISP_USAGE_INVALID 0 +#define CAM_ISP_USAGE_LEFT_PX 1 +#define CAM_ISP_USAGE_RIGHT_PX 2 +#define CAM_ISP_USAGE_RDI 3 /* Query devices */ /** @@ -362,7 +369,6 @@ struct cam_isp_csid_clock_config { * @cam_bw_bps: Bandwidth vote for CAMNOC * @ext_bw_bps: Bandwidth vote for path-to-DDR after CAMNOC */ - struct cam_isp_bw_vote { uint32_t resource_id; uint32_t reserved; @@ -379,7 +385,6 @@ struct cam_isp_bw_vote { * @right_pix_vote: Bandwidth vote for right ISP * @rdi_vote: RDI bandwidth requirements */ - struct cam_isp_bw_config { uint32_t usage_type; uint32_t num_rdi; @@ -407,6 +412,19 @@ struct cam_isp_bw_config_ab { uint64_t rdi_vote_ab[1]; } __attribute__((packed)); +/** + * struct cam_isp_bw_config_v2 - Bandwidth configuration + * + * @usage_type: Usage type (Single/Dual) + * @num_paths: Number of axi data paths + * @axi_path Per path vote info + */ +struct cam_isp_bw_config_v2 { + uint32_t usage_type; + uint32_t num_paths; + struct cam_axi_per_path_bw_vote axi_path[1]; +} __attribute__((packed)); + /** * struct cam_fe_config - Fetch Engine configuration * @@ -479,4 +497,14 @@ struct cam_isp_acquire_hw_info { #define CAM_ISP_ACQUIRE_OUT_VER0 0x3000 +/** + * struct cam_isp_init_frame_drop_config - init frame drop configuration + * + * @init_frame_drop: Initial number of frames needs to drop + */ + +struct cam_isp_init_frame_drop_config { + uint32_t init_frame_drop; +} __attribute__((packed)); + #endif /* __UAPI_CAM_ISP_H__ */ diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h index 5341d626e017..defed877b52d 100644 --- a/include/uapi/media/cam_req_mgr.h +++ b/include/uapi/media/cam_req_mgr.h @@ -36,6 +36,7 @@ * It includes both session and device handles */ #define CAM_REQ_MGR_MAX_HANDLES 64 +#define CAM_REQ_MGR_MAX_HANDLES_V2 128 #define MAX_LINKS_PER_SESSION 2 /* V4L event type which user space will subscribe to */ @@ -122,6 +123,20 @@ struct cam_req_mgr_link_info { int32_t link_hdl; }; +struct cam_req_mgr_link_info_v2 { + int32_t session_hdl; + uint32_t num_devices; + int32_t dev_hdls[CAM_REQ_MGR_MAX_HANDLES_V2]; + int32_t link_hdl; +}; + +struct cam_req_mgr_ver_info { + uint32_t version; + union { + struct cam_req_mgr_link_info link_info_v1; + struct cam_req_mgr_link_info_v2 link_info_v2; + } u; +}; /** * struct cam_req_mgr_unlink_info * @session_hdl: input param - session handle @@ -231,6 +246,7 @@ struct cam_req_mgr_link_control { #define CAM_REQ_MGR_RELEASE_BUF (CAM_COMMON_OPCODE_MAX + 11) #define CAM_REQ_MGR_CACHE_OPS (CAM_COMMON_OPCODE_MAX + 12) #define CAM_REQ_MGR_LINK_CONTROL (CAM_COMMON_OPCODE_MAX + 13) +#define CAM_REQ_MGR_LINK_V2 (CAM_COMMON_OPCODE_MAX + 14) /* end of cam_req_mgr opcodes */ #define CAM_MEM_FLAG_HW_READ_WRITE (1<<0) From 7034eb700006865b7eb5963a924766fd0855f4ec Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 15 Apr 2019 18:54:50 -0700 Subject: [PATCH 073/281] usb: dwc3: Give unique name to gsi endpoints Using same gsi endpoint name gsi-epin twice prevents creating second gsi-epin dir and endpoint files for debugfs. Hence give unique name by appending index after gsi-epin/out string. Also modify usb_ep_autoconfig_by_name() API to restrict string comparison to the length of the string passed as parameter. Change-Id: I3d6e9a3f9eb3fd0c445afc3b76f28dc9199374f4 Signed-off-by: Hemant Kumar Signed-off-by: Ajay Agarwal --- drivers/usb/dwc3/gadget.c | 9 ++++++--- drivers/usb/gadget/epautoconf.c | 9 +++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8424341304ae..1e9849ee2c99 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2422,9 +2422,12 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, if ((gsi_ep_index < gsi_ep_count) && (i > (num - 1 - gsi_ep_count))) { gsi_ep_index++; - /* For GSI EPs, name eps as "gsi-epin" or "gsi-epout" */ - snprintf(dep->name, sizeof(dep->name), "%s", - (epnum & 1) ? "gsi-epin" : "gsi-epout"); + /* + * For GSI EPs, name eps as "gsi-epin" or + * "gsi-epout" + */ + snprintf(dep->name, sizeof(dep->name), "%s%d", + (epnum & 1) ? "gsi-epin" : "gsi-epout", epnum >> 1); /* Set ep type as GSI */ dep->endpoint.ep_type = EP_TYPE_GSI; } else { diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index d942be9b3e0c..dba8916adaf2 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -211,7 +211,7 @@ void usb_ep_autoconfig_reset (struct usb_gadget *gadget) EXPORT_SYMBOL_GPL(usb_ep_autoconfig_reset); /** - * usb_ep_autoconfig_by_name - Used to pick the endpoint by name. eg ep1in-gsi + * usb_ep_autoconfig_by_name - Used to pick the endpoint by name. eg gsi-epin14 * @gadget: The device to which the endpoint must belong. * @desc: Endpoint descriptor, with endpoint direction and transfer mode * initialized. @@ -227,8 +227,12 @@ struct usb_ep *usb_ep_autoconfig_by_name( struct usb_ep *ep; bool ep_found = false; + if (!ep_name || !strlen(ep_name)) + goto err; + list_for_each_entry(ep, &gadget->ep_list, ep_list) - if (strcmp(ep->name, ep_name) == 0 && !ep->driver_data) { + if (strncmp(ep->name, ep_name, strlen(ep_name)) == 0 && + !ep->driver_data) { ep_found = true; break; } @@ -243,6 +247,7 @@ struct usb_ep *usb_ep_autoconfig_by_name( return ep; } +err: pr_err("%s:error finding ep %s\n", __func__, ep_name); return NULL; } From c241a1a75f7b8fac0bffa97ea796be7e8db9cd31 Mon Sep 17 00:00:00 2001 From: Sanjay Dwivedi Date: Thu, 27 Jun 2019 18:12:21 +0530 Subject: [PATCH 074/281] defconfig: sdxpoorwills: Removing unwanted configs from sdxpoorwills Few FS, BT, HID and USB_MASS STORAGE configurations are not required on auto platform. In NAND based memory, UBIFS is used so, EXT3 FILESYSTEM Config is removed. Synergy BT is used in all auto images. USB Host Mode Storage is not supported. Change-Id: I9d342fceeef6b45ea213479a9f6da2e8be72679c Signed-off-by: Sanjay Dwivedi --- .../configs/sdxpoorwills-auto-perf_defconfig | 39 +++++-------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig index 6d87a92b6a89..86c1b2828c40 100644 --- a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig +++ b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig @@ -14,6 +14,7 @@ CONFIG_RT_GROUP_SCHED=y CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set +CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_KALLSYMS_ALL=y @@ -172,14 +173,6 @@ CONFIG_RMNET_DATA_DEBUG_PKT=y CONFIG_CAN=y CONFIG_QTI_CAN=y CONFIG_BT=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=y -CONFIG_BT_HCIUART=y -CONFIG_BT_HCIUART_H4=y CONFIG_MSM_BT_POWER=y CONFIG_CFG80211=y CONFIG_CFG80211_DEBUGFS=y @@ -294,6 +287,7 @@ CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_QPNP=y CONFIG_REGULATOR_RPMH=y +# CONFIG_VGA_ARB is not set CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_DYNAMIC_MINORS=y @@ -301,30 +295,12 @@ CONFIG_SND_USB_AUDIO=y CONFIG_SND_USB_AUDIO_QMI=y CONFIG_SND_SOC=y CONFIG_SND_SOC_TLV320AIC3X=y -CONFIG_UHID=y -CONFIG_HID_APPLE=y -CONFIG_HID_ELECOM=y -CONFIG_HID_MAGICMOUSE=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MULTITOUCH=y +# CONFIG_HID_GENERIC is not set CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_ACM=y -CONFIG_USB_STORAGE=y -CONFIG_USB_STORAGE_DEBUG=y -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_USBAT=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -CONFIG_USB_STORAGE_ALAUDA=y -CONFIG_USB_STORAGE_ONETOUCH=y -CONFIG_USB_STORAGE_KARMA=y -CONFIG_USB_STORAGE_CYPRESS_ATACB=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_MSM=y CONFIG_USB_EHSET_TEST_FIXTURE=y @@ -436,12 +412,11 @@ CONFIG_PWM=y CONFIG_PWM_QPNP=y CONFIG_QCOM_SHOW_RESUME_IRQ=y CONFIG_ANDROID=y -CONFIG_EXT3_FS=y -CONFIG_EXT4_FS_SECURITY=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_UBIFS_FS=y CONFIG_UBIFS_FS_ADVANCED_COMPR=y +# CONFIG_NETWORK_FILESYSTEMS is not set CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y @@ -455,7 +430,7 @@ CONFIG_SCHEDSTATS=y CONFIG_SCHED_STACK_END_CHECK=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_IPC_LOGGING=y -CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_FTRACE is not set CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_CORESIGHT=y CONFIG_CORESIGHT_REMOTE_ETM=y @@ -471,7 +446,11 @@ CONFIG_SECURITY_NETWORK=y CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y # CONFIG_SECURITY_SELINUX_AVC_STATS is not set +CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y CONFIG_CRYPTO_DEV_QCRYPTO=y CONFIG_CRYPTO_DEV_QCEDEV=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set CONFIG_QMI_ENCDEC=y From 5381538ad7858ad33d785eb5691b74c647bb2819 Mon Sep 17 00:00:00 2001 From: Kiran Gunda Date: Fri, 21 Jun 2019 17:20:36 +0530 Subject: [PATCH 075/281] ARM: dts: msm: Add battery parameters for sdm429w Add battery parameters like Full Charge Current, Float Voltage and Jeita threasholds for sdm429w. Change-Id: Iaf1f06271e497b4bf5f31213e4b64205ceecdd03 Signed-off-by: Kiran Gunda --- arch/arm64/boot/dts/qcom/fg-gen3-batterydata-I13Z5P-680mAh.dtsi | 2 +- arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/fg-gen3-batterydata-I13Z5P-680mAh.dtsi b/arch/arm64/boot/dts/qcom/fg-gen3-batterydata-I13Z5P-680mAh.dtsi index 2eb9bc0cac1e..530b60d5ac0a 100644 --- a/arch/arm64/boot/dts/qcom/fg-gen3-batterydata-I13Z5P-680mAh.dtsi +++ b/arch/arm64/boot/dts/qcom/fg-gen3-batterydata-I13Z5P-680mAh.dtsi @@ -12,7 +12,7 @@ */ qcom,3388014_i13z5p_680mah_averaged_masterslave_mar26th2018 { - qcom, = <24>; + qcom,fastchg-current-ma = <480>; /* #3388014_I13Z5P_680mAh_averaged_MasterSlave_Mar26th2018*/ qcom,max-voltage-uv = <4400000>; qcom,fg-cc-cv-threshold-mv = <4390>; diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index f72d24692dd0..d17c7bb60a76 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -571,6 +571,8 @@ qcom,fg-cutoff-current = <50>; qcom,fg-sync-sleep-threshold-ma = <30>; qcom,battery-data = <&mtp_batterydata>; + qcom,fg-force-load-profile; + qcom,fg-jeita-thresholds = <0 20 45 60>; status = "okay"; qcom,fg-batt-soc@4000 { From 7c29f78f0fc422234f56709a5c9ba164e5071748 Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Thu, 16 Aug 2018 15:36:20 -0700 Subject: [PATCH 076/281] iommu: arm-smmu: Add DOMAIN_ATTR_NO_CFRE Some bus implementations may enter a bad state if iommu reports an error on context fault. As context faults are not always fatal, this must be avoided. Change-Id: I60d1ccb7cad64dfc9e327967c903befd3fa72877 Signed-off-by: Patrick Daly Signed-off-by: Srinivasarao P --- drivers/iommu/arm-smmu.c | 13 +++++++++++++ include/linux/iommu.h | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index de05de4b3333..004460d85018 100755 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1790,6 +1790,8 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx) reg &= ~SCTLR_CFCFG; reg |= SCTLR_HUPCF; } + if (cb->attributes & (1 << DOMAIN_ATTR_NO_CFRE)) + reg &= ~SCTLR_CFRE; if ((!(cb->attributes & (1 << DOMAIN_ATTR_S1_BYPASS)) && !(cb->attributes & (1 << DOMAIN_ATTR_EARLY_MAP))) || @@ -3316,6 +3318,11 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, & (1 << DOMAIN_ATTR_CB_STALL_DISABLE)); ret = 0; break; + case DOMAIN_ATTR_NO_CFRE: + *((int *)data) = !!(smmu_domain->attributes + & (1 << DOMAIN_ATTR_NO_CFRE)); + ret = 0; + break; case DOMAIN_ATTR_MMU500_ERRATA_MIN_ALIGN: *((int *)data) = smmu_domain->qsmmuv500_errata2_min_align; ret = 0; @@ -3550,6 +3557,12 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, break; } + case DOMAIN_ATTR_NO_CFRE: + if (*((int *)data)) + smmu_domain->attributes |= + 1 << DOMAIN_ATTR_NO_CFRE; + ret = 0; + break; default: ret = -ENODEV; } diff --git a/include/linux/iommu.h b/include/linux/iommu.h index acbc605d509b..6785d2e91ba5 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -119,6 +119,11 @@ enum iommu_cap { * DOMAIN_ATTR_FSL_PAMUV1 corresponds to the above mentioned contraints. * The caller can invoke iommu_domain_get_attr to check if the underlying * iommu implementation supports these constraints. + * + * DOMAIN_ATTR_NO_CFRE + * Some bus implementations may enter a bad state if iommu reports an error + * on context fault. As context faults are not always fatal, this must be + * avoided. */ enum iommu_attr { @@ -149,6 +154,7 @@ enum iommu_attr { DOMAIN_ATTR_UPSTREAM_IOVA_ALLOCATOR, DOMAIN_ATTR_MMU500_ERRATA_MIN_ALIGN, DOMAIN_ATTR_FORCE_IOVA_GUARD_PAGE, + DOMAIN_ATTR_NO_CFRE, DOMAIN_ATTR_MAX, }; From 07f9aeb5ecbbd05b9c0f20f66966641a1587f9e9 Mon Sep 17 00:00:00 2001 From: Xipeng Gu Date: Fri, 5 Jul 2019 11:55:30 +0800 Subject: [PATCH 077/281] clk: msm: mdss: Fix relock failed issue for DSI 12nm PLL The DSI re-lock sequence sometimes failed in some cases, Add enable sequence to fix this issue. CRs-Fixed: 2474445, 2477428 Change-Id: Ibb6ce1ebfc63c98c310521ca085824e2a853e197 Signed-off-by: Xipeng Gu --- drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c b/drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c index 0bdfeeb576d7..e502826d3973 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c +++ b/drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, 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 @@ -262,6 +262,12 @@ static int dsi_pll_relock(struct mdss_pll_resources *pll) data |= 0x1; /* set ONPLL_OVN to 0x1 */ MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_POWERUP_CTRL, data); ndelay(500); /* h/w recommended delay */ + MDSS_PLL_REG_W(pll_base, DSIPHY_SYS_CTRL, 0x49); + wmb(); /* make sure register committed before enabling branch clocks */ + udelay(5); /* h/w recommended delay */ + MDSS_PLL_REG_W(pll_base, DSIPHY_SYS_CTRL, 0xc9); + wmb(); /* make sure register committed before enabling branch clocks */ + udelay(50); /* h/w recommended delay */ if (!pll_is_pll_locked_12nm(pll, false)) { pr_err("DSI PLL ndx=%d lock failed!\n", From 1140078e093374e0340a7a3a8ec59432d29e7e1b Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Thu, 27 Jun 2019 15:23:05 +0800 Subject: [PATCH 078/281] coresight: Reset all activated sinks When multi-sink enabled by userspace, all activated sink should be deactivated in call reset interface. Change-Id: Ie0c4f7bcda4adc1b0dc0d60e433e8c3f634568e2 Signed-off-by: Mulu He Signed-off-by: Mao Jinlong --- drivers/hwtracing/coresight/coresight.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 2009a23f1d3e..9e013bd40f7d 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012, 2017-2019, 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 @@ -91,6 +91,23 @@ static int coresight_source_is_unique(struct coresight_device *csdev) csdev, coresight_id_match); } +static int coresight_reset_sink(struct device *dev, void *data) +{ + struct coresight_device *csdev = to_coresight_device(dev); + + if ((csdev->type == CORESIGHT_DEV_TYPE_SINK || + csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) && + csdev->activated) + csdev->activated = false; + + return 0; +} + +static void coresight_reset_all_sink(void) +{ + bus_for_each_dev(&coresight_bustype, NULL, NULL, coresight_reset_sink); +} + static int coresight_find_link_inport(struct coresight_device *csdev, struct coresight_device *parent) { @@ -1036,6 +1053,9 @@ static ssize_t reset_source_sink_store(struct bus_type *bus, __coresight_disable(csdev); } + /* Reset all activated sinks */ + coresight_reset_all_sink(); + mutex_unlock(&coresight_mutex); return size; } From 3fc584bf97a137b2dca3fd52a2abe0592eb5bb46 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Wed, 26 Jun 2019 14:56:59 +0800 Subject: [PATCH 079/281] Coresight-cti: No need to keep clk being on for cti save/restore CTI save/restore function only works when CTI have been enabled. In this situation, clk have been voted. So no need to keep clk being on. Change-Id: I3a4eb7aec7cc169128f00c2731fecbb68b932ff5 Signed-off-by: Yuanfang Zhang --- drivers/hwtracing/coresight/coresight-cti.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-cti.c b/drivers/hwtracing/coresight/coresight-cti.c index 066072a9cc39..e0120b718c72 100644 --- a/drivers/hwtracing/coresight/coresight-cti.c +++ b/drivers/hwtracing/coresight/coresight-cti.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, 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 @@ -1484,13 +1484,6 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) drvdata->cti_hwclk = of_property_read_bool(adev->dev.of_node, "qcom,cti-hwclk"); } - if (drvdata->cti_save && !drvdata->cti_hwclk) { - ret = pm_runtime_get_sync(drvdata->dev); - if (ret < 0) { - pm_runtime_put(drvdata->dev); - return ret; - } - } mutex_lock(&cti_lock); drvdata->cti.name = ((struct coresight_platform_data *) From ec7274815d2d8facb64179a2a8efe633590d5028 Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Fri, 5 Jul 2019 11:52:30 +0530 Subject: [PATCH 080/281] defconfig: Enable tmc and replicator on sdxpoorwills perf build Tmc components and replicator are required for some tests on perf build. They are disabled by default which won't cause any power and performance issue on perf build. Change-Id: Iabb879d1eca759b40864520077051cacf9357e69 Signed-off-by: Mao Jinlong --- arch/arm/configs/sdxpoorwills-auto-perf_defconfig | 2 ++ arch/arm/configs/sdxpoorwills-perf_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig index 6d87a92b6a89..d62b10937665 100644 --- a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig +++ b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig @@ -458,8 +458,10 @@ CONFIG_IPC_LOGGING=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 +CONFIG_CORESIGHT_QCOM_REPLICATOR=y CONFIG_CORESIGHT_STM=y CONFIG_CORESIGHT_TPDA=y CONFIG_CORESIGHT_TPDM=y diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig index ecf66274b959..4c48a1f716c9 100644 --- a/arch/arm/configs/sdxpoorwills-perf_defconfig +++ b/arch/arm/configs/sdxpoorwills-perf_defconfig @@ -432,8 +432,10 @@ CONFIG_IPC_LOGGING=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 +CONFIG_CORESIGHT_QCOM_REPLICATOR=y CONFIG_CORESIGHT_STM=y CONFIG_CORESIGHT_TPDA=y CONFIG_CORESIGHT_TPDM=y From bd3dbfb123e065391e6c5a397a429231bb9ef5f4 Mon Sep 17 00:00:00 2001 From: Zhenhua Huang Date: Fri, 28 Jun 2019 14:21:27 +0800 Subject: [PATCH 081/281] Revert "Revert "ANDROID: Communicates LMK events to userland where they can be logged"" This reverts commit 9fd99422748a952a0c01ee9846c5d213a96f23f2. The feature caused crash so we may wait until it's stable. Change-Id: Ibb5d9326dc9fde344dd76308878d7f106d21035a Signed-off-by: Zhenhua Huang --- drivers/staging/android/lowmemorykiller.c | 157 ---------------------- 1 file changed, 157 deletions(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index a098685daa15..ecae4c9f8ba8 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -98,159 +98,6 @@ static unsigned long lowmem_deathpending_timeout; pr_info(x); \ } while (0) - -static DECLARE_WAIT_QUEUE_HEAD(event_wait); -static DEFINE_SPINLOCK(lmk_event_lock); -static struct circ_buf event_buffer; -#define MAX_BUFFERED_EVENTS 8 -#define MAX_TASKNAME 128 - -struct lmk_event { - char taskname[MAX_TASKNAME]; - pid_t pid; - uid_t uid; - pid_t group_leader_pid; - unsigned long min_flt; - unsigned long maj_flt; - unsigned long rss_in_pages; - short oom_score_adj; - short min_score_adj; - unsigned long long start_time; - struct list_head list; -}; - -void handle_lmk_event(struct task_struct *selected, short min_score_adj) -{ - int head; - int tail; - struct lmk_event *events; - struct lmk_event *event; - int res; - long rss_in_pages = -1; - char taskname[MAX_TASKNAME]; - struct mm_struct *mm = get_task_mm(selected); - - if (mm) { - rss_in_pages = get_mm_rss(mm); - mmput(mm); - } - - res = get_cmdline(selected, taskname, MAX_TASKNAME - 1); - - /* No valid process name means this is definitely not associated with a - * userspace activity. - */ - - if (res <= 0 || res >= MAX_TASKNAME) - return; - - taskname[res] = '\0'; - - spin_lock(&lmk_event_lock); - - head = event_buffer.head; - tail = READ_ONCE(event_buffer.tail); - - /* Do not continue to log if no space remains in the buffer. */ - if (CIRC_SPACE(head, tail, MAX_BUFFERED_EVENTS) < 1) { - spin_unlock(&lmk_event_lock); - return; - } - - events = (struct lmk_event *) event_buffer.buf; - event = &events[head]; - - memcpy(event->taskname, taskname, res + 1); - - event->pid = selected->pid; - event->uid = from_kuid_munged(current_user_ns(), task_uid(selected)); - if (selected->group_leader) - event->group_leader_pid = selected->group_leader->pid; - else - event->group_leader_pid = -1; - event->min_flt = selected->min_flt; - event->maj_flt = selected->maj_flt; - event->oom_score_adj = selected->signal->oom_score_adj; - event->start_time = nsec_to_clock_t(selected->real_start_time); - event->rss_in_pages = rss_in_pages; - event->min_score_adj = min_score_adj; - - event_buffer.head = (head + 1) & (MAX_BUFFERED_EVENTS - 1); - - spin_unlock(&lmk_event_lock); - - wake_up_interruptible(&event_wait); -} - -static int lmk_event_show(struct seq_file *s, void *unused) -{ - struct lmk_event *events = (struct lmk_event *) event_buffer.buf; - int head; - int tail; - struct lmk_event *event; - - spin_lock(&lmk_event_lock); - - head = event_buffer.head; - tail = event_buffer.tail; - - if (head == tail) { - spin_unlock(&lmk_event_lock); - return -EAGAIN; - } - - event = &events[tail]; - - seq_printf(s, "%lu %lu %lu %lu %lu %lu %hd %hd %llu\n%s\n", - (unsigned long) event->pid, (unsigned long) event->uid, - (unsigned long) event->group_leader_pid, event->min_flt, - event->maj_flt, event->rss_in_pages, event->oom_score_adj, - event->min_score_adj, event->start_time, event->taskname); - - event_buffer.tail = (tail + 1) & (MAX_BUFFERED_EVENTS - 1); - - spin_unlock(&lmk_event_lock); - return 0; -} - -static unsigned int lmk_event_poll(struct file *file, poll_table *wait) -{ - int ret = 0; - - poll_wait(file, &event_wait, wait); - spin_lock(&lmk_event_lock); - if (event_buffer.head != event_buffer.tail) - ret = POLLIN; - spin_unlock(&lmk_event_lock); - return ret; -} - -static int lmk_event_open(struct inode *inode, struct file *file) -{ - return single_open(file, lmk_event_show, inode->i_private); -} - -static const struct file_operations event_file_ops = { - .open = lmk_event_open, - .poll = lmk_event_poll, - .read = seq_read -}; - -static void lmk_event_init(void) -{ - struct proc_dir_entry *entry; - - event_buffer.head = 0; - event_buffer.tail = 0; - event_buffer.buf = kmalloc( - sizeof(struct lmk_event) * MAX_BUFFERED_EVENTS, GFP_KERNEL); - if (!event_buffer.buf) - return; - entry = proc_create("lowmemorykiller", 0, NULL, &event_file_ops); - if (!entry) - pr_err("error creating kernel lmk event file\n"); -} - static unsigned long lowmem_count(struct shrinker *s, struct shrink_control *sc) { @@ -802,9 +649,6 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) sc->nr_to_scan, sc->gfp_mask, rem); mutex_unlock(&scan_mutex); - if (selected) - handle_lmk_event(selected, min_score_adj); - return rem; } @@ -818,7 +662,6 @@ static int __init lowmem_init(void) { register_shrinker(&lowmem_shrinker); vmpressure_notifier_register(&lmk_vmpr_nb); - lmk_event_init(); return 0; } device_initcall(lowmem_init); From a5d9d00a9467fe6a0dfff8f4e6b119cdad3d42df Mon Sep 17 00:00:00 2001 From: Sean Tranchetti Date: Fri, 5 Jul 2019 14:58:50 +0530 Subject: [PATCH 082/281] defconfig: msm8937: Enable missing networking options Android Kernel Net Testing requires additional configuration options to work properly. Enable the following- SYN_COOKIES INET_UDP_DIAG IP_SCTP INET_SCTP_DIAG Change-Id: I3c1ef2bb989ffb0a284f6e8bb08f3f08cccdff7c Signed-off-by: Sean Tranchetti Signed-off-by: Chinmay Agarwal --- arch/arm/configs/msm8937-perf_defconfig | 5 ++++- arch/arm/configs/msm8937_defconfig | 5 ++++- arch/arm64/configs/msm8937-perf_defconfig | 4 +++- arch/arm64/configs/msm8937_defconfig | 4 +++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig index 98966079d70e..36285ef66765 100755 --- a/arch/arm/configs/msm8937-perf_defconfig +++ b/arch/arm/configs/msm8937-perf_defconfig @@ -107,10 +107,12 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y +CONFIG_INET_UDP_DIAG=y CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y @@ -127,7 +129,6 @@ CONFIG_NF_CONNTRACK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=y CONFIG_NF_CONNTRACK_FTP=y @@ -174,6 +175,7 @@ CONFIG_NETFILTER_XT_MATCH_POLICY=y CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y CONFIG_NETFILTER_XT_MATCH_QUOTA=y CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set CONFIG_NETFILTER_XT_MATCH_SOCKET=y CONFIG_NETFILTER_XT_MATCH_STATE=y CONFIG_NETFILTER_XT_MATCH_STATISTIC=y @@ -207,6 +209,7 @@ CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y CONFIG_BRIDGE_NF_EBTABLES=y CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_IP_SCTP=y CONFIG_L2TP=y CONFIG_L2TP_DEBUGFS=y CONFIG_L2TP_V3=y diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig index ada99da4b1a5..6e9f54666f0e 100755 --- a/arch/arm/configs/msm8937_defconfig +++ b/arch/arm/configs/msm8937_defconfig @@ -110,10 +110,12 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y +CONFIG_INET_UDP_DIAG=y CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y @@ -130,7 +132,6 @@ CONFIG_NF_CONNTRACK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=y CONFIG_NF_CONNTRACK_FTP=y @@ -177,6 +178,7 @@ CONFIG_NETFILTER_XT_MATCH_POLICY=y CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y CONFIG_NETFILTER_XT_MATCH_QUOTA=y CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set CONFIG_NETFILTER_XT_MATCH_SOCKET=y CONFIG_NETFILTER_XT_MATCH_STATE=y CONFIG_NETFILTER_XT_MATCH_STATISTIC=y @@ -210,6 +212,7 @@ CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y CONFIG_BRIDGE_NF_EBTABLES=y CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_IP_SCTP=y CONFIG_L2TP=y CONFIG_L2TP_DEBUGFS=y CONFIG_L2TP_V3=y diff --git a/arch/arm64/configs/msm8937-perf_defconfig b/arch/arm64/configs/msm8937-perf_defconfig index aeeebb2774c0..7fde262b1b33 100755 --- a/arch/arm64/configs/msm8937-perf_defconfig +++ b/arch/arm64/configs/msm8937-perf_defconfig @@ -107,6 +107,7 @@ CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_NET_IPGRE_DEMUX=y +CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y @@ -128,7 +129,6 @@ CONFIG_NF_CONNTRACK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=y CONFIG_NF_CONNTRACK_FTP=y @@ -175,6 +175,7 @@ CONFIG_NETFILTER_XT_MATCH_POLICY=y CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y CONFIG_NETFILTER_XT_MATCH_QUOTA=y CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set CONFIG_NETFILTER_XT_MATCH_SOCKET=y CONFIG_NETFILTER_XT_MATCH_STATE=y CONFIG_NETFILTER_XT_MATCH_STATISTIC=y @@ -208,6 +209,7 @@ CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y CONFIG_BRIDGE_NF_EBTABLES=y CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_IP_SCTP=y CONFIG_L2TP=y CONFIG_L2TP_V3=y CONFIG_L2TP_IP=y diff --git a/arch/arm64/configs/msm8937_defconfig b/arch/arm64/configs/msm8937_defconfig index f09c4452782c..59f906afabb9 100755 --- a/arch/arm64/configs/msm8937_defconfig +++ b/arch/arm64/configs/msm8937_defconfig @@ -111,6 +111,7 @@ CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_NET_IPGRE_DEMUX=y +CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y @@ -132,7 +133,6 @@ CONFIG_NF_CONNTRACK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=y CONFIG_NF_CONNTRACK_FTP=y @@ -179,6 +179,7 @@ CONFIG_NETFILTER_XT_MATCH_POLICY=y CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y CONFIG_NETFILTER_XT_MATCH_QUOTA=y CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set CONFIG_NETFILTER_XT_MATCH_SOCKET=y CONFIG_NETFILTER_XT_MATCH_STATE=y CONFIG_NETFILTER_XT_MATCH_STATISTIC=y @@ -212,6 +213,7 @@ CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y CONFIG_BRIDGE_NF_EBTABLES=y CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_IP_SCTP=y CONFIG_L2TP=y CONFIG_L2TP_DEBUGFS=y CONFIG_L2TP_V3=y From 25e339bbb45912af9af29b25ee01ae04322ac3ba Mon Sep 17 00:00:00 2001 From: Sriharsha Allenki Date: Tue, 18 Jun 2019 16:49:24 +0530 Subject: [PATCH 083/281] usb: dwc3: Prevent continuous retries on error event Upon USB core generating an erratic error event, the dwc3-msm driver resets and restarts the core. Even after this if core could not recover, the driver keep on trying the same in a infinite loop. This could lead to the hogging of system resources leading to system failure. Prevent this by trying a maximum of three times to recover upon erratic error event. An example of continuous generation of error events is a DCP charger detected as SDP by the PMIC and core entering device mode. In this case, the core could not recover even after several tries. Change-Id: Ic2f2f10e6bcc7480be5116746072b0fb1651ce10 Signed-off-by: Sriharsha Allenki --- drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/gadget.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5983b2d89257..b8b3fb913077 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1175,6 +1175,7 @@ struct dwc3 { bool create_reg_debugfs; u32 xhci_imod_value; int core_id; + int retries_on_error; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8424341304ae..366279905dac 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -37,6 +37,8 @@ #include "gadget.h" #include "io.h" +#define MAX_ERROR_RECOVERY_TRIES 3 + static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc, bool remote_wakeup); static int dwc3_gadget_wakeup_int(struct dwc3 *dwc); static void dwc3_stop_active_transfers(struct dwc3 *dwc); @@ -3171,6 +3173,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) speed = reg & DWC3_DSTS_CONNECTSPD; dwc->speed = speed; + /* Reset the retry on erratic error event count */ + dwc->retries_on_error = 0; dwc3_update_ram_clk_sel(dwc, speed); switch (speed) { @@ -3545,7 +3549,7 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, break; case DWC3_DEVICE_EVENT_ERRATIC_ERROR: dwc3_trace(trace_dwc3_gadget, "Erratic Error"); - dbg_event(0xFF, "ERROR", 0); + dbg_event(0xFF, "ERROR", dwc->retries_on_error); dwc->dbg_gadget_events.erratic_error++; break; case DWC3_DEVICE_EVENT_CMD_CMPL: @@ -3631,9 +3635,12 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc) evt->lpos = (evt->lpos + left) % DWC3_EVENT_BUFFERS_SIZE; dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), left); - if (dwc3_notify_event(dwc, + if (dwc->retries_on_error < MAX_ERROR_RECOVERY_TRIES) { + if (dwc3_notify_event(dwc, DWC3_CONTROLLER_ERROR_EVENT, 0)) - dwc->err_evt_seen = 0; + dwc->err_evt_seen = 0; + dwc->retries_on_error++; + } break; } From 9e53de94b022085761e1f939f638c3cfbaf74670 Mon Sep 17 00:00:00 2001 From: Zhaohong Chen Date: Fri, 5 Jul 2019 16:29:42 +0800 Subject: [PATCH 084/281] msm: camera: eeprom: Fix not enough memory buffer issue in EEPROM Correct the limitation of memory map so that we can fully use the allocated memory. Change-Id: Ia844feeaa99a227e716e508a09050d56d2a47c8f Signed-off-by: Zhaohong Chen --- .../camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 0b6b7e942d14..02287709546e 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -439,8 +439,8 @@ static int32_t cam_eeprom_parse_memory_map( else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) validate_size = sizeof(struct cam_cmd_unconditional_wait); - if (remain_buf_len < validate_size || - *num_map >= MSM_EEPROM_MAX_MEM_MAP_CNT) { + if (remain_buf_len < validate_size || *num_map >= + (MSM_EEPROM_MEMORY_MAP_MAX_SIZE * MSM_EEPROM_MAX_MEM_MAP_CNT)) { CAM_ERR(CAM_EEPROM, "not enough buffer"); return -EINVAL; } @@ -449,7 +449,9 @@ static int32_t cam_eeprom_parse_memory_map( i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf; if (i2c_random_wr->header.count == 0 || - i2c_random_wr->header.count >= MSM_EEPROM_MAX_MEM_MAP_CNT || + i2c_random_wr->header.count >= + (MSM_EEPROM_MEMORY_MAP_MAX_SIZE * + MSM_EEPROM_MAX_MEM_MAP_CNT) || (size_t)*num_map > U16_MAX - i2c_random_wr->header.count) { CAM_ERR(CAM_EEPROM, "OOB Error"); return -EINVAL; From 6f701bbe384f125d22a6ba46957b1654282289de Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Fri, 26 Apr 2019 15:20:18 +0800 Subject: [PATCH 085/281] sched/fair: Avoid unnecessary active load balance When find busiest group, it will avoid load balance if it is only 1 task running on src cpu. Consider race when different cpus do newly idle load balance at the same time, check src cpu nr_running to avoid unnecessary active load balance again. See the race condition example here: 1) cpu2 have 2 tasks, so cpu2 rq->nr_running == 2 and cfs.h_nr_running ==2. 2) cpu4 and cpu5 doing newly idle load balance at the same time. 3) cpu4 and cpu5 both see cpu2 sched_load_balance_sg_stats sum_nr_run=2 so they are both see cpu2 as the busiest rq. 4) cpu5 did a success migration task from cpu2, so cpu2 only have 1 task left, cpu2 rq->nr_running == 1 and cfs.h_nr_running ==1. 5) cpu4 surely goes to no_move because currently cpu4 only have 1 task which is currently running. 6) and then cpu4 goes here to check if cpu2 need active load balance. Change-Id: Ia9539a43e9769c4936f06ecfcc11864984c50c29 Signed-off-by: Maria Yu --- kernel/sched/fair.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 29ba2d66c49b..6f7d15aac082 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -10011,8 +10011,10 @@ static int need_active_balance(struct lb_env *env) * It's worth migrating the task if the src_cpu's capacity is reduced * because of other sched_class or IRQs if more capacity stays * available on dst_cpu. + * Avoid pulling the CFS task if it is the only task running. */ if ((env->idle != CPU_NOT_IDLE) && + (env->src_rq->nr_running > 1) && (env->src_rq->cfs.h_nr_running == 1)) { if ((check_cpu_capacity(env->src_rq, sd)) && (capacity_of(env->src_cpu)*sd->imbalance_pct < capacity_of(env->dst_cpu)*100)) From d7bf8ba295a8a0e13e012ca8fa123e6e89386972 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Wed, 21 Nov 2018 17:07:20 -0800 Subject: [PATCH 086/281] usb: gadget: Fix double free of device descriptor pointers Upon driver unbind usb_free_all_descriptors() function frees all speed descriptor pointers without setting them to NULL. In case gadget speed changes (i.e from super speed plus to super speed) after driver unbind only upto super speed descriptor pointers get populated. Super speed plus desc still holds the stale (already freed) pointer. As a result next composition switch results into double free of super speed plus descriptor. Fix this issue by setting all descriptor pointers to NULL after freeing them in usb_free_all_descriptors(). Change-Id: I4f28294c165bb3b5dc9feb4f22d819f527ad4d50 Signed-off-by: Hemant Kumar Signed-off-by: Chandana Kishori Chiluveru --- drivers/usb/gadget/config.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index 17a6077b89a4..9b9d31eb6037 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -198,9 +198,13 @@ EXPORT_SYMBOL_GPL(usb_assign_descriptors); void usb_free_all_descriptors(struct usb_function *f) { usb_free_descriptors(f->fs_descriptors); + f->fs_descriptors = NULL; usb_free_descriptors(f->hs_descriptors); + f->hs_descriptors = NULL; usb_free_descriptors(f->ss_descriptors); + f->ss_descriptors = NULL; usb_free_descriptors(f->ssp_descriptors); + f->ssp_descriptors = NULL; } EXPORT_SYMBOL_GPL(usb_free_all_descriptors); From 32adff736abd31b9ac22a08bd78f3d014539fe5f Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Mon, 8 Jul 2019 15:30:21 +0530 Subject: [PATCH 087/281] drivers: hwmon: Update wait times for end of conversion check Reduce the wait time for EOC interrupt and timeout time when polling for EOC, according to HW side recommendation. Change-Id: Ia1629311ce16810d7eb2a87a15c094d14e0457a1 Signed-off-by: Jishnu Prakash --- drivers/hwmon/qpnp-adc-voltage.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c index 35d33de7dc13..086e706a242e 100644 --- a/drivers/hwmon/qpnp-adc-voltage.c +++ b/drivers/hwmon/qpnp-adc-voltage.c @@ -107,8 +107,8 @@ #define QPNP_VADC_CONV_TIMEOUT_ERR 2 #define QPNP_VADC_CONV_TIME_MIN 1000 #define QPNP_VADC_CONV_TIME_MAX 1100 -#define QPNP_ADC_COMPLETION_TIMEOUT HZ -#define QPNP_VADC_ERR_COUNT 20 +#define QPNP_ADC_COMPLETION_TIMEOUT msecs_to_jiffies(100) +#define QPNP_VADC_ERR_COUNT 150 #define QPNP_OP_MODE_SHIFT 3 #define QPNP_VADC_THR_LSB_MASK(val) (val & 0xff) @@ -161,7 +161,8 @@ */ #define QPNP_VADC_HC1_CONV_TIME_MIN_US 213 #define QPNP_VADC_HC1_CONV_TIME_MAX_US 214 -#define QPNP_VADC_HC1_ERR_COUNT 1600 +#define QPNP_VADC_HC1_ERR_COUNT_POLL 705 +#define QPNP_VADC_HC1_ERR_COUNT 235 #define QPNP_VADC_CAL_DELAY_CTL_1 0x3744 #define QPNP_VADC_CAL_DELAY_MEAS_SLOW 0x73 @@ -363,11 +364,17 @@ static int32_t qpnp_vadc_status_debug(struct qpnp_vadc_chip *vadc) return 0; } -static int qpnp_vadc_hc_check_conversion_status(struct qpnp_vadc_chip *vadc) +static int qpnp_vadc_hc_check_conversion_status(struct qpnp_vadc_chip *vadc, + bool poll) { - int rc = 0, count = 0; + int rc = 0, count = 0, retry; u8 status1 = 0; + if (poll) + retry = QPNP_VADC_HC1_ERR_COUNT_POLL; + else + retry = QPNP_VADC_HC1_ERR_COUNT; + while (status1 != QPNP_VADC_STATUS1_EOC) { rc = qpnp_vadc_read_reg(vadc, QPNP_VADC_STATUS1, &status1, 1); if (rc < 0) @@ -378,7 +385,7 @@ static int qpnp_vadc_hc_check_conversion_status(struct qpnp_vadc_chip *vadc) usleep_range(QPNP_VADC_HC1_CONV_TIME_MIN_US, QPNP_VADC_HC1_CONV_TIME_MAX_US); count++; - if (count > QPNP_VADC_HC1_ERR_COUNT) { + if (count > retry) { pr_err("retry error exceeded\n"); rc = qpnp_vadc_status_debug(vadc); if (rc < 0) @@ -429,7 +436,7 @@ static int qpnp_vadc_wait_for_eoc(struct qpnp_vadc_chip *vadc) int ret; if (vadc->vadc_poll_eoc) { - ret = qpnp_vadc_hc_check_conversion_status(vadc); + ret = qpnp_vadc_hc_check_conversion_status(vadc, true); if (ret < 0) { pr_err("polling mode conversion failed\n"); return ret; @@ -439,7 +446,7 @@ static int qpnp_vadc_wait_for_eoc(struct qpnp_vadc_chip *vadc) &vadc->adc->adc_rslt_completion, QPNP_ADC_COMPLETION_TIMEOUT); if (!ret) { - ret = qpnp_vadc_hc_check_conversion_status(vadc); + ret = qpnp_vadc_hc_check_conversion_status(vadc, false); if (ret < 0) { pr_err("interrupt mode conversion failed\n"); return ret; From a4e89d324c3312f6c98a80a716331dbfc41e4b61 Mon Sep 17 00:00:00 2001 From: Zhaohong Chen Date: Wed, 3 Jul 2019 13:12:35 +0800 Subject: [PATCH 088/281] ARM: dts: msm: add camera configuration for sdm845 rb3 device Add ov8856 configuration that is required for camera functionality on sdm845 rb3. While at it, remove the device nodes that are not required. Change-Id: Ie1a0768dce354d06bfb752f57655796932f6bbc4 Signed-off-by: Zhaohong Chen --- .../dts/qcom/sdm845-camera-sensor-rb3.dtsi | 308 ++---------------- arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi | 9 + 2 files changed, 42 insertions(+), 275 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi index f71c28331e97..8aac76e8b5d2 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi @@ -12,84 +12,30 @@ */ &soc { - led_flash_rear: qcom,camera-flash@0 { - cell-index = <0>; - reg = <0x00 0x00>; - compatible = "qcom,camera-flash"; - flash-source = <&pmi8998_flash0 &pmi8998_flash1>; - torch-source = <&pmi8998_torch0 &pmi8998_torch1>; - switch-source = <&pmi8998_switch0>; - status = "ok"; - }; - - led_flash_rear_aux: qcom,camera-flash@1 { - cell-index = <1>; - reg = <0x01 0x00>; - compatible = "qcom,camera-flash"; - flash-source = <&pmi8998_flash0 &pmi8998_flash1>; - torch-source = <&pmi8998_torch0 &pmi8998_torch1>; - switch-source = <&pmi8998_switch0>; - status = "ok"; - }; - - led_flash_front: qcom,camera-flash@2 { - cell-index = <2>; - reg = <0x02 0x00>; - compatible = "qcom,camera-flash"; - flash-source = <&pmi8998_flash2>; - torch-source = <&pmi8998_torch2>; - switch-source = <&pmi8998_switch1>; - status = "ok"; - }; - - led_flash_iris: qcom,camera-flash@3 { - cell-index = <3>; - reg = <0x03 0x00>; - compatible = "qcom,camera-flash"; - flash-source = <&pmi8998_flash2>; - torch-source = <&pmi8998_torch2>; - switch-source = <&pmi8998_switch2>; - status = "ok"; - }; - - actuator_regulator: gpio-regulator@0 { + camera_rear_avdd_ldo: gpio-regulator@0 { compatible = "regulator-fixed"; - reg = <0x00 0x00>; - regulator-name = "actuator_regulator"; + reg = <0x01 0x00>; + regulator-name = "camera_rear_avdd_ldo"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; - regulator-enable-ramp-delay = <100>; - enable-active-high; - gpio = <&tlmm 27 0>; - vin-supply = <&pmi8998_bob>; - }; - - camera_ldo: gpio-regulator@2 { - compatible = "regulator-fixed"; - reg = <0x02 0x00>; - regulator-name = "camera_ldo"; - regulator-min-microvolt = <1050000>; - regulator-max-microvolt = <1050000>; regulator-enable-ramp-delay = <233>; enable-active-high; - gpio = <&pm8998_gpios 9 0>; + gpio = <&pm8998_gpios 10 0>; pinctrl-names = "default"; - pinctrl-0 = <&camera_dvdd_en_default>; - vin-supply = <&pm8998_s3>; + pinctrl-0 = <&camera_rear_avdd_en_default>; }; - camera_vana_ldo: gpio-regulator@4 { + camera_rear_dvdd_ldo: gpio-regulator@1 { compatible = "regulator-fixed"; - reg = <0x04 0x00>; - regulator-name = "camera_vana_ldo"; - regulator-min-microvolt = <2850000>; - regulator-max-microvolt = <2850000>; - regulator-enable-ramp-delay = <233>; + reg = <0x02 0x00>; + regulator-name = "camera_rear_dvdd_ldo"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-enable-ramp-delay = <135>; enable-active-high; - gpio = <&tlmm 10 0>; + gpio = <&pm8998_gpios 12 0>; pinctrl-names = "default"; - pinctrl-0 = <&cam_sensor_rear_vana>; - vin-supply = <&pmi8998_bob>; + pinctrl-0 = <&camera_rear_dvdd_en_default>; }; }; @@ -99,74 +45,20 @@ status = "ok"; }; - actuator_rear: qcom,actuator@0 { - cell-index = <0>; - reg = <0x0>; - compatible = "qcom,actuator"; - cci-master = <0>; - cam_vaf-supply = <&actuator_regulator>; - regulator-names = "cam_vaf"; - rgltr-cntrl-support; - rgltr-min-voltage = <2800000>; - rgltr-max-voltage = <2800000>; - rgltr-load-current = <0>; - }; - - actuator_rear_aux: qcom,actuator@1 { - cell-index = <1>; - reg = <0x1>; - compatible = "qcom,actuator"; - cci-master = <1>; - cam_vaf-supply = <&actuator_regulator>; - regulator-names = "cam_vaf"; - rgltr-cntrl-support; - rgltr-min-voltage = <2800000>; - rgltr-max-voltage = <2800000>; - rgltr-load-current = <0>; - }; - - actuator_front: qcom,actuator@2 { - cell-index = <2>; - reg = <0x2>; - compatible = "qcom,actuator"; - cci-master = <1>; - cam_vaf-supply = <&actuator_regulator>; - regulator-names = "cam_vaf"; - rgltr-cntrl-support; - rgltr-min-voltage = <2800000>; - rgltr-max-voltage = <2800000>; - rgltr-load-current = <0>; - }; - - ois_rear: qcom,ois@0 { - cell-index = <0>; - reg = <0x0>; - compatible = "qcom,ois"; - cci-master = <0>; - cam_vaf-supply = <&actuator_regulator>; - regulator-names = "cam_vaf"; - rgltr-cntrl-support; - rgltr-min-voltage = <2800000>; - rgltr-max-voltage = <2800000>; - rgltr-load-current = <0>; - status = "ok"; - }; - - eeprom_rear: qcom,eeprom@0 { + otp_rear: qcom,eeprom@0 { cell-index = <0>; reg = <0>; compatible = "qcom,eeprom"; cam_vio-supply = <&pm8998_lvs1>; - cam_vana-supply = <&pmi8998_bob>; - cam_vdig-supply = <&camera_ldo>; + cam_vana-supply = <&camera_rear_avdd_ldo>; + cam_vdig-supply = <&camera_rear_dvdd_ldo>; cam_clk-supply = <&titan_top_gdsc>; - cam_vaf-supply = <&actuator_regulator>; regulator-names = "cam_vio", "cam_vana", "cam_vdig", - "cam_clk", "cam_vaf"; + "cam_clk"; rgltr-cntrl-support; - rgltr-min-voltage = <0 3312000 1050000 0 2800000>; - rgltr-max-voltage = <0 3600000 1050000 0 2800000>; - rgltr-load-current = <0 80000 105000 0 0>; + rgltr-min-voltage = <1800000 2800000 1200000 0>; + rgltr-max-voltage = <1800000 2800000 1200000 0>; + rgltr-load-current = <0 80000 105000 0>; gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk0_active @@ -174,15 +66,12 @@ pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; gpios = <&tlmm 13 0>, - <&tlmm 80 0>, - <&tlmm 79 0>; + <&tlmm 9 0>; gpio-reset = <1>; - gpio-vana = <2>; - gpio-req-tbl-num = <0 1 2>; - gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; gpio-req-tbl-label = "CAMIF_MCLK0", - "CAM_RESET0", - "CAM_VANA0"; + "CAM_RESET0"; sensor-position = <0>; sensor-mode = <0>; cci-master = <0>; @@ -240,47 +129,6 @@ clock-rates = <24000000>; }; - eeprom_front: qcom,eeprom@2 { - cell-index = <2>; - reg = <0x2>; - compatible = "qcom,eeprom"; - cam_vio-supply = <&pm8998_lvs1>; - cam_vana-supply = <&pmi8998_bob>; - cam_vdig-supply = <&camera_ldo>; - cam_clk-supply = <&titan_top_gdsc>; - cam_vaf-supply = <&actuator_regulator>; - regulator-names = "cam_vio", "cam_vana", "cam_vdig", - "cam_clk", "cam_vaf"; - rgltr-cntrl-support; - rgltr-min-voltage = <0 3312000 1050000 0 2800000>; - rgltr-max-voltage = <0 3600000 1050000 0 2800000>; - rgltr-load-current = <0 80000 105000 0 0>; - gpio-no-mux = <0>; - pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk1_active - &cam_sensor_front_active>; - pinctrl-1 = <&cam_sensor_mclk1_suspend - &cam_sensor_front_suspend>; - gpios = <&tlmm 14 0>, - <&tlmm 28 0>, - <&tlmm 8 0>; - gpio-reset = <1>; - gpio-vana = <2>; - gpio-req-tbl-num = <0 1 2>; - gpio-req-tbl-flags = <1 0 0>; - gpio-req-tbl-label = "CAMIF_MCLK2", - "CAM_RESET2", - "CAM_VANA2"; - sensor-position = <1>; - sensor-mode = <0>; - cci-master = <1>; - status = "ok"; - clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; - clock-names = "cam_clk"; - clock-cntl-level = "turbo"; - clock-rates = <24000000>; - }; - eeprom_back: qcom,eeprom@3 { cell-index = <3>; reg = <0x3>; @@ -328,19 +176,16 @@ sensor-position-roll = <270>; sensor-position-pitch = <0>; sensor-position-yaw = <180>; - led-flash-src = <&led_flash_rear>; - actuator-src = <&actuator_rear>; - ois-src = <&ois_rear>; - eeprom-src = <&eeprom_rear>; + eeprom-src = <&otp_rear>; cam_vio-supply = <&pm8998_lvs1>; - cam_vana-supply = <&pmi8998_bob>; - cam_vdig-supply = <&camera_ldo>; + cam_vana-supply = <&camera_rear_avdd_ldo>; + cam_vdig-supply = <&camera_rear_dvdd_ldo>; cam_clk-supply = <&titan_top_gdsc>; regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk"; rgltr-cntrl-support; - rgltr-min-voltage = <0 3312000 1050000 0>; - rgltr-max-voltage = <0 3600000 1050000 0>; + rgltr-min-voltage = <1800000 2800000 1200000 0>; + rgltr-max-voltage = <1800000 2800000 1200000 0>; rgltr-load-current = <0 80000 105000 0>; gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; @@ -349,15 +194,12 @@ pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; gpios = <&tlmm 13 0>, - <&tlmm 80 0>, - <&tlmm 79 0>; + <&tlmm 9 0>; gpio-reset = <1>; - gpio-vana = <2>; - gpio-req-tbl-num = <0 1 2>; - gpio-req-tbl-flags = <1 0 0>; + gpio-req-tbl-num = <0 1>; + gpio-req-tbl-flags = <1 0>; gpio-req-tbl-label = "CAMIF_MCLK0", - "CAM_RESET0", - "CAM_VANA"; + "CAM_RESET0"; sensor-mode = <0>; cci-master = <0>; status = "ok"; @@ -404,49 +246,6 @@ clock-rates = <24000000>; }; - qcom,cam-sensor@2 { - cell-index = <2>; - compatible = "qcom,cam-sensor"; - reg = <0x02>; - csiphy-sd-index = <2>; - sensor-position-roll = <270>; - sensor-position-pitch = <0>; - sensor-position-yaw = <0>; - eeprom-src = <&eeprom_front>; - actuator-src = <&actuator_front>; - led-flash-src = <&led_flash_front>; - cam_vio-supply = <&pm8998_lvs1>; - cam_vana-supply = <&camera_vana_ldo>; - cam_vdig-supply = <&camera_ldo>; - cam_clk-supply = <&titan_top_gdsc>; - regulator-names = "cam_vio", "cam_vana", "cam_vdig", - "cam_clk"; - rgltr-cntrl-support; - rgltr-min-voltage = <0 2850000 1050000 0>; - rgltr-max-voltage = <0 2850000 1050000 0>; - rgltr-load-current = <0 80000 105000 0>; - gpio-no-mux = <0>; - pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk1_active - &cam_sensor_front_active>; - pinctrl-1 = <&cam_sensor_mclk1_suspend - &cam_sensor_front_suspend>; - gpios = <&tlmm 14 0>, - <&tlmm 28 0>; - gpio-reset = <1>; - gpio-req-tbl-num = <0 1>; - gpio-req-tbl-flags = <1 0>; - gpio-req-tbl-label = "CAMIF_MCLK2", - "CAM_RESET2"; - sensor-mode = <0>; - cci-master = <1>; - status = "ok"; - clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; - clock-names = "cam_clk"; - clock-cntl-level = "turbo"; - clock-rates = <24000000>; - }; - qcom,cam-sensor@3 { cell-index = <3>; compatible = "qcom,cam-sensor"; @@ -531,45 +330,4 @@ clock-cntl-level = "turbo"; clock-rates = <24000000>; }; - - qcom,cam-sensor@5 { - cell-index = <5>; - compatible = "qcom,cam-sensor"; - reg = <0x05>; - csiphy-sd-index = <1>; - sensor-position-roll = <270>; - sensor-position-pitch = <0>; - sensor-position-yaw = <0>; - led-flash-src = <>; - cam_vio-supply = <&pm8998_lvs1>; - cam_vana-supply = <&camera_vana_ldo>; - cam_vdig-supply = <&camera_ldo>; - cam_clk-supply = <&titan_top_gdsc>; - regulator-names = "cam_vio", "cam_vana", "cam_vdig", - "cam_clk"; - rgltr-cntrl-support; - rgltr-min-voltage = <0 2850000 1050000 0>; - rgltr-max-voltage = <0 2850000 1050000 0>; - rgltr-load-current = <0 80000 105000 0>; - gpio-no-mux = <0>; - pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk1_active - &cam_sensor_front_active>; - pinctrl-1 = <&cam_sensor_mclk1_suspend - &cam_sensor_front_suspend>; - gpios = <&tlmm 14 0>, - <&tlmm 28 0>; - gpio-reset = <1>; - gpio-req-tbl-num = <0 1>; - gpio-req-tbl-flags = <1 0>; - gpio-req-tbl-label = "CAMIF_MCLK2", - "CAM_RESET2"; - sensor-mode = <0>; - cci-master = <1>; - status = "ok"; - clocks = <&clock_camcc CAM_CC_MCLK1_CLK>; - clock-names = "cam_clk"; - clock-cntl-level = "turbo"; - clock-rates = <24000000>; - }; }; diff --git a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi index 9e5e6c651f01..a7a234a3670e 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi @@ -3620,6 +3620,15 @@ }; }; + camera_rear_avdd_en { + camera_rear_avdd_en_default: camera_rear_avdd_en_default { + pins = "gpio10"; + function = "normal"; + power-source = <0>; + output-low; + }; + }; + camera_rear_dvdd_en { camera_rear_dvdd_en_default: camera_rear_dvdd_en_default { pins = "gpio12"; From a42d482efe49c82ba2d665146ef0e9fd547f76f1 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Tue, 5 Dec 2017 09:48:14 +0530 Subject: [PATCH 089/281] drivers: mailbox: Use high priority tasklet The normal tasklets are deferred to ksoftirqd task context when a RT task is active on the CPU where tasklet is raised. Use high priority tasklet to avoid the delays. Change-Id: I955f524a4a01b968adc131efe301d1d66d802e8c Signed-off-by: Pavankumar Kondeti --- drivers/mailbox/qcom-rpmh-mailbox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mailbox/qcom-rpmh-mailbox.c b/drivers/mailbox/qcom-rpmh-mailbox.c index 16afda7e3e08..ad0842daf1ce 100644 --- a/drivers/mailbox/qcom-rpmh-mailbox.c +++ b/drivers/mailbox/qcom-rpmh-mailbox.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -404,7 +404,7 @@ static inline void send_tcs_response(struct tcs_response *resp) list_add_tail(&resp->list, &drv->response_pending); spin_unlock_irqrestore(&drv->drv_lock, flags); - tasklet_schedule(&drv->tasklet); + tasklet_hi_schedule(&drv->tasklet); } static inline void enable_tcs_irq(struct rsc_drv *drv, int m, bool enable) From c482dcf28086c7291dff3aba0427387bf1f428cf Mon Sep 17 00:00:00 2001 From: Kiran Gunda Date: Tue, 9 Jul 2019 12:21:24 +0530 Subject: [PATCH 090/281] ARM: dts: msm: Increase the "fg-bmd-en-delay" for sdm429w The default BMD delay of 200ms is not enough to settle down the batt_id. Hence, increase the delay to 300ms. Change-Id: I5b4d244a47d424401c3a58626682995fe81bc660 Signed-off-by: Kiran Gunda --- arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index d17c7bb60a76..50e6018ff9c6 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -571,6 +571,7 @@ qcom,fg-cutoff-current = <50>; qcom,fg-sync-sleep-threshold-ma = <30>; qcom,battery-data = <&mtp_batterydata>; + qcom,fg-bmd-en-delay-ms = <300>; qcom,fg-force-load-profile; qcom,fg-jeita-thresholds = <0 20 45 60>; status = "okay"; From 4f8e641363d023ed9a046b44934057d81c37aab3 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Thu, 4 Jul 2019 19:19:49 +0800 Subject: [PATCH 091/281] coresight: byte-cntr: stop reading byte-cntr when etr is diasbled Tmc etr buffer will be read when user runs 'cat /dev/byte-cntr'. If tmc etr is disabled, the buffer will be released. So exit byte-cntr-read when etr is disabled. Change-Id: Ie1a5367a76eec11563e4a5ff36f616ae40b620f2 Signed-off-by: Yuanfang Zhang --- drivers/hwtracing/coresight/coresight-byte-cntr.c | 6 +++--- drivers/hwtracing/coresight/coresight-tmc.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-byte-cntr.c b/drivers/hwtracing/coresight/coresight-byte-cntr.c index 9fa3e0f59441..6f80b607c1c8 100644 --- a/drivers/hwtracing/coresight/coresight-byte-cntr.c +++ b/drivers/hwtracing/coresight/coresight-byte-cntr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -237,6 +237,7 @@ void tmc_etr_byte_cntr_stop(struct byte_cntr *byte_cntr_data) mutex_lock(&byte_cntr_data->byte_cntr_lock); byte_cntr_data->enable = false; + byte_cntr_data->read_active = false; coresight_csr_set_byte_cntr(byte_cntr_data->csr, 0); mutex_unlock(&byte_cntr_data->byte_cntr_lock); @@ -264,7 +265,7 @@ static int tmc_etr_byte_cntr_open(struct inode *in, struct file *fp) mutex_lock(&byte_cntr_data->byte_cntr_lock); - if (!tmcdrvdata->enable || !byte_cntr_data->block_size) { + if (!byte_cntr_data->enable || !byte_cntr_data->block_size) { mutex_unlock(&byte_cntr_data->byte_cntr_lock); return -EINVAL; } @@ -277,7 +278,6 @@ static int tmc_etr_byte_cntr_open(struct inode *in, struct file *fp) fp->private_data = byte_cntr_data; nonseekable_open(in, fp); - byte_cntr_data->enable = true; byte_cntr_data->read_active = true; mutex_unlock(&byte_cntr_data->byte_cntr_lock); diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 8aed31a49a5f..51c57a47e5fc 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012, 2017-2019, The Linux Foundation. All rights reserved. * * Description: CoreSight Trace Memory Controller driver * @@ -469,6 +469,8 @@ static ssize_t out_mode_store(struct device *dev, coresight_cti_unmap_trigout(drvdata->cti_flush, 3, 0); coresight_cti_unmap_trigin(drvdata->cti_reset, 2, 0); + tmc_etr_byte_cntr_stop(drvdata->byte_cntr); + drvdata->usbch = usb_qdss_open("qdss", drvdata, usb_notifier); if (IS_ERR(drvdata->usbch)) { From 1c10806277980ecf8662ef72963dede7dcc5dd5f Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Tue, 18 Jun 2019 11:08:13 +0530 Subject: [PATCH 092/281] msm: vidc: Add checks to avoid OOB access validate structures and payload sizes in the packet against packet size to avoid OOB access. Change-Id: Id44e5c6be4dde3e6545d453f5edd3219776a4e58 Signed-off-by: Manikanta Kanamarlapudi --- .../platform/msm/vidc/hfi_response_handler.c | 93 +++++++++++++++---- 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index b50e641887cf..1e82d32dfe01 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -933,6 +933,21 @@ static enum vidc_status hfi_parse_init_done_properties( u32 prop_id, next_offset; u32 codecs = 0, domain = 0; +#define VALIDATE_PROPERTY_STRUCTURE_SIZE(pkt_size, property_size) ({\ + if (pkt_size < property_size) { \ + status = VIDC_ERR_BAD_PARAM; \ + break; \ + } \ +}) + +#define VALIDATE_PROPERTY_PAYLOAD_SIZE(pkt_size, payload_size, \ + property_count) ({\ + if (pkt_size/payload_size < property_count) { \ + status = VIDC_ERR_BAD_PARAM; \ + break; \ + } \ +}) + while (status == VIDC_ERR_NONE && num_properties && rem_bytes >= sizeof(u32)) { @@ -946,6 +961,10 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_codec_mask_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + codecs = prop->codecs; domain = prop->video_domains; next_offset += sizeof(struct hfi_codec_mask_supported); @@ -958,11 +977,14 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_capability_supported_info *) (data_ptr + next_offset); - if ((rem_bytes - next_offset) < prop->num_capabilities * - sizeof(struct hfi_capability_supported)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - sizeof(u32), + sizeof(struct hfi_capability_supported), + prop->num_capabilities); + next_offset += sizeof(u32) + prop->num_capabilities * sizeof(struct hfi_capability_supported); @@ -983,10 +1005,10 @@ static enum vidc_status hfi_parse_init_done_properties( char *fmt_ptr; struct hfi_uncompressed_plane_info *plane_info; - if ((rem_bytes - next_offset) < sizeof(*prop)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + num_format_entries = prop->format_entries; next_offset = sizeof(*prop); fmt_ptr = (char *)&prop->rg_format_info[0]; @@ -997,11 +1019,10 @@ static enum vidc_status hfi_parse_init_done_properties( plane_info = (struct hfi_uncompressed_plane_info *) fmt_ptr; - if ((rem_bytes - next_offset) < - sizeof(*plane_info)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*plane_info)); + bytes_to_skip = sizeof(*plane_info) - sizeof(struct hfi_uncompressed_plane_constraints) + @@ -1009,6 +1030,10 @@ static enum vidc_status hfi_parse_init_done_properties( sizeof(struct hfi_uncompressed_plane_constraints); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + bytes_to_skip); + fmt_ptr += bytes_to_skip; next_offset += bytes_to_skip; num_format_entries--; @@ -1021,6 +1046,15 @@ static enum vidc_status hfi_parse_init_done_properties( struct hfi_properties_supported *prop = (struct hfi_properties_supported *) (data_ptr + next_offset); + + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - sizeof(*prop) + + sizeof(u32), sizeof(u32), + prop->num_properties); + next_offset += sizeof(*prop) - sizeof(u32) + prop->num_properties * sizeof(u32); num_properties--; @@ -1032,6 +1066,15 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_profile_level_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - + sizeof(u32), + sizeof(struct hfi_profile_level), + prop->profile_count); + next_offset += sizeof(u32) + prop->profile_count * sizeof(struct hfi_profile_level); @@ -1056,6 +1099,10 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_nal_stream_format_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + copy_nal_stream_format_caps_to_sessions( prop->nal_stream_format_supported, capabilities, num_sessions, @@ -1068,12 +1115,18 @@ static enum vidc_status hfi_parse_init_done_properties( } case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(u32)); next_offset += sizeof(u32); num_properties--; break; } case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(struct hfi_intra_refresh)); next_offset += sizeof(struct hfi_intra_refresh); num_properties--; @@ -1081,6 +1134,9 @@ static enum vidc_status hfi_parse_init_done_properties( } case HFI_PROPERTY_TME_VERSION_SUPPORTED: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(u32)); capabilities->tme_version = *((u32 *)(data_ptr + next_offset)); next_offset += @@ -1094,8 +1150,13 @@ static enum vidc_status hfi_parse_init_done_properties( __func__, data_ptr, prop_id); break; } - rem_bytes -= next_offset; - data_ptr += next_offset; + + if (rem_bytes > next_offset) { + rem_bytes -= next_offset; + data_ptr += next_offset; + } else { + rem_bytes = 0; + } } return status; From 1dc4a359d2a23bae1a85f710fa3c6dd11a428733 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Mon, 8 Jul 2019 18:24:25 +0800 Subject: [PATCH 093/281] soc: qcom: fix invalid length can be configured to DCC Invalid length can't be configured to DCC. This change remove the design of setting length to 1 when length is 0. Change-Id: Idcc1cfa5c38be31cad60e25182aa789d5f8bb163 Signed-off-by: Yuanfang Zhang --- drivers/soc/qcom/dcc_v2.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/soc/qcom/dcc_v2.c b/drivers/soc/qcom/dcc_v2.c index afe304d2b8b9..1e977ca5dd06 100644 --- a/drivers/soc/qcom/dcc_v2.c +++ b/drivers/soc/qcom/dcc_v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, 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 @@ -1063,8 +1063,6 @@ static ssize_t dcc_store_config(struct device *dev, apb_bus = 1; } - if (len == 0) - len = 1; if (base == 0) { dev_err(drvdata->dev, "DCC: Invalid Address\n"); From f99808af8b29902520973bfb14950d76b0512ab6 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Tue, 9 Jul 2019 13:28:24 -0700 Subject: [PATCH 094/281] qseecom: decrease clk_access_cnt When scm_call returns EBUSY and app_access_lock is released, clk_access_cnt could be larger than 2 as a new qseecom thread may come to increase clk_access_cnt in this situation. So clk_access_cnt should be always decreased. Change-Id: I2400e807b9f15e3d7d8caad6978bfa93aa3cdd76 Signed-off-by: Zhen Kong --- drivers/misc/qseecom.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 00cf8e2d4358..b82f3859dd62 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -1496,20 +1496,17 @@ static int __qseecom_decrease_clk_ref_count(enum qseecom_ce_hw_instance ce) else qclk = &qseecom.ce_drv; - if (qclk->clk_access_cnt > 2) { + if (qclk->clk_access_cnt > 0) { + qclk->clk_access_cnt--; + } else { pr_err("Invalid clock ref count %d\n", qclk->clk_access_cnt); ret = -EINVAL; - goto err_dec_ref_cnt; } - if (qclk->clk_access_cnt == 2) - qclk->clk_access_cnt--; -err_dec_ref_cnt: mutex_unlock(&clk_access_lock); return ret; } - static int qseecom_scale_bus_bandwidth_timer(uint32_t mode) { int32_t ret = 0; From 6757b96a511a6d76b699e9ab53366827447dc3b1 Mon Sep 17 00:00:00 2001 From: Xiao Li Date: Sat, 6 Jul 2019 17:18:28 +0800 Subject: [PATCH 095/281] ASoC: aw8896: add logic to handle regulator for DVDD aw8896's DVDD is not powered by default, add logic to read regulator info from device tree, and enable power for DVDD in the driver probe function. Change-Id: I544ef3e8e7f273f868cefc6a3ff27b6e7f9ed768 Signed-off-by: Xiao Li --- .../devicetree/bindings/sound/aw8896.txt | 11 ++- sound/soc/codecs/aw8896.c | 85 ++++++++++++++++++- sound/soc/codecs/aw8896.h | 9 ++ 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/aw8896.txt b/Documentation/devicetree/bindings/sound/aw8896.txt index e74ce6711105..c96b3675deff 100644 --- a/Documentation/devicetree/bindings/sound/aw8896.txt +++ b/Documentation/devicetree/bindings/sound/aw8896.txt @@ -6,7 +6,13 @@ Required properties: - reg : I2C address of the device - - reset-gpio: gpio used for HW reset + - reset-gpio : gpio used for HW reset + + - dvdd-supply : Power supply for PA's dvdd + + - dvdd-voltage : Minimum and maximum voltage in uV to set for power supply + + - dvdd-current : dvdd's max current in uA Optional properties: @@ -18,4 +24,7 @@ Examples: compatible = "awinic,i2c_smartpa"; reg = <0x34>; reset-gpio = <&tlmm 68 0>; + dvdd-supply = <&pm660_l9>; + dvdd-voltage = <1800000 1800000>; + dvdd-current = <15000>; }; diff --git a/sound/soc/codecs/aw8896.c b/sound/soc/codecs/aw8896.c index dbc7cd8cfbff..2592b480a4a3 100644 --- a/sound/soc/codecs/aw8896.c +++ b/sound/soc/codecs/aw8896.c @@ -43,6 +43,7 @@ #define AW_READ_CHIPID_RETRIES 5 #define AW_READ_CHIPID_RETRY_DELAY 5 #define AW8896_MAX_DSP_START_TRY_COUNT 10 +#define DT_MAX_PROP_SIZE 80 static int aw8896_spk_control; static int aw8896_rcv_control; @@ -1068,6 +1069,14 @@ static irqreturn_t aw8896_irq(int irq, void *data) static int aw8896_parse_dt(struct device *dev, struct aw8896 *aw8896, struct device_node *np) { + int prop_val = 0; + int ret = 0; + int len = 0; + const __be32 *prop = NULL; + struct device_node *regnode = NULL; + char *dvdd_supply = "dvdd"; + char prop_name[DT_MAX_PROP_SIZE] = {0}; + aw8896->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); if (aw8896->reset_gpio < 0) { dev_err(dev, @@ -1082,7 +1091,47 @@ static int aw8896_parse_dt(struct device *dev, struct aw8896 *aw8896, if (aw8896->irq_gpio < 0) dev_info(dev, "%s: no irq gpio provided.\n", __func__); + snprintf(prop_name, DT_MAX_PROP_SIZE, "%s-supply", dvdd_supply); + regnode = of_parse_phandle(np, prop_name, 0); + if (!regnode) { + dev_err(dev, "%s: no %s provided\n", __func__, prop_name); + goto err_get_regulator; + } + + aw8896->supply.regulator = devm_regulator_get(dev, dvdd_supply); + if (IS_ERR(aw8896->supply.regulator)) { + dev_err(dev, "%s: failed to get supply for %s\n", __func__, + dvdd_supply); + goto err_get_regulator; + } + + snprintf(prop_name, DT_MAX_PROP_SIZE, "%s-voltage", dvdd_supply); + prop = of_get_property(np, prop_name, &len); + if (!prop || (len != (2 * sizeof(__be32)))) { + dev_err(dev, "%s: no %s provided or format invalid\n", + __func__, prop_name); + goto err_get_voltage; + } + + aw8896->supply.min_uv = be32_to_cpup(&prop[0]); + aw8896->supply.max_uv = be32_to_cpup(&prop[1]); + + snprintf(prop_name, DT_MAX_PROP_SIZE, "%s-current", dvdd_supply); + ret = of_property_read_u32(np, prop_name, &prop_val); + if (ret) { + dev_err(dev, "%s: no %s provided\n", __func__, prop_name); + goto err_get_current; + } + aw8896->supply.ua = prop_val; + return 0; + +err_get_current: +err_get_voltage: + devm_regulator_put(aw8896->supply.regulator); + aw8896->supply.regulator = NULL; +err_get_regulator: + return -EINVAL; } int aw8896_hw_reset(struct aw8896 *aw8896) @@ -1354,7 +1403,7 @@ static int aw8896_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, aw8896); mutex_init(&aw8896->lock); - /* aw8896 rst & int */ + if (np) { ret = aw8896_parse_dt(&i2c->dev, aw8896, np); if (ret) { @@ -1388,6 +1437,30 @@ static int aw8896_i2c_probe(struct i2c_client *i2c, } } + ret = regulator_set_voltage(aw8896->supply.regulator, + aw8896->supply.max_uv, + aw8896->supply.min_uv); + if (ret) { + dev_err(&i2c->dev, "%s: set voltage %d ~ %d failed\n", + __func__, + aw8896->supply.min_uv, + aw8896->supply.max_uv); + goto err_supply_set; + } + + ret = regulator_set_load(aw8896->supply.regulator, aw8896->supply.ua); + if (ret < 0) { + dev_err(&i2c->dev, "%s: set current %d failed\n", __func__, + aw8896->supply.ua); + goto err_supply_set; + } + + ret = regulator_enable(aw8896->supply.regulator); + if (ret < 0) { + dev_err(&i2c->dev, "%s: regulator enable failed\n", __func__); + goto err_supply_set; + } + ret = aw8896_hw_reset(aw8896); if (ret < 0) { dev_err(&i2c->dev, "%s: aw8896_hw_reset failed\n", __func__); @@ -1461,6 +1534,11 @@ static int aw8896_i2c_probe(struct i2c_client *i2c, if (gpio_is_valid(aw8896->irq_gpio)) devm_gpio_free(&i2c->dev, aw8896->irq_gpio); err_hw_rst: + if (aw8896->supply.regulator) + regulator_disable(aw8896->supply.regulator); +err_supply_set: + if (aw8896->supply.regulator) + devm_regulator_put(aw8896->supply.regulator); err_irq_gpio_request: if (gpio_is_valid(aw8896->reset_gpio)) devm_gpio_free(&i2c->dev, aw8896->reset_gpio); @@ -1486,6 +1564,11 @@ static int aw8896_i2c_remove(struct i2c_client *i2c) if (gpio_is_valid(aw8896->reset_gpio)) devm_gpio_free(&i2c->dev, aw8896->reset_gpio); + if (aw8896->supply.regulator) { + regulator_disable(aw8896->supply.regulator); + devm_regulator_put(aw8896->supply.regulator); + } + devm_kfree(&i2c->dev, aw8896); aw8896 = NULL; diff --git a/sound/soc/codecs/aw8896.h b/sound/soc/codecs/aw8896.h index 48e01ca11c6f..5663cb21115c 100644 --- a/sound/soc/codecs/aw8896.h +++ b/sound/soc/codecs/aw8896.h @@ -15,6 +15,7 @@ #ifndef _AW8896_H_ #define _AW8896_H_ +#include /* * i2c transaction on Linux limited to 64k @@ -81,10 +82,18 @@ enum aw8896_dsp_cfg_state { AW8896_DSP_CFG_OK, }; +struct dvdd_supply { + struct regulator *regulator; + int min_uv; + int max_uv; + int ua; +}; + struct aw8896 { struct regmap *regmap; struct i2c_client *i2c; struct snd_soc_codec *codec; + struct dvdd_supply supply; struct mutex lock; int dsp_init; int dsp_fw_state; From d4a2a43e1c43616e4fde265f2bc2362d476d3e7f Mon Sep 17 00:00:00 2001 From: jjunliu Date: Wed, 10 Jul 2019 13:55:05 +0800 Subject: [PATCH 096/281] ARM: dts: msm: Enable display on SDM845 RB3 Camera and GPU test will fail because of display disabled. So enable display settings same as SDM845 MTP on SDM845 RB3. Change-Id: I3a8c0c5d1ae73988f9dbb732acc8cde238043b8a Signed-off-by: Jun Liu --- arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi index 13910803eb00..ffb59552c602 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi @@ -21,14 +21,6 @@ #include "sdm845-rb3.dtsi" #include "sdm845-audio-overlay.dtsi" -&labibb { - status = "disabled"; -}; - -&pmi8998_wled { - status = "disabled"; -}; - &qupv3_se3_i2c { status = "disabled"; }; @@ -41,10 +33,6 @@ status = "ok"; }; -&ext_5v_boost { - status = "disabled"; -}; - &wil6210 { status = "disabled"; }; @@ -83,14 +71,6 @@ pins = "gpio11"; }; -&sde_dp { - status = "disabled"; -}; - -&mdss_mdp { - status = "disabled"; -}; - &soc { qcom,qbt1000 { compatible = "qcom,qbt1000"; From 8b1d9b7b35d84f23f1786c85beefc688b9c7e0eb Mon Sep 17 00:00:00 2001 From: Xipeng Gu Date: Thu, 11 Jul 2019 14:22:55 +0800 Subject: [PATCH 097/281] clk: msm: mdss: fix incorrect log parameters The pr_err log parameters is not accurate sequence, make it right sequence. Change-Id: I1838fa80ec3aa048bc60a5bf12a9cff76c62e1db Signed-off-by: Xipeng Gu --- drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c b/drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c index e502826d3973..1baf5347b3e4 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c +++ b/drivers/clk/msm/mdss/mdss-dsi-pll-12nm-util.c @@ -900,7 +900,7 @@ int pll_vco_prepare_12nm(struct clk *c) rc = c->ops->set_rate(c, pll->vco_cached_rate); if (rc) { pr_err("index=%d vco_set_rate failed. rc=%d\n", - rc, pll->index); + pll->index, rc); goto error; } } From 81e13dcb286d5d1d28efba282cc90dbadd8f4f85 Mon Sep 17 00:00:00 2001 From: Rahul Shahare Date: Mon, 3 Jun 2019 17:43:40 +0530 Subject: [PATCH 098/281] defconfig: msm: Disable CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE flag To support Boot image with header version v2, Disable CONFIG_BUILD_ARM64_APPENDED_DTB flag in defconfig and perf_defconfig for sdm670. Change-Id: I4b0b461bd5321f52c4acc67135f49c78a8250522 Signed-off-by: Rahul Shahare --- arch/arm64/configs/sdm670-perf_defconfig | 1 - arch/arm64/configs/sdm670_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig index 386de917f721..58aabffd6c6c 100755 --- a/arch/arm64/configs/sdm670-perf_defconfig +++ b/arch/arm64/configs/sdm670-perf_defconfig @@ -75,7 +75,6 @@ CONFIG_SETEND_EMULATION=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y # CONFIG_EFI is not set -CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y CONFIG_PM_AUTOSLEEP=y diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig index 1558f6a957e0..a9f8f6532276 100755 --- a/arch/arm64/configs/sdm670_defconfig +++ b/arch/arm64/configs/sdm670_defconfig @@ -79,7 +79,6 @@ CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y -CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y CONFIG_PM_AUTOSLEEP=y From 54baff71953bba74981db99d70ebc1be4c5e314c Mon Sep 17 00:00:00 2001 From: Baochu Xu Date: Thu, 27 Jun 2019 16:39:18 +0800 Subject: [PATCH 099/281] ARM: dts: msm: Select audio PA for SDM429W Select PA for audio machine driver for SDM429W. Change-Id: Iaa42f5568926215db48ff00fe410064175fb0369 Signed-off-by: Baochu Xu --- arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi index 78cd72f2008b..eaa844b372cb 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi @@ -592,8 +592,8 @@ /delete-property/qcom,cdc-us-eu-gpios; - asoc-codec = <&stub_codec>, <&msm_dig_codec>; - asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec"; + asoc-codec = <&stub_codec>, <&msm_dig_codec>, <&ext_smart_pa>; + asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec", "ext-smart-pa"; }; &soc { @@ -655,7 +655,7 @@ }; &i2c_2 { - aw8896_smartpa@34 { + ext_smart_pa: aw8896_smartpa@34 { compatible = "awinic,aw8896_smartpa"; reg = <0x34>; reset-gpio = <&tlmm 68 0>; From 01252c2720cc1d38249702b702032d4b65c69390 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 27 Jun 2019 22:10:15 -0700 Subject: [PATCH 100/281] ARM: dts: msm: Rename SA415M dts files The automotive chip name is SA415M so rename the device tree files for CCARD and TTP accordingly. Change-Id: I9250822428349bd6cad5b364b5af2bec28816ec8 Signed-off-by: Gustavo Solaira --- .../devicetree/bindings/arm/msm/msm.txt | 4 +-- arch/arm/boot/dts/qcom/Makefile | 9 +++--- ...d-pcie-ep.dts => sa415m-ccard-pcie-ep.dts} | 4 +-- ...ard-usb-ep.dts => sa415m-ccard-usb-ep.dts} | 4 +-- ...dxpoorwills-ccard.dts => sa415m-ccard.dts} | 4 +-- ...poorwills-ccard.dtsi => sa415m-ccard.dtsi} | 2 +- arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts | 31 +++++++++++++++++++ ...sdxpoorwills-v2-ttp.dts => sa415m-ttp.dts} | 6 ++-- ...{sdxpoorwills-ttp.dtsi => sa415m-ttp.dtsi} | 0 9 files changed, 48 insertions(+), 16 deletions(-) rename arch/arm/boot/dts/qcom/{sdxpoorwills-ccard-pcie-ep.dts => sa415m-ccard-pcie-ep.dts} (92%) rename arch/arm/boot/dts/qcom/{sdxpoorwills-ccard-usb-ep.dts => sa415m-ccard-usb-ep.dts} (89%) rename arch/arm/boot/dts/qcom/{sdxpoorwills-ccard.dts => sa415m-ccard.dts} (89%) rename arch/arm/boot/dts/qcom/{sdxpoorwills-ccard.dtsi => sa415m-ccard.dtsi} (99%) create mode 100644 arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts rename arch/arm/boot/dts/qcom/{sdxpoorwills-v2-ttp.dts => sa415m-ttp.dts} (84%) rename arch/arm/boot/dts/qcom/{sdxpoorwills-ttp.dtsi => sa415m-ttp.dtsi} (100%) diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index 4f8e4f518a8c..67060d309164 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -410,6 +410,6 @@ compatible = "qcom,sdxpoorwills-rumi" compatible = "qcom,sdxpoorwills-atp" compatible = "qcom,sdxpoorwills-mtp" compatible = "qcom,sdxpoorwills-cdp" -compatible = "qcom,sdxpoorwills-ttp" -compatible = "qcom,sdxpoorwills-ccard" +compatible = "qcom,sa415m-ttp" +compatible = "qcom,sa415m-ccard" compatible = "qcom,mdm9607-ttp" diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 17524cf129dc..ff0ae9a96e54 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -3,7 +3,7 @@ dtb-$(CONFIG_ARCH_SDXPOORWILLS) += sdxpoorwills-rumi.dtb \ sdxpoorwills-cdp.dtb \ sdxpoorwills-mtp.dtb \ sdxpoorwills-atp.dtb \ - sdxpoorwills-v2-ttp.dtb \ + sa415m-ttp.dtb \ sdxpoorwills-cdp-256.dtb \ sdxpoorwills-mtp-256.dtb \ sdxpoorwills-dualwifi-cdp.dtb \ @@ -16,9 +16,10 @@ dtb-$(CONFIG_ARCH_SDXPOORWILLS) += sdxpoorwills-rumi.dtb \ sdxpoorwills-v2-cdp.dtb \ sdxpoorwills-v2-dualwifi-mtp.dtb \ sdxpoorwills-v2-dualwifi-cdp.dtb \ - sdxpoorwills-ccard.dtb \ - sdxpoorwills-ccard-pcie-ep.dtb \ - sdxpoorwills-ccard-usb-ep.dtb \ + sa415m-ccard.dtb \ + sa415m-ccard-pcie-ep.dtb \ + sa415m-ccard-usb-ep.dtb \ + sa415m-ttp-usb-ep.dtb \ sdxpoorwills-v2-pcie-ep-mtp-256.dtb \ sdxpoorwills-v2-pcie-ep-mtp.dtb diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard-pcie-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts similarity index 92% rename from arch/arm/boot/dts/qcom/sdxpoorwills-ccard-pcie-ep.dts rename to arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts index c7bf2bd31c35..adc30bcac1dc 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard-pcie-ep.dts +++ b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "sdxpoorwills-ccard.dtsi" +#include "sa415m-ccard.dtsi" / { model = "Qualcomm Technologies, Inc. SA415M CCARD PCIE-EP"; - compatible = "qcom,sdxpoorwills-ccard", + compatible = "qcom,sa415m-ccard", "qcom,sdxpoorwills", "qcom,ccard"; qcom,board-id = <25 1>, <25 0x101>; }; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard-usb-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts similarity index 89% rename from arch/arm/boot/dts/qcom/sdxpoorwills-ccard-usb-ep.dts rename to arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts index 9f0764e363bc..1cf3a55a09b8 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard-usb-ep.dts +++ b/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "sdxpoorwills-ccard.dtsi" +#include "sa415m-ccard.dtsi" / { model = "Qualcomm Technologies, Inc. SA415M CCARD USB-EP"; - compatible = "qcom,sdxpoorwills-ccard", + compatible = "qcom,sa415m-ccard", "qcom,sdxpoorwills", "qcom,ccard"; qcom,board-id = <25 2>, <25 0x102>; }; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard.dts b/arch/arm/boot/dts/qcom/sa415m-ccard.dts similarity index 89% rename from arch/arm/boot/dts/qcom/sdxpoorwills-ccard.dts rename to arch/arm/boot/dts/qcom/sa415m-ccard.dts index b9acf1ced6f0..a0212fc9c3df 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard.dts +++ b/arch/arm/boot/dts/qcom/sa415m-ccard.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "sdxpoorwills-ccard.dtsi" +#include "sa415m-ccard.dtsi" / { model = "Qualcomm Technologies, Inc. SA415M CCARD"; - compatible = "qcom,sdxpoorwills-ccard", + compatible = "qcom,sa415m-ccard", "qcom,sdxpoorwills", "qcom,ccard"; qcom,board-id = <25 0>, <25 0x100>; }; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard.dtsi b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi similarity index 99% rename from arch/arm/boot/dts/qcom/sdxpoorwills-ccard.dtsi rename to arch/arm/boot/dts/qcom/sa415m-ccard.dtsi index d327aa35e437..f3c6f748751b 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-ccard.dtsi +++ b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi @@ -10,7 +10,7 @@ * GNU General Public License for more details. */ -#include "sdxpoorwills-ttp.dtsi" +#include "sa415m-ttp.dtsi" #include "sdxpoorwills-v2.dtsi" &blsp1_uart2b_hs { diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts new file mode 100644 index 000000000000..802e831930fa --- /dev/null +++ b/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts @@ -0,0 +1,31 @@ +/* Copyright (c) 2017-2019, 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 "sa415m-ttp.dtsi" +#include "sdxpoorwills-v2.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA415M TTP USB-EP"; + compatible = "qcom,sa415m-ttp", + "qcom,sdxpoorwills", "qcom,ttp"; + qcom,board-id = <30 0x102>; +}; + +&blsp1_uart2b_hs { + status = "okay"; +}; + +&mss_mem { + reg = <0x86400000 0x9300000>; +}; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-v2-ttp.dts b/arch/arm/boot/dts/qcom/sa415m-ttp.dts similarity index 84% rename from arch/arm/boot/dts/qcom/sdxpoorwills-v2-ttp.dts rename to arch/arm/boot/dts/qcom/sa415m-ttp.dts index a686c4b69528..d83eb685f8c7 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-v2-ttp.dts +++ b/arch/arm/boot/dts/qcom/sa415m-ttp.dts @@ -12,12 +12,12 @@ /dts-v1/; -#include "sdxpoorwills-ttp.dtsi" +#include "sa415m-ttp.dtsi" #include "sdxpoorwills-v2.dtsi" / { - model = "Qualcomm Technologies, Inc. SDXPOORWILLS TTP V2"; - compatible = "qcom,sdxpoorwills-ttp", + model = "Qualcomm Technologies, Inc. SA415M TTP V2"; + compatible = "qcom,sa415m-ttp", "qcom,sdxpoorwills", "qcom,ttp"; qcom,board-id = <30 0x100>; }; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dtsi b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi similarity index 100% rename from arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dtsi rename to arch/arm/boot/dts/qcom/sa415m-ttp.dtsi From aae6a21c58a398a3f3ed6aa4b9fa3f149b7de849 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 20 Jun 2019 17:42:13 -0700 Subject: [PATCH 101/281] ARM: dts: msm: Enable 1.8V RGMII mode on SA415M CCARD Enable 1.8V for SA415M CCARD board. Move PMIC pinctrl settings to the pinctrl dtsi file. Enable GPIO_09 only for CCARD boards which use 1.8V to drive RGMII IO lines. Change-Id: I58561d9fa633a6b108bf34a6020f96dfa6343e39 Acked-by: Rahul Kawadgave Signed-off-by: Gustavo Solaira --- arch/arm/boot/dts/qcom/pmxpoorwills.dtsi | 8 +++++--- arch/arm/boot/dts/qcom/sa415m-ccard.dtsi | 17 +++++++++-------- .../arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi | 17 +++++++++++++++++ .../boot/dts/qcom/sdxpoorwills-regulator.dtsi | 6 +++--- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/arch/arm/boot/dts/qcom/pmxpoorwills.dtsi b/arch/arm/boot/dts/qcom/pmxpoorwills.dtsi index 08e306d8f802..fb88e76df546 100644 --- a/arch/arm/boot/dts/qcom/pmxpoorwills.dtsi +++ b/arch/arm/boot/dts/qcom/pmxpoorwills.dtsi @@ -60,16 +60,18 @@ <0x0 0xc2 0 IRQ_TYPE_NONE>, <0x0 0xc3 0 IRQ_TYPE_NONE>, <0x0 0xc4 0 IRQ_TYPE_NONE>, - <0x0 0xc5 0 IRQ_TYPE_NONE>; + <0x0 0xc5 0 IRQ_TYPE_NONE>, + <0x0 0xc8 0 IRQ_TYPE_NONE>; interrupt-names = "pmxpoorwills_gpio1", "pmxpoorwills_gpio2", "pmxpoorwills_gpio3", "pmxpoorwills_gpio4", "pmxpoorwills_gpio5", - "pmxpoorwills_gpio6"; + "pmxpoorwills_gpio6", + "pmxpoorwills_gpio9"; gpio-controller; #gpio-cells = <2>; - qcom,gpios-disallowed = <7 8 9>; + qcom,gpios-disallowed = <7 8>; }; pmxpoorwills_rtc: qcom,pmxpoorwills_rtc { diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi index f3c6f748751b..aa708e6d43d1 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi +++ b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi @@ -141,12 +141,13 @@ }; }; -&pmxpoorwills_gpios { - a2b_cdc_sel { - a2b_cdc_sel_default: a2b_cdc_sel_default { - pins = "gpio1"; - power-source = <1>; - output-high; - }; - }; +&emac_hw { + /delete-property/ vreg_rgmii-supply; + pinctrl-names = "default"; + pinctrl-0 = <&vreg_rgmii_off_default>; +}; + +&vreg_rgmii_io_pads { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; }; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi index 8c11e09f696c..09a62190ba00 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi @@ -1755,6 +1755,14 @@ }; &pmxpoorwills_gpios { + a2b_cdc_sel { + a2b_cdc_sel_default: a2b_cdc_sel_default { + pins = "gpio1"; + power-source = <1>; + output-high; + }; + }; + ambient_therm { ambient_therm_default: ambient_therm_default { pins = "gpio2"; @@ -1768,4 +1776,13 @@ bias-high-impedance; }; }; + + vreg_rgmii_off { + vreg_rgmii_off_default: vreg_rgmii_off_default { + pins = "gpio9"; + bias-pull-down; + output-disable; + input-enable; + }; + }; }; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi index 7543f7caa6b9..70dc3aecc750 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills-regulator.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -398,8 +398,8 @@ vreg_rgmii_io_pads: rgmii_io_pads_regulator { compatible = "regulator-fixed"; regulator-name = "rgmii_io_pads"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; regulator-enable-ramp-delay = <100>; gpio = <&tlmm 83 GPIO_ACTIVE_HIGH>; enable-active-high; From 3cf3290c182258a3d767fd331209f6e4a09fa514 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Thu, 20 Jun 2019 21:11:50 +0530 Subject: [PATCH 102/281] msm: mhi_dev: add random mac generation and ethernet parse support Host can generate Ethernet packets over the network stack. Add support to assign proper protocol for ethernet packets. Also, add support for mhi net device for random mac address generation. Change-Id: Icd29e7df9aff0529ebaf4897560d9a9acec76fd7 Signed-off-by: Rama Krishna Phani A --- .../devicetree/bindings/mhi/msm_mhi_dev.txt | 17 ++++ drivers/platform/msm/mhi_dev/mhi_dev_net.c | 89 +++++++++++++++++-- 2 files changed, 100 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/mhi/msm_mhi_dev.txt b/Documentation/devicetree/bindings/mhi/msm_mhi_dev.txt index 30174680a91d..ece30e43d308 100644 --- a/Documentation/devicetree/bindings/mhi/msm_mhi_dev.txt +++ b/Documentation/devicetree/bindings/mhi/msm_mhi_dev.txt @@ -31,6 +31,18 @@ Optional property: MHI driver on the host. This property is required if iatu property qcom,mhi-config-iatu is present. +MSM MHI DEV NET + +MSM MHI DEV enables communication with the host over a PCIe link using the +Network Interface. + +Required properties: + - compatible: should be "qcom,msm-mhi-dev-net" for MHI net device driver. + +Optional property: + - qcom,mhi-ethernet-interface;: If property is present use ethernet packet + parsing support. + Example: mhi: qcom,msm-mhi-dev { @@ -44,3 +56,8 @@ Example: qcom,mhi-ep-msi = <1>; qcom,mhi-version = <0x1000000>; }; + + qcom,mhi_net_dev { + compatible = "qcom,msm-mhi-dev-net"; + qcom,mhi-ethernet-interface; + }; diff --git a/drivers/platform/msm/mhi_dev/mhi_dev_net.c b/drivers/platform/msm/mhi_dev/mhi_dev_net.c index d1f86a476f46..c78f20cd78d9 100644 --- a/drivers/platform/msm/mhi_dev/mhi_dev_net.c +++ b/drivers/platform/msm/mhi_dev/mhi_dev_net.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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,11 +27,13 @@ #include #include #include +#include +#include #include "mhi.h" #define MHI_NET_DRIVER_NAME "mhi_dev_net_drv" -#define MHI_NET_DEV_NAME "mhi_dev_net%d" +#define MHI_NET_DEV_NAME "mhi_swip%d" #define MHI_NET_DEFAULT_MTU 8192 #define MHI_NET_IPC_PAGES (100) #define MHI_MAX_RX_REQ (128) @@ -90,6 +92,7 @@ struct mhi_dev_net_client { u32 out_chan; /* read channel - always odd */ u32 in_chan; + bool eth_iface; struct mhi_dev_client *out_handle; struct mhi_dev_client *in_handle; /*process pendig packets */ @@ -113,6 +116,7 @@ struct mhi_dev_net_client { struct mhi_dev_net_ctxt { struct mhi_dev_net_chan_attr chan_attr[MHI_MAX_SOFTWARE_CHANNELS]; struct mhi_dev_net_client *client_handle; + struct platform_device *pdev; void (*net_event_notifier)(struct mhi_dev_client_cb_reason *cb); }; @@ -247,8 +251,12 @@ static void mhi_dev_net_read_completion_cb(void *req) unsigned long flags; skb->len = mreq->transfer_len; - skb->protocol = - mhi_dev_net_eth_type_trans(skb); + + if (net_handle->eth_iface) + skb->protocol = eth_type_trans(skb, net_handle->dev); + else + skb->protocol = mhi_dev_net_eth_type_trans(skb); + skb_put(skb, mreq->transfer_len); net_handle->dev->stats.rx_packets++; skb->dev = net_handle->dev; @@ -433,12 +441,15 @@ static const struct net_device_ops mhi_dev_net_ops_ip = { .ndo_change_mtu = mhi_dev_net_change_mtu, }; -static void mhi_dev_net_setup(struct net_device *dev) +static void mhi_dev_net_rawip_setup(struct net_device *dev) { dev->netdev_ops = &mhi_dev_net_ops_ip; ether_setup(dev); + mhi_dev_net_log(MHI_INFO, + "mhi_dev_net Raw IP setup\n"); /* set this after calling ether_setup */ + dev->header_ops = NULL; dev->type = ARPHRD_RAWIP; dev->hard_header_len = 0; dev->mtu = MHI_NET_DEFAULT_MTU; @@ -446,6 +457,14 @@ static void mhi_dev_net_setup(struct net_device *dev) dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); } +static void mhi_dev_net_ether_setup(struct net_device *dev) +{ + dev->netdev_ops = &mhi_dev_net_ops_ip; + ether_setup(dev); + mhi_dev_net_log(MHI_INFO, + "mhi_dev_net Ethernet setup\n"); +} + static int mhi_dev_net_enable_iface(struct mhi_dev_net_client *mhi_dev_net_ptr) { int ret = 0; @@ -462,12 +481,20 @@ static int mhi_dev_net_enable_iface(struct mhi_dev_net_client *mhi_dev_net_ptr) "mhi_dev_net interface registration\n"); netdev = alloc_netdev(sizeof(struct mhi_dev_net_client), MHI_NET_DEV_NAME, NET_NAME_PREDICTABLE, - mhi_dev_net_setup); + mhi_net_ctxt.client_handle->eth_iface ? + mhi_dev_net_ether_setup : + mhi_dev_net_rawip_setup); if (!netdev) { pr_err("Failed to allocate netdev for mhi_dev_net\n"); goto net_dev_alloc_fail; } + if (mhi_net_ctxt.client_handle->eth_iface) { + eth_random_addr(netdev->dev_addr); + if (!is_valid_ether_addr(netdev->dev_addr)) + return -EADDRNOTAVAIL; + } + mhi_dev_net_ctxt = netdev_priv(netdev); mhi_dev_net_ptr->dev = netdev; *mhi_dev_net_ctxt = mhi_dev_net_ptr; @@ -621,6 +648,12 @@ int mhi_dev_net_interface_init(void) "Failed to create IPC logging for mhi_dev_net\n"); mhi_net_ctxt.client_handle = mhi_net_client; + if (mhi_net_ctxt.pdev) + mhi_net_ctxt.client_handle->eth_iface = + of_property_read_bool + ((&mhi_net_ctxt.pdev->dev)->of_node, + "qcom,mhi-ethernet-interface"); + /*Process pending packet work queue*/ mhi_net_client->pending_pckt_wq = create_singlethread_workqueue("pending_xmit_pckt_wq"); @@ -665,3 +698,47 @@ void __exit mhi_dev_net_exit(void) mhi_dev_net_close(); } EXPORT_SYMBOL(mhi_dev_net_exit); + +static int mhi_dev_net_probe(struct platform_device *pdev) +{ + if (pdev->dev.of_node) { + mhi_net_ctxt.pdev = pdev; + mhi_dev_net_log(MHI_INFO, + "MHI Network probe success"); + } + + return 0; +} + +static int mhi_dev_net_remove(struct platform_device *pdev) +{ + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id mhi_dev_net_match_table[] = { + { .compatible = "qcom,msm-mhi-dev-net" }, + {} +}; + +static struct platform_driver mhi_dev_net_driver = { + .driver = { + .name = "qcom,msm-mhi-dev-net", + .of_match_table = mhi_dev_net_match_table, + }, + .probe = mhi_dev_net_probe, + .remove = mhi_dev_net_remove, +}; + +static int __init mhi_dev_net_init(void) +{ + return platform_driver_register(&mhi_dev_net_driver); +} +subsys_initcall(mhi_dev_net_init); + +static void __exit mhi_dev_exit(void) +{ + platform_driver_unregister(&mhi_dev_net_driver); +} +module_exit(mhi_dev_net_exit); From b3a7cf1ebb4553c3deafee1c01b20909e2cd23bf Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Thu, 4 Jul 2019 20:11:49 +0530 Subject: [PATCH 103/281] ARM: dts: msm: add MHI NET devicetree node for sdxpoorwills Add initial devicetree node to support MHI NET based devices over PCIe on sdxpoorwills. Change-Id: I59a305b89daba546b708ee06292f4ca648bd33bb Signed-off-by: Rama Krishna Phani A --- arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts | 4 ++++ arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi | 4 ++++ arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi | 4 ++++ arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi | 4 ++++ arch/arm/boot/dts/qcom/sdxpoorwills.dtsi | 6 ++++++ 5 files changed, 22 insertions(+) diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts index adc30bcac1dc..c2a447b300bb 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts +++ b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts @@ -52,3 +52,7 @@ &ipc_router_mhi_dev_xprt { status = "okay"; }; + +&mhi_net_device { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi index ba29301a8a17..1f0782591ee3 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi @@ -39,6 +39,10 @@ status = "okay"; }; +&mhi_net_device { + status = "okay"; +}; + &restart_pshold { qcom,force-warm-reboot; }; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi index 43490bfae4b0..f139ba985ab2 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi @@ -36,6 +36,10 @@ status = "okay"; }; +&mhi_net_device { + status = "okay"; +}; + &restart_pshold { qcom,force-warm-reboot; }; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi index d2fe3be7a278..14e70bc14069 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi @@ -39,6 +39,10 @@ status = "okay"; }; +&mhi_net_device { + status = "okay"; +}; + &restart_pshold { qcom,force-warm-reboot; }; diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi index 02a1bf9602e3..abbc8b5a7f65 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi @@ -520,6 +520,12 @@ status = "disabled"; }; + mhi_net_device: qcom,mhi_net_dev { + compatible = "qcom,msm-mhi-dev-net"; + qcom,mhi-ethernet-interface; + status = "disabled"; + }; + gdsc_emac: qcom,gdsc@147004 { compatible = "qcom,gdsc"; regulator-name = "gdsc_emac"; From af12767b8c83f20ea962b232c1d83c7a5866bb53 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Mon, 10 Jun 2019 13:06:41 -0700 Subject: [PATCH 104/281] qseecom: use scm_call2 for shutdown app Unlike scm_call2, __qseecom_scm_call2_locked() will unlock app_access_lock to let another qseecom thread work. But this mutex should not be released for shutdown app thread to prevent another thread accessing the resource that is freed by shutdown thread. So change to use scm_call2 for this cmd. Change-Id: Ifdd526e0b401cab5c9d6df71d5854022e0f273f0 Signed-off-by: Zhen Kong --- drivers/misc/qseecom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 00cf8e2d4358..6611b2222002 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -534,7 +534,7 @@ static int qseecom_scm_call2(uint32_t svc_id, uint32_t tz_cmd_id, smc_id = TZ_OS_APP_SHUTDOWN_ID; desc.arginfo = TZ_OS_APP_SHUTDOWN_ID_PARAM_ID; desc.args[0] = req->app_id; - ret = __qseecom_scm_call2_locked(smc_id, &desc); + ret = scm_call2(smc_id, &desc); break; } case QSEOS_APP_LOOKUP_COMMAND: { From 893c9f03573cac571eb056466bbfdb96fa1cb28d Mon Sep 17 00:00:00 2001 From: wya Date: Mon, 8 Jul 2019 13:16:21 +0800 Subject: [PATCH 105/281] android: binder: Fix the binder transaction fail issue for 32bit target If macro BINDER_IPC_32BIT define in binder.c file, the type binder_size_t will build as 64bit,so move BINDER_IPC_32BIT define to binder header file. Change-Id: Ic94cee7ccff158a33739e60d254bec34801431a0 Signed-off-by: Wen Yang --- drivers/android/binder.c | 6 ------ drivers/android/binder_alloc.h | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 01d5f5d18fd9..6107c03f78da 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -70,12 +70,6 @@ #include #include #include - -#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT -#define BINDER_IPC_32BIT 1 -#endif - -#include #include "binder_alloc.h" #include "binder_trace.h" diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h index b60d161b7a7a..8db096204808 100644 --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h @@ -22,6 +22,11 @@ #include #include #include + +#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT +#define BINDER_IPC_32BIT 1 +#endif + #include extern struct list_lru binder_alloc_lru; From 5747bd9b224a6dc6aa8dbbb5b35d1d2e72bec6a6 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 11 Jul 2019 21:20:04 -0700 Subject: [PATCH 106/281] defconfig: sa415m: Enable the AT24 EEPROM for SA415M Enable the AT24 I2C EEPROM driver for SA415M devices. Change-Id: I3931f9637d910791456f14f50f5233e500e6d2e7 Signed-off-by: Gustavo Solaira --- arch/arm/configs/sdxpoorwills-auto-perf_defconfig | 1 + arch/arm/configs/sdxpoorwills-auto_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig index f29255534c70..f329fc4dc9ea 100644 --- a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig +++ b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig @@ -193,6 +193,7 @@ CONFIG_MTD_UBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_QSEECOM=y +CONFIG_EEPROM_AT24=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y diff --git a/arch/arm/configs/sdxpoorwills-auto_defconfig b/arch/arm/configs/sdxpoorwills-auto_defconfig index d5544bd8f92b..b7700bcb9ae3 100644 --- a/arch/arm/configs/sdxpoorwills-auto_defconfig +++ b/arch/arm/configs/sdxpoorwills-auto_defconfig @@ -194,6 +194,7 @@ CONFIG_MTD_UBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_QSEECOM=y +CONFIG_EEPROM_AT24=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y From 958e51c535a6ad5c4a7c2e7eb2b7626dcba8e1c6 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 11 Jul 2019 21:21:13 -0700 Subject: [PATCH 107/281] ARM: dts: msm: Enable EEPROM for SA415M boards Enable the I2C EEPROM device for SA415M TTP and CCARD boards. The EEPROM stores the CDT data. Change-Id: Ibabbdf9ea46105b0119dd9e38a01e508cee83872 Signed-off-by: Gustavo Solaira --- arch/arm/boot/dts/qcom/sa415m-ttp.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi index c8fe49212a52..e8fdc08c3174 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi +++ b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi @@ -46,6 +46,14 @@ }; }; +&i2c_3 { + eeprom@52 { + compatible = "atmel,24c128"; + reg = <0x52>; + pagesize = <32>; + }; +}; + &i2c_4 { status = "okay"; From f994f2000e78c1e396c524eebc4af13d88d3e3d6 Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Wed, 29 May 2019 10:24:40 -0700 Subject: [PATCH 108/281] msm: camera: eeprom: Fix OOB condition for memory map count Fix OOB check for memory map count to access correct memory map. Change-Id: Ifa3d323103725e4df57e86295bb7567835654b71 Signed-off-by: Jigarkumar Zala Signed-off-by: Sridhar Gujje --- .../cam_sensor_module/cam_eeprom/cam_eeprom_core.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 02287709546e..6797ba4e58d6 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -439,8 +439,9 @@ static int32_t cam_eeprom_parse_memory_map( else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) validate_size = sizeof(struct cam_cmd_unconditional_wait); - if (remain_buf_len < validate_size || *num_map >= - (MSM_EEPROM_MEMORY_MAP_MAX_SIZE * MSM_EEPROM_MAX_MEM_MAP_CNT)) { + if (remain_buf_len < validate_size || + *num_map >= (MSM_EEPROM_MAX_MEM_MAP_CNT * + MSM_EEPROM_MEMORY_MAP_MAX_SIZE)) { CAM_ERR(CAM_EEPROM, "not enough buffer"); return -EINVAL; } @@ -449,10 +450,10 @@ static int32_t cam_eeprom_parse_memory_map( i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf; if (i2c_random_wr->header.count == 0 || - i2c_random_wr->header.count >= - (MSM_EEPROM_MEMORY_MAP_MAX_SIZE * - MSM_EEPROM_MAX_MEM_MAP_CNT) || - (size_t)*num_map > U16_MAX - i2c_random_wr->header.count) { + i2c_random_wr->header.count >= MSM_EEPROM_MAX_MEM_MAP_CNT || + (size_t)*num_map >= ((MSM_EEPROM_MAX_MEM_MAP_CNT * + MSM_EEPROM_MEMORY_MAP_MAX_SIZE) - + i2c_random_wr->header.count)) { CAM_ERR(CAM_EEPROM, "OOB Error"); return -EINVAL; } From 94eed55ab06761f07d4e98fcfdc6837a158aa0b4 Mon Sep 17 00:00:00 2001 From: Junwen Wu Date: Mon, 8 Jul 2019 18:10:49 +0800 Subject: [PATCH 109/281] ARM: dts: msm: Add support for speed-bin 5 for SDM439/429 Add speed-bin 5 to support the fmax of 1.7GHz for cpu clock. Change-Id: I46fef4cf28f62d48a9673aa70b4957c70936a12c Signed-off-by: Junwen Wu --- arch/arm64/boot/dts/qcom/sdm429.dtsi | 14 +++++++++++++- arch/arm64/boot/dts/qcom/sdm439.dtsi | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429.dtsi b/arch/arm64/boot/dts/qcom/sdm429.dtsi index 06c54a123527..b261860f7a80 100644 --- a/arch/arm64/boot/dts/qcom/sdm429.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, 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 @@ -220,6 +220,18 @@ < 400000000 1>, < 533333333 3>; + qcom,speed5-bin-v0-c1 = + < 0 0>, + < 960000000 1>, + < 1305600000 1>, + < 1497600000 2>, + < 1708800000 3>; + + qcom,speed5-bin-v0-cci = + < 0 0>, + < 400000000 1>, + < 533333333 3>; + #clock-cells = <1>; }; diff --git a/arch/arm64/boot/dts/qcom/sdm439.dtsi b/arch/arm64/boot/dts/qcom/sdm439.dtsi index e4e74cbad5f5..b42d18eaf9a2 100644 --- a/arch/arm64/boot/dts/qcom/sdm439.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm439.dtsi @@ -356,6 +356,26 @@ < 0 0>, < 400000000 1>, < 533333333 3>; + + qcom,speed5-bin-v0-c0 = + < 0 0>, + < 768000000 1>, + < 998400000 1>, + < 1171200000 2>, + < 1305600000 3>, + < 1459200000 5>; + + qcom,speed5-bin-v0-c1= + < 0 0>, + < 960000000 1>, + < 1305600000 1>, + < 1497600000 2>, + < 1708800000 3>; + + qcom,speed5-bin-v0-cci = + < 0 0>, + < 400000000 1>, + < 533333333 3>; }; &clock_gcc { From 2fe70d7a5fc1cd17e72f46c56c17ee95b386e0ac Mon Sep 17 00:00:00 2001 From: Sanjay Dwivedi Date: Thu, 13 Jun 2019 03:16:27 -0700 Subject: [PATCH 110/281] Revert "defconfig: remove paranoid network from sdxpoorwills defconfig" This reverts commit be2411bf906d36d34c64166fd8e994a3b0bd98d6. Paranoid network is required for data call.Initially paranoid network was removed to avoid unnescessary logging by net manager but has impacted data call. Change-Id: I277519d6b7b61d509e9f28b210c296e975cf40f3 Signed-off-by: Sanjay Dwivedi --- arch/arm/configs/sdxpoorwills-auto-perf_defconfig | 1 - arch/arm/configs/sdxpoorwills-auto_defconfig | 1 - arch/arm/configs/sdxpoorwills-perf_defconfig | 1 - arch/arm/configs/sdxpoorwills_defconfig | 1 - 4 files changed, 4 deletions(-) diff --git a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig index f29255534c70..44311dd7308c 100644 --- a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig +++ b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig @@ -65,7 +65,6 @@ CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y -# CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NETFILTER=y CONFIG_NETFILTER_DEBUG=y CONFIG_NF_CONNTRACK=y diff --git a/arch/arm/configs/sdxpoorwills-auto_defconfig b/arch/arm/configs/sdxpoorwills-auto_defconfig index d5544bd8f92b..50f6a5752998 100644 --- a/arch/arm/configs/sdxpoorwills-auto_defconfig +++ b/arch/arm/configs/sdxpoorwills-auto_defconfig @@ -66,7 +66,6 @@ CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y -# CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NETFILTER=y CONFIG_NETFILTER_DEBUG=y CONFIG_NF_CONNTRACK=y diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig index 4c48a1f716c9..44eb38b145d0 100644 --- a/arch/arm/configs/sdxpoorwills-perf_defconfig +++ b/arch/arm/configs/sdxpoorwills-perf_defconfig @@ -66,7 +66,6 @@ CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y -# CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NETFILTER=y CONFIG_NETFILTER_DEBUG=y CONFIG_NF_CONNTRACK=y diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig index f892b1a60db9..2b02a4872f56 100644 --- a/arch/arm/configs/sdxpoorwills_defconfig +++ b/arch/arm/configs/sdxpoorwills_defconfig @@ -68,7 +68,6 @@ CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y -# CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NETFILTER=y CONFIG_NETFILTER_DEBUG=y CONFIG_NF_CONNTRACK=y From c9698592488ce70ca1f0f212b469dc5c71618023 Mon Sep 17 00:00:00 2001 From: Praveen Kurapati Date: Fri, 12 Jul 2019 15:03:14 +0530 Subject: [PATCH 111/281] ARM: dts: msm: Disable IPA h/w for SDM845.LE Without full modem flavour IPA is not supported. Add changes to disable IPA driver. Change-Id: I1fc6083a0e4ba27b912666b68d5d529dbb388009 Signed-off-by: Praveen Kurapati --- arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi index 13910803eb00..5456693f22f0 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi @@ -99,6 +99,10 @@ qcom,ipc-gpio = <&tlmm 121 0>; qcom,finger-detect-gpio = <&pm8998_gpios 4 0>; }; + + qcom,rmnet-ipa { + status="disabled"; + }; }; &ssc_sensors { @@ -193,3 +197,7 @@ }; }; }; + +&ipa_hw { + status="disabled"; +}; From eb4608c5388335fae1c1ed9e4e616024173eefe7 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Fri, 12 Jul 2019 14:57:12 -0700 Subject: [PATCH 112/281] ARM: dts: msm: Disable L0s PCIe substate for sdxpoorwills boards Disable L0s PCIe substate for all sdxpoorwills boards since it causes AER failures in some designs. Change-Id: Ic220cc8d099e3e93652fa8fbf75d2b3e138e34d2 Signed-off-by: Gustavo Solaira --- arch/arm/boot/dts/qcom/sdxpoorwills-pcie.dtsi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie.dtsi index 19072090568b..e0ecfaa8eda2 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, 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 @@ -130,7 +130,6 @@ qcom,vreg-cx-voltage-level = ; - qcom,l0s-supported; qcom,l1-supported; qcom,l1ss-supported; qcom,aux-clk-sync; From a3c6d226ca270b5c178f39e78222c5b10f0c7584 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Fri, 12 Jul 2019 12:17:31 +0530 Subject: [PATCH 113/281] sched/walt: Fix invalid access of CPU cycle counter callback There is a potential reordering issue with CPU cycle counter callback update and access. The update path is invoked from the low level clock driver by calling register_cpu_cycle_counter_cb(). register_cpu_cycle_counter_cb() { cpu_cycle_counter_cb = *cb use_cycle_counter = true } The access/reader path is invoked from update_task_ravg()-> update_task_cpu_cycles(). update_task_cpu_cycles() { if (use_cycle_counter) *cpu_cycle_counter_cb() } If the stores of cpu_cycle_counter_cb and use_cycle_counter are re-ordered (either at compile time or execution time), there is a possibility of accessing the callback function pointer before the update. This can be fixed by adding a write memory barrier at the update side and a read memory barrier at the access side. However this re-ordering issue happens only once during boot up time. So adding a read memory barrier at the access side which is in scheduler hotpaths is not efficient. Since the access path always takes a rq lock, acquire all CPUs rq locks at the update side. Change-Id: I81715ab0255ff9f52410dcf707a04ea7c6ccf165 Signed-off-by: Pavankumar Kondeti --- kernel/sched/walt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/sched/walt.c b/kernel/sched/walt.c index 48f64aad4154..9a85525bb4a3 100644 --- a/kernel/sched/walt.c +++ b/kernel/sched/walt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, 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 @@ -323,14 +323,19 @@ update_window_start(struct rq *rq, u64 wallclock, int event) int register_cpu_cycle_counter_cb(struct cpu_cycle_counter_cb *cb) { + unsigned long flags; + mutex_lock(&cluster_lock); if (!cb->get_cpu_cycle_counter) { mutex_unlock(&cluster_lock); return -EINVAL; } + acquire_rq_locks_irqsave(cpu_possible_mask, &flags); cpu_cycle_counter_cb = *cb; use_cycle_counter = true; + release_rq_locks_irqrestore(cpu_possible_mask, &flags); + mutex_unlock(&cluster_lock); return 0; From ebfd4645a6517370abf551b6f0875d274f87a590 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Thu, 11 Jul 2019 12:52:51 +0530 Subject: [PATCH 114/281] diag: Update new msg, log and event masks for diag logging Log and event mask ranges are updated and new entry of msg mask array is updated. Change-Id: I0a257e6b54b8d6ccdb3ec5d7ac2400751c95fa61 Signed-off-by: Manoj Prabhu B --- include/linux/diagchar.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h index 83718596c268..d33071c320b1 100644 --- a/include/linux/diagchar.h +++ b/include/linux/diagchar.h @@ -148,7 +148,7 @@ * a new RANGE of SSIDs to the msg_mask_tbl. */ #define MSG_MASK_TBL_CNT 26 -#define APPS_EVENT_LAST_ID 0xCA7 +#define APPS_EVENT_LAST_ID 0xCAA #define MSG_SSID_0 0 #define MSG_SSID_0_LAST 130 @@ -183,7 +183,7 @@ #define MSG_SSID_15 8000 #define MSG_SSID_15_LAST 8000 #define MSG_SSID_16 8500 -#define MSG_SSID_16_LAST 8531 +#define MSG_SSID_16_LAST 8532 #define MSG_SSID_17 9000 #define MSG_SSID_17_LAST 9008 #define MSG_SSID_18 9500 @@ -783,7 +783,8 @@ static const uint32_t msg_bld_masks_16[] = { MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR | MSG_LVL_FATAL, MSG_LVL_MED, - MSG_LVL_MED + MSG_LVL_MED, + MSG_LVL_LOW }; static const uint32_t msg_bld_masks_17[] = { @@ -921,7 +922,7 @@ static const uint32_t msg_bld_masks_25[] = { /* LOG CODES */ static const uint32_t log_code_last_tbl[] = { 0x0, /* EQUIP ID 0 */ - 0x1C94, /* EQUIP ID 1 */ + 0x1C9A, /* EQUIP ID 1 */ 0x0, /* EQUIP ID 2 */ 0x0, /* EQUIP ID 3 */ 0x4910, /* EQUIP ID 4 */ From dc6f305e0111e3b0cb0cf40981e2cc4847668c71 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 8 Jul 2019 14:27:42 -0700 Subject: [PATCH 115/281] usb: f_gsi: Fix error handling path in ipa_connect_channels Commit 7674e8f6a77e ("usb: f_gsi: Don't enable IPA data path if connect channel fails") added error handling path and IN and out endpoints. For DPL out ep and out request are NULL. In case ipa_connect_channels returns error for DPL usb_gsi_ep_op() is de-referencing NULL pointer. Add NULL check for out ep in error handling path. Change-Id: Ia2db2ed840a4ab9032366042f00a1a9ac086d91f Signed-off-by: Hemant Kumar --- drivers/usb/gadget/function/f_gsi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index 97c50d06b0cb..ffd5952f1220 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -726,11 +726,13 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) return ret; end_xfer_ep_out: - usb_gsi_ep_op(d_port->out_ep, NULL, - GSI_EP_OP_ENDXFER); + if (d_port->out_ep) + usb_gsi_ep_op(d_port->out_ep, NULL, + GSI_EP_OP_ENDXFER); free_trb_ep_out: - usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, - GSI_EP_OP_FREE_TRBS); + if (d_port->out_ep) + usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, + GSI_EP_OP_FREE_TRBS); end_xfer_ep_in: usb_gsi_ep_op(d_port->in_ep, NULL, GSI_EP_OP_ENDXFER); From 22f3f5d7747a8858f0f9de8cd365ead082864082 Mon Sep 17 00:00:00 2001 From: Manu Gautam Date: Fri, 10 May 2019 15:25:48 +0530 Subject: [PATCH 116/281] usb: dwc3-msm: Add GSI mode support for Normal USB EPs Allow non-GSI capable or normal USB endpoint to be used in GSI mode. In this case, USB driver receives events from hardware and updates GSI doorbell register with completed TRB. USB GSI hardware wrapper isn't involved for such EPs. In order to use this feature, GSI function driver must choose interrupter number as '0' with such endpoints, non-zero interrupters are reserved for USB GSI wrapper use. Change-Id: Ief51b722bbe1aa97ff806e5a3b8b1ca806671a8f Signed-off-by: Manu Gautam Signed-off-by: Ajay Agarwal --- drivers/usb/dwc3/core.h | 2 + drivers/usb/dwc3/dwc3-msm.c | 74 ++++++++++++++++++++++++++++++++++--- drivers/usb/dwc3/gadget.c | 28 ++++++++++++++ include/linux/usb/gadget.h | 1 + 4 files changed, 100 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 89d7ee0f459e..eabd29d5da3c 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -620,6 +620,7 @@ struct dwc3_ep_events { * @dbg_ep_events_ts: timestamp for previous event counters * @fifo_depth: allocated TXFIFO depth * @ep_cfg_init_params: Used by GSI EP to save EP_CFG init_cmd params + * @gsi_db_reg_addr: Address of GSI DB register mapped to this EP */ struct dwc3_ep { struct usb_ep endpoint; @@ -676,6 +677,7 @@ struct dwc3_ep { struct timespec dbg_ep_events_ts; int fifo_depth; struct dwc3_gadget_ep_cmd_params ep_cfg_init_params; + void __iomem *gsi_db_reg_addr; }; enum dwc3_phy { diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index af704b7228d5..c74b6af84243 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -203,7 +203,7 @@ static const char * const gsi_op_strings[] = { "ENABLE_GSI", "UPDATE_XFER", "RING_DB", "END_XFER", "GET_CH_INFO", "GET_XFER_IDX", "PREPARE_TRBS", "FREE_TRBS", "SET_CLR_BLOCK_DBL", "CHECK_FOR_SUSP", - "EP_DISABLE" }; + "EP_DISABLE", "EP_UPDATE_DB" }; /* Input bits to state machine (mdwc->inputs) */ @@ -898,8 +898,17 @@ static void gsi_get_channel_info(struct usb_ep *ep, /* Store last 16 bits of LINK TRB address as per GSI hw requirement */ ch_info->last_trb_addr = (dwc3_trb_dma_offset(dep, &dep->trb_pool[last_trb_index - 1]) & 0x0000FFFF); - ch_info->gevntcount_low_addr = (u32)(dwc->reg_phys + + + /* + * Check if NORMAL EP is used with GSI. In that case USB driver + * processes events and GSI shouldn't access GEVNTCOUNT(0) register. + */ + if (ep->ep_intr_num) { + ch_info->gevntcount_low_addr = (u32)(dwc->reg_phys + DWC3_GEVNTCOUNT(ep->ep_intr_num)); + } else { + dev_dbg(dwc->dev, "gevntcount returned as 0 for normal EP\n"); + } ch_info->gevntcount_hi_addr = 0; dev_dbg(dwc->dev, @@ -929,8 +938,15 @@ static int gsi_startxfer_for_ep(struct usb_ep *ep) } memset(¶ms, 0, sizeof(params)); - params.param0 = GSI_TRB_ADDR_BIT_53_MASK | GSI_TRB_ADDR_BIT_55_MASK; - params.param0 |= (ep->ep_intr_num << 16); + /* + * Check if NORMAL EP is used with GSI. In that case USB driver + * updates GSI doorbell and USB GSI wrapper h/w isn't involved. + */ + if (ep->ep_intr_num) { + params.param0 = GSI_TRB_ADDR_BIT_53_MASK | + GSI_TRB_ADDR_BIT_55_MASK; + params.param0 |= (ep->ep_intr_num << 16); + } params.param1 = lower_32_bits(dwc3_trb_dma_offset(dep, &dep->trb_pool[0])); cmd = DWC3_DEPCMD_STARTTRANSFER; @@ -957,7 +973,18 @@ static void gsi_store_ringbase_dbl_info(struct usb_ep *ep, struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); - int n = ep->ep_intr_num - 1; + int n; + + /* + * Check if NORMAL EP is used with GSI. In that case USB driver + * updates GSI doorbell and USB GSI wrapper h/w isn't involved. + */ + if (!ep->ep_intr_num) { + dev_dbg(mdwc->dev, "%s: is no-op for normal EP\n", __func__); + return; + } + + n = ep->ep_intr_num - 1; dwc3_msm_write_reg(mdwc->base, GSI_RING_BASE_ADDR_L(n), dwc3_trb_dma_offset(dep, &dep->trb_pool[0])); @@ -991,6 +1018,21 @@ static void gsi_store_ringbase_dbl_info(struct usb_ep *ep, dwc3_msm_read_reg(mdwc->base, GSI_DBL_ADDR_L(n))); } +static void dwc3_msm_gsi_db_update(struct dwc3_ep *dep, dma_addr_t offset) +{ + struct dwc3 *dwc = dep->dwc; + struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); + + if (!dep->gsi_db_reg_addr) { + dev_err(mdwc->dev, "Failed to update GSI DBL\n"); + return; + } + + writel_relaxed(offset, dep->gsi_db_reg_addr); + dev_dbg(mdwc->dev, "Writing TRB addr: %pa to %pK\n", + &offset, dep->gsi_db_reg_addr); +} + /* * Rings Doorbell for GSI Channel * @@ -1016,6 +1058,8 @@ static void gsi_ring_db(struct usb_ep *ep, struct usb_gsi_request *request) return; } + dep->gsi_db_reg_addr = gsi_dbl_address_lsb; + gsi_dbl_address_msb = devm_ioremap_nocache(mdwc->dev, request->db_reg_phs_addr_msb, sizeof(u32)); if (!gsi_dbl_address_msb) { @@ -1399,6 +1443,15 @@ static void gsi_enable(struct usb_ep *ep) struct dwc3 *dwc = dep->dwc; struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); + /* + * Check if NORMAL EP is used with GSI. In that case USB driver + * updates GSI doorbell and USB GSI wrapper h/w isn't involved. + */ + if (!ep->ep_intr_num) { + dev_dbg(mdwc->dev, "%s: is no-op for normal EP\n", __func__); + return; + } + dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, GSI_CLK_EN_MASK, 1); dwc3_msm_write_reg_field(mdwc->base, @@ -1435,6 +1488,12 @@ static void gsi_set_clear_dbell(struct usb_ep *ep, else gsi_enable_ep_events(ep); + /* Nothing to be done if NORMAL EP is used with GSI */ + if (!ep->ep_intr_num) { + dev_dbg(mdwc->dev, "%s: is no-op for normal EP\n", __func__); + return; + } + dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, BLOCK_GSI_WR_GO_MASK, block_db); } @@ -1490,6 +1549,7 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep, struct gsi_channel_info *ch_info; bool block_db; unsigned long flags; + dma_addr_t offset; dbg_log_string("%s(%d):%s", ep->name, ep->ep_num, gsi_op_to_string(op)); @@ -1555,6 +1615,10 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep, case GSI_EP_OP_DISABLE: ret = ep->ops->disable(ep); break; + case GSI_EP_OP_UPDATE_DB: + offset = *(dma_addr_t *)op_data; + dwc3_msm_gsi_db_update(dep, offset); + break; default: dev_err(mdwc->dev, "%s: Invalid opcode GSI EP\n", __func__); } diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index e8d270dceed0..c6917c337840 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2710,6 +2710,25 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, return 1; } +static void dwc3_gsi_ep_transfer_complete(struct dwc3 *dwc, struct dwc3_ep *dep) +{ + struct usb_ep *ep = &dep->endpoint; + struct dwc3_trb *trb; + dma_addr_t offset; + + trb = &dep->trb_pool[dep->trb_dequeue]; + while (trb->ctrl & DWC3_TRBCTL_LINK_TRB) { + dwc3_ep_inc_trb(&dep->trb_dequeue); + trb = &dep->trb_pool[dep->trb_dequeue]; + } + + if (!(trb->ctrl & DWC3_TRB_CTRL_HWO)) { + offset = dwc3_trb_dma_offset(dep, trb); + usb_gsi_ep_op(ep, (void *)&offset, GSI_EP_OP_UPDATE_DB); + dwc3_ep_inc_trb(&dep->trb_dequeue); + } +} + static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, struct dwc3_ep *dep, const struct dwc3_event_depevt *event) { @@ -2721,6 +2740,15 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, if (event->status & DEPEVT_STATUS_BUSERR) status = -ECONNRESET; + /* + * Check if NORMAL EP is used with GSI. + * In that case dwc3 driver recevies EP events from hardware and + * updates GSI doorbell with completed TRB. + */ + if (dep->endpoint.ep_type == EP_TYPE_GSI) { + dwc3_gsi_ep_transfer_complete(dwc, dep); + return; + } clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status); if (clean_busy && (!dep->endpoint.desc || is_xfer_complete || diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 0267bed4bcf9..418978e5ad98 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -67,6 +67,7 @@ enum gsi_ep_op { GSI_EP_OP_SET_CLR_BLOCK_DBL, GSI_EP_OP_CHECK_FOR_SUSPEND, GSI_EP_OP_DISABLE, + GSI_EP_OP_UPDATE_DB, }; /* From ee0c93b2ca836be442e5b77899f87260f95136ec Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 12 Jul 2019 15:52:45 -0700 Subject: [PATCH 117/281] ANDROID: f2fs: fix wrong android tracepoint f2fs_submit_page_bio is called from in-place-write case. Let's not assume read path only. Fixes: 8a007427f605 ("ANDROID: f2fs: Complement "android_fs" tracepoint of read path") Change-Id: I9bb8b7833d57c4342b318da52e4353f70acc3eb0 Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 86c94c0c59be..1e58d1c80151 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -510,7 +510,10 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio) inc_page_count(fio->sbi, is_read_io(fio->op) ? __read_io_type(page): WB_DATA_TYPE(fio->page)); - __f2fs_submit_read_bio(fio->sbi, bio, fio->type); + if (is_read_io(fio->op)) + __f2fs_submit_read_bio(fio->sbi, bio, fio->type); + else + __submit_bio(fio->sbi, bio, fio->type); return 0; } From 5e2c340821b100893d20b324a6b644665627b80e Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 26 Jun 2019 19:06:30 -0700 Subject: [PATCH 118/281] ANDROID: f2fs: add android fsync tracepoint Change-Id: Id7c23173f85a835a2294ee698597b7d60f1ee356 Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 12 ++++++++ include/trace/events/android_fs.h | 9 ++++++ include/trace/events/android_fs_template.h | 34 ++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 24fe54e4a9df..0c76bd1348d6 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -29,6 +29,7 @@ #include "gc.h" #include "trace.h" #include +#include static int f2fs_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) @@ -220,6 +221,15 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, trace_f2fs_sync_file_enter(inode); + if (trace_android_fs_fsync_start_enabled()) { + char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; + + path = android_fstrace_get_pathname(pathbuf, + MAX_TRACE_PATHBUF_LEN, inode); + trace_android_fs_fsync_start(inode, + current->pid, path, current->comm); + } + if (S_ISDIR(inode->i_mode)) goto go_write; @@ -325,6 +335,8 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, out: trace_f2fs_sync_file_exit(inode, cp_reason, datasync, ret); f2fs_trace_ios(NULL, 1); + trace_android_fs_fsync_end(inode, start, end - start); + return ret; } diff --git a/include/trace/events/android_fs.h b/include/trace/events/android_fs.h index 49509533d3fa..0ee4a07f0240 100644 --- a/include/trace/events/android_fs.h +++ b/include/trace/events/android_fs.h @@ -25,6 +25,15 @@ DEFINE_EVENT(android_fs_data_end_template, android_fs_datawrite_end, TP_PROTO(struct inode *inode, loff_t offset, int bytes), TP_ARGS(inode, offset, bytes)); +DEFINE_EVENT(android_fs_fsync_start_template, android_fs_fsync_start, + TP_PROTO(struct inode *inode, + pid_t pid, char *pathname, char *command), + TP_ARGS(inode, pid, pathname, command)); + +DEFINE_EVENT(android_fs_data_end_template, android_fs_fsync_end, + TP_PROTO(struct inode *inode, loff_t offset, int bytes), + TP_ARGS(inode, offset, bytes)); + #endif /* _TRACE_ANDROID_FS_H */ /* This part must be outside protection */ diff --git a/include/trace/events/android_fs_template.h b/include/trace/events/android_fs_template.h index b23d17b56c63..0832c26acaed 100644 --- a/include/trace/events/android_fs_template.h +++ b/include/trace/events/android_fs_template.h @@ -61,4 +61,38 @@ DECLARE_EVENT_CLASS(android_fs_data_end_template, __entry->offset, __entry->bytes) ); +DECLARE_EVENT_CLASS(android_fs_fsync_start_template, + TP_PROTO(struct inode *inode, + pid_t pid, char *pathname, char *command), + TP_ARGS(inode, pid, pathname, command), + TP_STRUCT__entry( + __string(pathbuf, pathname); + __field(loff_t, i_size); + __string(cmdline, command); + __field(pid_t, pid); + __field(ino_t, ino); + ), + TP_fast_assign( + { + /* + * Replace the spaces in filenames and cmdlines + * because this screws up the tooling that parses + * the traces. + */ + __assign_str(pathbuf, pathname); + (void)strreplace(__get_str(pathbuf), ' ', '_'); + __entry->i_size = i_size_read(inode); + __assign_str(cmdline, command); + (void)strreplace(__get_str(cmdline), ' ', '_'); + __entry->pid = pid; + __entry->ino = inode->i_ino; + } + ), + TP_printk("entry_name %s, cmdline %s," + " pid %d, i_size %llu, ino %lu", + __get_str(pathbuf), + __get_str(cmdline), __entry->pid, __entry->i_size, + (unsigned long) __entry->ino) +); + #endif /* _TRACE_ANDROID_FS_TEMPLATE_H */ From 0d3cc847f809f22544084fe89159ee17f5eae6d5 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Wed, 19 Jun 2019 17:40:41 +0530 Subject: [PATCH 119/281] usb: gadget: Add support for RmNet CV2X instance Add support for RmNet CV2X interface. Details of the patch: - Add support for 2 normal EPs to be used in GSI mode - Add new protocol ID and make necessary changes For this new protocol USB_PROT_RMNET_V2X_IPA: - Use USB2_PROD and USB2_CONS as channel client type - Use normal EPs - Pass dummy GEVENTCOUNT register address to GSI. Change-Id: I35e7f4f52562cd4fa8ffab4e2950c17827c2cc4f Signed-off-by: Ajay Agarwal --- .../devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 2 + drivers/usb/dwc3/core.h | 3 ++ drivers/usb/dwc3/dwc3-msm.c | 41 +++++++++++++++---- drivers/usb/dwc3/gadget.c | 10 ++--- drivers/usb/gadget/function/f_gsi.c | 39 ++++++++++++++---- drivers/usb/gadget/function/f_gsi.h | 4 ++ 7 files changed, 79 insertions(+), 21 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 83ecdc725916..20abd3d575bb 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -63,6 +63,7 @@ Optional properties: during bus suspend. - snps,usb3-u1u2-disable: If present, disable U1U2 low power modes in Superspeed mode - snps,usb2-l1-disable: If present, disable L1 low power modes in Highspeed mode + - normal-eps-in-gsi-mode: If present, two normal EPS (1 In, 1 Out) can be used in GSI mode This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 02839e236966..146fe3e6201f 100755 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1284,6 +1284,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,usb3-u1u2-disable"); dwc->usb2_l1_disable = device_property_read_bool(dev, "snps,usb2-l1-disable"); + dwc->normal_eps_in_gsi_mode = device_property_read_bool(dev, + "normal-eps-in-gsi-mode"); if (dwc->enable_bus_suspend) { pm_runtime_set_autosuspend_delay(dev, 500); pm_runtime_use_autosuspend(dev); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index eabd29d5da3c..80386d2c4fd8 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -991,6 +991,8 @@ struct dwc3_scratchpad_array { * @create_reg_debugfs: create debugfs entry to allow dwc3 register dump * @xhci_imod_value: imod value to use with xhci * @core_id: usb core id to differentiate different controller + * @normal_eps_in_gsi_mode: if true, two normal EPS (1 In, 1 Out) can be used in + * GSI mode */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -1193,6 +1195,7 @@ struct dwc3 { u32 xhci_imod_value; int core_id; int retries_on_error; + bool normal_eps_in_gsi_mode; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index c74b6af84243..37c4e7e57631 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -312,6 +312,8 @@ struct dwc3_msm { u64 dummy_gsi_db; dma_addr_t dummy_gsi_db_dma; + u64 dummy_gevntcnt; + dma_addr_t dummy_gevntcnt_dma; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ @@ -864,6 +866,7 @@ static void gsi_get_channel_info(struct usb_ep *ep, int last_trb_index = 0; struct dwc3 *dwc = dep->dwc; struct usb_gsi_request *request = ch_info->ch_req; + struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); /* Provide physical USB addresses for DEPCMD and GEVENTCNT registers */ ch_info->depcmd_low_addr = (u32)(dwc->reg_phys + @@ -898,6 +901,8 @@ static void gsi_get_channel_info(struct usb_ep *ep, /* Store last 16 bits of LINK TRB address as per GSI hw requirement */ ch_info->last_trb_addr = (dwc3_trb_dma_offset(dep, &dep->trb_pool[last_trb_index - 1]) & 0x0000FFFF); + dev_dbg(dwc->dev, "depcmd_laddr=%x last_trb_addr=%x\n", + ch_info->depcmd_low_addr, ch_info->last_trb_addr); /* * Check if NORMAL EP is used with GSI. In that case USB driver @@ -906,15 +911,18 @@ static void gsi_get_channel_info(struct usb_ep *ep, if (ep->ep_intr_num) { ch_info->gevntcount_low_addr = (u32)(dwc->reg_phys + DWC3_GEVNTCOUNT(ep->ep_intr_num)); + ch_info->gevntcount_hi_addr = 0; + dev_dbg(dwc->dev, "gevtcnt_laddr=%x gevtcnt_haddr=%x\n", + ch_info->gevntcount_low_addr, ch_info->gevntcount_hi_addr); } else { - dev_dbg(dwc->dev, "gevntcount returned as 0 for normal EP\n"); + ch_info->gevntcount_low_addr = (u32)mdwc->dummy_gevntcnt_dma; + ch_info->gevntcount_hi_addr = + (u32)((u64)mdwc->dummy_gevntcnt_dma >> 32); + dev_dbg(dwc->dev, "Dummy GEVNTCNT Addr %pK: %llx %x (LSB)\n", + &mdwc->dummy_gevntcnt, + (unsigned long long)mdwc->dummy_gevntcnt_dma, + (u32)mdwc->dummy_gevntcnt_dma); } - ch_info->gevntcount_hi_addr = 0; - - dev_dbg(dwc->dev, - "depcmd_laddr=%x last_trb_addr=%x gevtcnt_laddr=%x gevtcnt_haddr=%x", - ch_info->depcmd_low_addr, ch_info->last_trb_addr, - ch_info->gevntcount_low_addr, ch_info->gevntcount_hi_addr); } /* @@ -2129,6 +2137,19 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, dev_err(dwc->dev, "failed to map dummy doorbell buffer\n"); mdwc->dummy_gsi_db_dma = (dma_addr_t)NULL; } + + /* + * Set-up dummy GEVNTCOUNT address to be passed on to GSI for + * normal (non HW-accelerated) EPs. + */ + mdwc->dummy_gevntcnt_dma = dma_map_single(dwc->sysdev, + &mdwc->dummy_gevntcnt, + sizeof(mdwc->dummy_gevntcnt), + DMA_FROM_DEVICE); + if (dma_mapping_error(dwc->sysdev, mdwc->dummy_gevntcnt_dma)) { + dev_err(dwc->dev, "failed to map dummy geventcount\n"); + mdwc->dummy_gevntcnt_dma = (dma_addr_t)NULL; + } break; case DWC3_GSI_EVT_BUF_SETUP: dev_dbg(mdwc->dev, "DWC3_GSI_EVT_BUF_SETUP\n"); @@ -2202,6 +2223,12 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma); } + if (mdwc->dummy_gevntcnt_dma) { + dma_unmap_single(dwc->sysdev, mdwc->dummy_gevntcnt_dma, + sizeof(mdwc->dummy_gevntcnt), + DMA_FROM_DEVICE); + mdwc->dummy_gevntcnt_dma = (dma_addr_t)NULL; + } if (mdwc->dummy_gsi_db_dma) { dma_unmap_single(dwc->sysdev, mdwc->dummy_gsi_db_dma, sizeof(mdwc->dummy_gsi_db), diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index c6917c337840..d0391b4ae7bb 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2390,8 +2390,8 @@ static const struct usb_gadget_ops dwc3_gadget_ops = { /* -------------------------------------------------------------------------- */ -#define NUM_GSI_OUT_EPS 1 -#define NUM_GSI_IN_EPS 2 +#define NUM_GSI_OUT_EPS(dwc) (dwc->normal_eps_in_gsi_mode ? 2 : 1) +#define NUM_GSI_IN_EPS(dwc) (dwc->normal_eps_in_gsi_mode ? 3 : 2) static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, u8 num, u32 direction) @@ -2399,13 +2399,13 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, struct dwc3_ep *dep; u8 i, gsi_ep_count, gsi_ep_index = 0; - gsi_ep_count = NUM_GSI_OUT_EPS + NUM_GSI_IN_EPS; + gsi_ep_count = NUM_GSI_OUT_EPS(dwc) + NUM_GSI_IN_EPS(dwc); /* OUT GSI EPs based on direction field */ if (gsi_ep_count && !direction) - gsi_ep_count = NUM_GSI_OUT_EPS; + gsi_ep_count = NUM_GSI_OUT_EPS(dwc); /* IN GSI EPs */ else if (gsi_ep_count && direction) - gsi_ep_count = NUM_GSI_IN_EPS; + gsi_ep_count = NUM_GSI_IN_EPS(dwc); for (i = 0; i < num; i++) { u8 epnum = (i << 1) | (direction ? 1 : 0); diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index 97c50d06b0cb..76aee7e469cb 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -572,9 +572,11 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) GSI_EP_OP_GET_CH_INFO); log_event_dbg("%s: USB GSI IN OPS Completed", __func__); - in_params->client = - (gsi->prot_id != USB_PROT_DIAG_IPA) ? IPA_CLIENT_USB_CONS : - IPA_CLIENT_USB_DPL_CONS; + if (gsi->prot_id != USB_PROT_DIAG_IPA) + in_params->client = (gsi->prot_id != USB_PROT_RMNET_V2X_IPA) ? + IPA_CLIENT_USB_CONS : IPA_CLIENT_USB2_CONS; + else + in_params->client = IPA_CLIENT_USB_DPL_CONS; in_params->ipa_ep_cfg.mode.mode = IPA_BASIC; in_params->teth_prot = (enum ipa_usb_teth_prot)gsi->prot_id; in_params->gevntcount_low_addr = @@ -627,7 +629,8 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) usb_gsi_ep_op(d_port->out_ep, (void *)&gsi_channel_info, GSI_EP_OP_GET_CH_INFO); log_event_dbg("%s: USB GSI OUT OPS Completed", __func__); - out_params->client = IPA_CLIENT_USB_PROD; + out_params->client = (gsi->prot_id != USB_PROT_RMNET_V2X_IPA) ? + IPA_CLIENT_USB_PROD : IPA_CLIENT_USB2_PROD; out_params->ipa_ep_cfg.mode.mode = IPA_BASIC; out_params->teth_prot = (enum ipa_usb_teth_prot)gsi->prot_id; out_params->gevntcount_low_addr = @@ -1519,6 +1522,7 @@ static long gsi_ctrl_dev_ioctl(struct file *fp, unsigned int cmd, case GSI_MBIM_GPS_USB_STATUS: val = atomic_read(&gsi->connected); if (gsi->prot_id == USB_PROT_RMNET_IPA || + gsi->prot_id == USB_PROT_RMNET_V2X_IPA || gsi->prot_id == USB_PROT_RMNET_ETHER) val = gsi->rmnet_dtr_status; @@ -1699,6 +1703,9 @@ static int gsi_function_ctrl_port_init(struct f_gsi *gsi) case USB_PROT_RMNET_IPA: cdev_name = GSI_RMNET_CTRL_NAME; break; + case USB_PROT_RMNET_V2X_IPA: + cdev_name = GSI_RMNET_V2X_CTRL_NAME; + break; case USB_PROT_RMNET_ETHER: cdev_name = ETHER_RMNET_CTRL_NAME; break; @@ -2188,6 +2195,7 @@ gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | USB_CDC_REQ_SET_CONTROL_LINE_STATE: line_state = (w_value & GSI_CTRL_DTR ? true : false); if (gsi->prot_id == USB_PROT_RMNET_IPA || + gsi->prot_id == USB_PROT_RMNET_V2X_IPA || gsi->prot_id == USB_PROT_RMNET_ETHER) gsi->rmnet_dtr_status = line_state; log_event_dbg("%s: USB_CDC_REQ_SET_CONTROL_LINE_STATE DTR:%d\n", @@ -2291,6 +2299,7 @@ static int gsi_get_alt(struct usb_function *f, unsigned int intf) /* RNDIS, RMNET and DPL only support alt 0*/ if (intf == gsi->ctrl_id || gsi->prot_id == USB_PROT_RNDIS_IPA || gsi->prot_id == USB_PROT_RMNET_IPA || + gsi->prot_id == USB_PROT_RMNET_V2X_IPA || gsi->prot_id == USB_PROT_DIAG_IPA || is_ext_prot_ether(gsi->prot_id)) return 0; @@ -2412,6 +2421,7 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, /* Control interface has only altsetting 0 */ if (intf == gsi->ctrl_id || gsi->prot_id == USB_PROT_RMNET_IPA || + gsi->prot_id == USB_PROT_RMNET_V2X_IPA || gsi->prot_id == USB_PROT_RMNET_ETHER) { if (alt != 0) goto fail; @@ -2448,6 +2458,7 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, /* for rndis and rmnet alt is always 0 update alt accordingly */ if (gsi->prot_id == USB_PROT_RNDIS_IPA || gsi->prot_id == USB_PROT_RMNET_IPA || + gsi->prot_id == USB_PROT_RMNET_V2X_IPA || gsi->prot_id == USB_PROT_DIAG_IPA || is_ext_prot_ether(gsi->prot_id)) alt = 1; @@ -2478,9 +2489,11 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, /* Configure EPs for GSI */ if (gsi->d_port.in_ep && - gsi->prot_id <= USB_PROT_DIAG_IPA) { + gsi->prot_id <= USB_PROT_RMNET_V2X_IPA) { if (gsi->prot_id == USB_PROT_DIAG_IPA) gsi->d_port.in_ep->ep_intr_num = 3; + else if (gsi->prot_id == USB_PROT_RMNET_V2X_IPA) + gsi->d_port.in_ep->ep_intr_num = 0; else gsi->d_port.in_ep->ep_intr_num = 2; usb_gsi_ep_op(gsi->d_port.in_ep, @@ -2489,8 +2502,11 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, } if (gsi->d_port.out_ep && - gsi->prot_id <= USB_PROT_DIAG_IPA) { - gsi->d_port.out_ep->ep_intr_num = 1; + gsi->prot_id <= USB_PROT_RMNET_V2X_IPA) { + if (gsi->prot_id == USB_PROT_RMNET_V2X_IPA) + gsi->d_port.out_ep->ep_intr_num = 0; + else + gsi->d_port.out_ep->ep_intr_num = 1; usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request, GSI_EP_OP_CONFIG); @@ -2585,6 +2601,7 @@ static void gsi_disable(struct usb_function *f) rndis_uninit(gsi->params); if (gsi->prot_id == USB_PROT_RMNET_IPA || + gsi->prot_id == USB_PROT_RMNET_V2X_IPA || gsi->prot_id == USB_PROT_RMNET_ETHER) gsi->rmnet_dtr_status = false; @@ -2815,7 +2832,7 @@ static int gsi_update_function_bind_params(struct f_gsi *gsi, info->data_nop_desc->bInterfaceNumber = gsi->data_id; /* allocate instance-specific endpoints */ - if (info->fs_in_desc && gsi->prot_id <= USB_PROT_DIAG_IPA) { + if (info->fs_in_desc && gsi->prot_id <= USB_PROT_RMNET_V2X_IPA) { ep = usb_ep_autoconfig_by_name(cdev->gadget, info->fs_in_desc, info->in_epname); if (!ep) @@ -2833,7 +2850,7 @@ static int gsi_update_function_bind_params(struct f_gsi *gsi, } } - if (info->fs_out_desc && gsi->prot_id <= USB_PROT_DIAG_IPA) { + if (info->fs_out_desc && gsi->prot_id <= USB_PROT_RMNET_V2X_IPA) { ep = usb_ep_autoconfig_by_name(cdev->gadget, info->fs_out_desc, info->out_epname); if (!ep) @@ -3009,6 +3026,7 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) if (gsi->prot_id == USB_PROT_RMNET_IPA || + gsi->prot_id == USB_PROT_RMNET_V2X_IPA || gsi->prot_id == USB_PROT_DIAG_IPA || is_ext_prot_ether(gsi->prot_id)) gsi->ctrl_id = -ENODEV; @@ -3220,6 +3238,7 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) } break; case USB_PROT_RMNET_IPA: + case USB_PROT_RMNET_V2X_IPA: case USB_PROT_RMNET_ETHER: info.string_defs = rmnet_gsi_string_defs; info.data_desc = &rmnet_gsi_interface_desc; @@ -3485,6 +3504,7 @@ static int gsi_bind_config(struct f_gsi *gsi) gsi->function.strings = ecm_gsi_strings; break; case USB_PROT_RMNET_IPA: + case USB_PROT_RMNET_V2X_IPA: case USB_PROT_RMNET_ETHER: gsi->function.name = "rmnet"; gsi->function.strings = rmnet_gsi_strings; @@ -3883,6 +3903,7 @@ static int usb_gsi_uevent(struct device *dev, struct kobj_uevent_env *env) switch (gsi->prot_id) { case USB_PROT_RMNET_IPA: + case USB_PROT_RMNET_V2X_IPA: case USB_PROT_RMNET_ETHER: str = gsi->rmnet_dtr_status ? "connected" : "disconnected"; break; diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h index b7e8fe84cdd3..02be58d961dc 100644 --- a/drivers/usb/gadget/function/f_gsi.h +++ b/drivers/usb/gadget/function/f_gsi.h @@ -32,6 +32,7 @@ #include "configfs.h" #define GSI_RMNET_CTRL_NAME "rmnet_ctrl" +#define GSI_RMNET_V2X_CTRL_NAME "rmnet_v2x_ctrl" #define GSI_MBIM_CTRL_NAME "android_mbim" #define GSI_DPL_CTRL_NAME "dpl_ctrl" #define ETHER_RMNET_CTRL_NAME "rmnet_ctrl0" @@ -125,6 +126,7 @@ enum usb_prot_id { USB_PROT_RMNET_IPA, USB_PROT_MBIM_IPA, USB_PROT_DIAG_IPA, + USB_PROT_RMNET_V2X_IPA, /* non-accelerated */ USB_PROT_RMNET_ETHER, @@ -339,6 +341,8 @@ static int name_to_prot_id(const char *name) return USB_PROT_MBIM_IPA; if (!strncasecmp(name, "dpl", MAX_INST_NAME_LEN)) return USB_PROT_DIAG_IPA; + if (!strncasecmp(name, "rmnet.v2x", MAX_INST_NAME_LEN)) + return USB_PROT_RMNET_V2X_IPA; if (!strncasecmp(name, "rmnet.ether", MAX_INST_NAME_LEN)) return USB_PROT_RMNET_ETHER; if (!strncasecmp(name, "dpl.ether", MAX_INST_NAME_LEN)) From 5cafd70dce31e0248a7048d94278cffc2a7ccfb5 Mon Sep 17 00:00:00 2001 From: Naitik Bharadiya Date: Thu, 4 Jul 2019 11:16:46 +0530 Subject: [PATCH 120/281] defconfig: msm: Enable/Disable configs for SDM710 Enable/Disable following configs for SDM710 targets to align them with android base config. Enable : CONFIG_XFRM_INTERFACE CONFIG_MEMBARRIER CONFIG_ARM64_SW_TTBR0_PAN Disable : CONFIG_PM_AUTOSLEEP. Change-Id: Iecd03aef66e9cb25a6a74c9ccbd48f488af2feeb Signed-off-by: Naitik Bharadiya --- arch/arm64/configs/sdm670-perf_defconfig | 4 ++-- arch/arm64/configs/sdm670_defconfig | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig index 386de917f721..cd589e2d4917 100755 --- a/arch/arm64/configs/sdm670-perf_defconfig +++ b/arch/arm64/configs/sdm670-perf_defconfig @@ -37,7 +37,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set @@ -72,13 +71,13 @@ CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y # CONFIG_EFI is not set CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -95,6 +94,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig index 1558f6a957e0..d88e4ac8410f 100755 --- a/arch/arm64/configs/sdm670_defconfig +++ b/arch/arm64/configs/sdm670_defconfig @@ -39,7 +39,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -77,12 +76,12 @@ CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -100,6 +99,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y From bf53d289e776d6324cd7cc6fedccb3ae6b7e3f2e Mon Sep 17 00:00:00 2001 From: Naitik Bharadiya Date: Thu, 4 Jul 2019 11:51:32 +0530 Subject: [PATCH 121/281] defconfig: msm: enable CONFIG_USB_RTL8152 for SDM710 Enable config for Realtek RTL8152/RTL8153 based USB Ethernet Adapters for SDM710 target. This is to align them with android base config. Change-Id: I67614eab0384eeeb301a11809d3413e3bb68fb7c Signed-off-by: Naitik Bharadiya --- arch/arm64/configs/sdm670-perf_defconfig | 1 + arch/arm64/configs/sdm670_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig index cd589e2d4917..9b5749b3df9b 100755 --- a/arch/arm64/configs/sdm670-perf_defconfig +++ b/arch/arm64/configs/sdm670-perf_defconfig @@ -296,6 +296,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_LAN78XX=y CONFIG_USB_USBNET=y CONFIG_WCNSS_MEM_PRE_ALLOC=y diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig index d88e4ac8410f..6697c885767b 100755 --- a/arch/arm64/configs/sdm670_defconfig +++ b/arch/arm64/configs/sdm670_defconfig @@ -302,6 +302,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_LAN78XX=y CONFIG_USB_USBNET=y CONFIG_WCNSS_MEM_PRE_ALLOC=y From fefd7f9c102b30966a658547aa6979be2573bab7 Mon Sep 17 00:00:00 2001 From: zhaochen Date: Wed, 10 Jul 2019 17:58:03 +0800 Subject: [PATCH 122/281] ARM: dts: msm: enable usb_1 in host mode Enable usb1, qusb_phy1, usb_qmp_phy in sdm845-rb3 platform. Change-Id: Ie9e8691c2046d059698f93e19da459e5ed1e154e Signed-off-by: Zhaoyuan Cheng --- arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi index 9f3bd2b1c0dc..dd1188bc42ed 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi @@ -21,6 +21,18 @@ #include "sdm845-rb3.dtsi" #include "sdm845-audio-overlay.dtsi" +&usb1 { + status = "ok"; +}; + +&qusb_phy1 { + status = "ok"; +}; + +&usb_qmp_phy { + status = "ok"; +}; + &qupv3_se3_i2c { status = "disabled"; }; @@ -58,6 +70,18 @@ }; }; +&pcie0 { + pinctrl-names = "default", "slot_power_on"; + pinctrl-1 = <&pcie0_3v3_on &pcie0_1v5_on>; + 3v3_gpio = <&tlmm 90 0>; + 1v5_gpio = <&tlmm 90 0>; + status = "ok"; +}; + +&pcie1 { + /delete-property/ wake-gpio; +}; + &max_rst_suspend { mux { pins = "gpio31","gpio77","gpio32"; From 60d7e469d8b47ac4ff5fc4a5cad8071bca2b3378 Mon Sep 17 00:00:00 2001 From: Xipeng Gu Date: Tue, 16 Jul 2019 16:15:30 +0800 Subject: [PATCH 123/281] ARM: dts: msm: Set L6A voltage as proper value on Spyro Set L6A's voltage as power grid defined value, USB and DSI set voltage vote to 0.8V. Change-Id: I161ed27261df4f3d065cf75a034385016687a99e Signed-off-by: Xipeng Gu --- arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 4 ++-- arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index 50e6018ff9c6..450691b42381 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -687,7 +687,7 @@ hsusb_vdd_dig-supply = <&L6A>; HSUSB_1p8-supply = <&L12A>; HSUSB_3p3-supply = <&L16A>; - qcom,vdd-voltage-level = <0 928000 928000>; + qcom,vdd-voltage-level = <0 800000 800000>; vbus_otg-supply = <&smb2_vbus>; status = "okay"; }; @@ -732,7 +732,7 @@ reg = <0>; qcom,supply-name = "vdda"; qcom,supply-min-voltage = <800000>; - qcom,supply-max-voltage = <930000>; + qcom,supply-max-voltage = <800000>; qcom,supply-enable-load = <100000>; qcom,supply-disable-load = <100>; qcom,supply-post-on-sleep = <20>; diff --git a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi index 3d05d5661783..0a06e2da6a7c 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi @@ -177,7 +177,7 @@ L6A: pm660_l6: regulator-l6 { regulator-min-microvolt = <670000>; regulator-max-microvolt = <930000>; - qcom,init-voltage = <670000>; + qcom,init-voltage = <800000>; status = "okay"; }; }; From 146756d4c8a3efe979c749df3edd80152a15c0b2 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 9 May 2019 16:34:09 +0530 Subject: [PATCH 124/281] msm: vidc: Avoid information leak while accessing the packet Use trusted packet size on the received packet and check for the size of the data received against the expected size before accessing the packet. Change-Id: I1bd6008249a0bf4edeec711ec8d23cf7b8dac1f1 Signed-off-by: Priyanka Gujjula --- .../platform/msm/vidc/hfi_response_handler.c | 95 ++++++++++++++++--- .../msm/vidc_3x/hfi_response_handler.c | 77 ++++++++++++--- 2 files changed, 148 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index 1e82d32dfe01..bde311010a68 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -103,12 +103,22 @@ static enum msm_vidc_pixel_depth get_hal_pixel_depth(u32 hfi_bit_depth) return MSM_VIDC_BIT_DEPTH_UNSUPPORTED; } +static inline int validate_pkt_size(u32 rem_size, u32 msg_size) +{ + if (rem_size < msg_size) { + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, rem_size); + return false; + } + return true; +} + static int hfi_process_sess_evt_seq_changed(u32 device_id, struct hfi_msg_event_notify_packet *pkt, struct msm_vidc_cb_info *info) { struct msm_vidc_cb_event event_notify = {0}; - int num_properties_changed; + u32 num_properties_changed; struct hfi_frame_size *frame_sz; struct hfi_profile_level *profile_level; struct hfi_bit_depth *pixel_depth; @@ -116,17 +126,15 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, struct hfi_buffer_requirements *buf_req; struct hfi_index_extradata_input_crop_payload *crop_info; struct hfi_dpb_counts *dpb_counts; - u32 entropy_mode = 0; + u32 rem_size, entropy_mode = 0; u8 *data_ptr; int prop_id; enum msm_vidc_pixel_depth luma_bit_depth, chroma_bit_depth; struct hfi_colour_space *colour_info; - if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { - dprintk(VIDC_ERR, - "hal_process_session_init_done: bad_pkt_size\n"); + if (!validate_pkt_size(pkt->size, + sizeof(struct hfi_msg_event_notify_packet))) return -E2BIG; - } event_notify.device_id = device_id; event_notify.session_id = (void *)(uintptr_t)pkt->session_id; @@ -147,10 +155,18 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, if (num_properties_changed) { data_ptr = (u8 *) &pkt->rg_ext_event_data[0]; + rem_size = pkt->size - sizeof(struct + hfi_msg_event_notify_packet) + sizeof(u32); do { + if (!validate_pkt_size(rem_size, sizeof(u32))) + return -E2BIG; prop_id = (int) *((u32 *)data_ptr); + rem_size -= sizeof(u32); switch (prop_id) { case HFI_PROPERTY_PARAM_FRAME_SIZE: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_frame_size))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); frame_sz = (struct hfi_frame_size *) data_ptr; @@ -160,8 +176,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, frame_sz->height, frame_sz->width); data_ptr += sizeof(struct hfi_frame_size); + rem_size -= sizeof(struct hfi_frame_size); break; case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_profile_level))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); profile_level = (struct hfi_profile_level *) data_ptr; @@ -172,8 +192,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, profile_level->level); data_ptr += sizeof(struct hfi_profile_level); + rem_size -= sizeof(struct hfi_profile_level); break; case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_bit_depth))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); pixel_depth = (struct hfi_bit_depth *) data_ptr; /* @@ -204,8 +228,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, event_notify.bit_depth, luma_bit_depth, chroma_bit_depth); data_ptr += sizeof(struct hfi_bit_depth); + rem_size -= sizeof(struct hfi_bit_depth); break; case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_pic_struct))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); pic_struct = (struct hfi_pic_struct *) data_ptr; event_notify.pic_struct = @@ -215,8 +243,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, pic_struct->progressive_only); data_ptr += sizeof(struct hfi_pic_struct); + rem_size -= sizeof(struct hfi_pic_struct); break; case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_dpb_counts))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); dpb_counts = (struct hfi_dpb_counts *) data_ptr; event_notify.max_dpb_count = @@ -231,9 +263,13 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, dpb_counts->max_ref_count, dpb_counts->max_dec_buffering); data_ptr += - sizeof(struct hfi_pic_struct); + sizeof(struct hfi_dpb_counts); + rem_size -= sizeof(struct hfi_dpb_counts); break; case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_colour_space))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); colour_info = (struct hfi_colour_space *) data_ptr; @@ -244,8 +280,11 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, colour_info->colour_space); data_ptr += sizeof(struct hfi_colour_space); + rem_size -= sizeof(struct hfi_colour_space); break; case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: + if (!validate_pkt_size(rem_size, sizeof(u32))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); entropy_mode = *(u32 *)data_ptr; event_notify.entropy_mode = entropy_mode; @@ -253,8 +292,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, "Entropy Mode: 0x%x\n", entropy_mode); data_ptr += sizeof(u32); + rem_size -= sizeof(u32); break; case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_buffer_requirements))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); buf_req = (struct hfi_buffer_requirements *) @@ -266,8 +309,13 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, event_notify.capture_buf_count); data_ptr += sizeof(struct hfi_buffer_requirements); + rem_size -= + sizeof(struct hfi_buffer_requirements); break; case HFI_INDEX_EXTRADATA_INPUT_CROP: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_index_extradata_input_crop_payload))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); crop_info = (struct hfi_index_extradata_input_crop_payload *) @@ -288,6 +336,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, data_ptr += sizeof(struct hfi_index_extradata_input_crop_payload); + rem_size -= sizeof(struct + hfi_index_extradata_input_crop_payload); break; default: dprintk(VIDC_ERR, @@ -747,7 +797,7 @@ static inline void copy_cap_prop( } static int hfi_fill_codec_info(u8 *data_ptr, - struct vidc_hal_sys_init_done *sys_init_done) { + struct vidc_hal_sys_init_done *sys_init_done, u32 rem_size) { u32 i; u32 codecs = 0, codec_count = 0, size = 0; struct msm_vidc_capability *capability; @@ -757,6 +807,9 @@ static int hfi_fill_codec_info(u8 *data_ptr, if (prop_id == HFI_PROPERTY_PARAM_CODEC_SUPPORTED) { struct hfi_codec_supported *prop; + if (!validate_pkt_size(rem_size - sizeof(u32), + sizeof(struct hfi_codec_supported))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); prop = (struct hfi_codec_supported *) data_ptr; sys_init_done->dec_codec_supported = @@ -764,6 +817,8 @@ static int hfi_fill_codec_info(u8 *data_ptr, sys_init_done->enc_codec_supported = prop->encoder_codec_supported; size = sizeof(struct hfi_codec_supported) + sizeof(u32); + rem_size -= + sizeof(struct hfi_codec_supported) + sizeof(u32); } else { dprintk(VIDC_WARN, "%s: prop_id %#x, expected codec_supported property\n", @@ -804,14 +859,22 @@ static int hfi_fill_codec_info(u8 *data_ptr, } sys_init_done->codec_count = codec_count; + if (!validate_pkt_size(rem_size, sizeof(u32))) + return -E2BIG; prop_id = *((u32 *)(orig_data_ptr + size)); if (prop_id == HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED) { - struct hfi_max_sessions_supported *prop = - (struct hfi_max_sessions_supported *) + struct hfi_max_sessions_supported *prop; + + if (!validate_pkt_size(rem_size - sizeof(u32), sizeof(struct + hfi_max_sessions_supported))) + return -E2BIG; + prop = (struct hfi_max_sessions_supported *) (orig_data_ptr + size + sizeof(u32)); sys_init_done->max_sessions_supported = prop->max_sessions; size += sizeof(struct hfi_max_sessions_supported) + sizeof(u32); + rem_size -= + sizeof(struct hfi_max_sessions_supported) + sizeof(u32); dprintk(VIDC_DBG, "max_sessions_supported %d\n", prop->max_sessions); } @@ -1167,7 +1230,8 @@ enum vidc_status hfi_process_sys_init_done_prop_read( struct vidc_hal_sys_init_done *sys_init_done) { enum vidc_status status = VIDC_ERR_NONE; - u32 rem_bytes, bytes_read, num_properties; + int bytes_read; + u32 rem_bytes, num_properties; u8 *data_ptr; if (!pkt || !sys_init_done) { @@ -1175,6 +1239,11 @@ enum vidc_status hfi_process_sys_init_done_prop_read( "hfi_msg_sys_init_done: Invalid input\n"); return VIDC_ERR_FAIL; } + if (pkt->size < sizeof(struct hfi_msg_sys_init_done_packet)) { + dprintk(VIDC_ERR, "%s: bad_packet_size: %d\n", + __func__, pkt->size); + return VIDC_ERR_FAIL; + } rem_bytes = pkt->size - sizeof(struct hfi_msg_sys_init_done_packet) + sizeof(u32); @@ -1202,7 +1271,9 @@ enum vidc_status hfi_process_sys_init_done_prop_read( "Venus didn't set any properties in SYS_INIT_DONE"); return status; } - bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done); + bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done, rem_bytes); + if (bytes_read < 0) + return VIDC_ERR_FAIL; data_ptr += bytes_read; rem_bytes -= bytes_read; num_properties--; diff --git a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c index 9f85f5d8b0f0..5dfb4427ba34 100644 --- a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c @@ -100,12 +100,22 @@ static enum msm_vidc_pixel_depth get_hal_pixel_depth(u32 hfi_bit_depth) return MSM_VIDC_BIT_DEPTH_UNSUPPORTED; } +static inline int validate_pkt_size(u32 rem_size, u32 msg_size) +{ + if (rem_size < msg_size) { + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, rem_size); + return false; + } + return true; +} + static int hfi_process_sess_evt_seq_changed(u32 device_id, struct hfi_msg_event_notify_packet *pkt, struct msm_vidc_cb_info *info) { struct msm_vidc_cb_event event_notify = {0}; - int num_properties_changed; + u32 num_properties_changed, rem_size; struct hfi_frame_size *frame_sz; struct hfi_profile_level *profile_level; struct hfi_bit_depth *pixel_depth; @@ -114,15 +124,11 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, int prop_id; enum msm_vidc_pixel_depth luma_bit_depth, chroma_bit_depth; struct hfi_colour_space *colour_info; - /* Initialize pic_struct to unknown as default */ event_notify.pic_struct = MSM_VIDC_PIC_STRUCT_UNKNOWN; - - if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { - dprintk(VIDC_ERR, - "hal_process_session_init_done: bad_pkt_size\n"); + if (!validate_pkt_size(pkt->size, + sizeof(struct hfi_msg_event_notify_packet))) return -E2BIG; - } event_notify.device_id = device_id; event_notify.session_id = (void *)(uintptr_t)pkt->session_id; @@ -143,10 +149,18 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, if (num_properties_changed) { data_ptr = (u8 *) &pkt->rg_ext_event_data[0]; + rem_size = pkt->size - sizeof(struct + hfi_msg_event_notify_packet) + sizeof(u32); do { + if (!validate_pkt_size(rem_size, sizeof(u32))) + return -E2BIG; prop_id = (int) *((u32 *)data_ptr); + rem_size -= sizeof(u32); switch (prop_id) { case HFI_PROPERTY_PARAM_FRAME_SIZE: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_frame_size))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); frame_sz = (struct hfi_frame_size *) data_ptr; @@ -156,8 +170,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, frame_sz->height, frame_sz->width); data_ptr += sizeof(struct hfi_frame_size); + rem_size -= sizeof(struct hfi_frame_size); break; case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_profile_level))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); profile_level = (struct hfi_profile_level *) data_ptr; @@ -166,8 +184,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, profile_level->level); data_ptr += sizeof(struct hfi_profile_level); + rem_size -= sizeof(struct hfi_profile_level); break; case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_bit_depth))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); pixel_depth = (struct hfi_bit_depth *) data_ptr; /* @@ -198,8 +220,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, event_notify.bit_depth, luma_bit_depth, chroma_bit_depth); data_ptr += sizeof(struct hfi_bit_depth); + rem_size -= sizeof(struct hfi_bit_depth); break; case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_pic_struct))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); pic_struct = (struct hfi_pic_struct *) data_ptr; event_notify.pic_struct = @@ -209,8 +235,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, pic_struct->progressive_only); data_ptr += sizeof(struct hfi_pic_struct); + rem_size -= sizeof(struct hfi_pic_struct); break; case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE: + if (!validate_pkt_size(rem_size, sizeof(struct + hfi_colour_space))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); colour_info = (struct hfi_colour_space *) data_ptr; @@ -221,6 +251,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id, colour_info->colour_space); data_ptr += sizeof(struct hfi_colour_space); + rem_size -= sizeof(struct hfi_colour_space); + break; break; default: dprintk(VIDC_ERR, @@ -579,7 +611,7 @@ static inline void copy_cap_prop( } static int hfi_fill_codec_info(u8 *data_ptr, - struct vidc_hal_sys_init_done *sys_init_done) { + struct vidc_hal_sys_init_done *sys_init_done, u32 rem_size) { u32 i; u32 codecs = 0, codec_count = 0, size = 0; struct msm_vidc_capability *capability; @@ -589,6 +621,9 @@ static int hfi_fill_codec_info(u8 *data_ptr, if (prop_id == HFI_PROPERTY_PARAM_CODEC_SUPPORTED) { struct hfi_codec_supported *prop; + if (!validate_pkt_size(rem_size - sizeof(u32), + sizeof(struct hfi_codec_supported))) + return -E2BIG; data_ptr = data_ptr + sizeof(u32); prop = (struct hfi_codec_supported *) data_ptr; sys_init_done->dec_codec_supported = @@ -596,6 +631,8 @@ static int hfi_fill_codec_info(u8 *data_ptr, sys_init_done->enc_codec_supported = prop->encoder_codec_supported; size = sizeof(struct hfi_codec_supported) + sizeof(u32); + rem_size -= + sizeof(struct hfi_codec_supported) + sizeof(u32); } else { dprintk(VIDC_WARN, "%s: prop_id %#x, expected codec_supported property\n", @@ -636,14 +673,22 @@ static int hfi_fill_codec_info(u8 *data_ptr, } sys_init_done->codec_count = codec_count; + if (!validate_pkt_size(rem_size, sizeof(u32))) + return -E2BIG; prop_id = *((u32 *)(orig_data_ptr + size)); if (prop_id == HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED) { - struct hfi_max_sessions_supported *prop = - (struct hfi_max_sessions_supported *) + struct hfi_max_sessions_supported *prop; + + if (!validate_pkt_size(rem_size - sizeof(u32), sizeof(struct + hfi_max_sessions_supported))) + return -E2BIG; + prop = (struct hfi_max_sessions_supported *) (orig_data_ptr + size + sizeof(u32)); sys_init_done->max_sessions_supported = prop->max_sessions; size += sizeof(struct hfi_max_sessions_supported) + sizeof(u32); + rem_size -= + sizeof(struct hfi_max_sessions_supported) + sizeof(u32); dprintk(VIDC_DBG, "max_sessions_supported %d\n", prop->max_sessions); } @@ -1003,7 +1048,8 @@ enum vidc_status hfi_process_sys_init_done_prop_read( struct vidc_hal_sys_init_done *sys_init_done) { enum vidc_status status = VIDC_ERR_NONE; - u32 rem_bytes, bytes_read, num_properties; + int bytes_read; + u32 rem_bytes, num_properties; u8 *data_ptr; u32 codecs = 0, domain = 0; @@ -1012,6 +1058,11 @@ enum vidc_status hfi_process_sys_init_done_prop_read( "hfi_msg_sys_init_done: Invalid input\n"); return VIDC_ERR_FAIL; } + if (pkt->size < sizeof(struct hfi_msg_sys_init_done_packet)) { + dprintk(VIDC_ERR, "%s: bad packet size: %d\n", + __func__, pkt->size); + return VIDC_ERR_FAIL; + } rem_bytes = pkt->size - sizeof(struct hfi_msg_sys_init_done_packet) + sizeof(u32); @@ -1039,7 +1090,9 @@ enum vidc_status hfi_process_sys_init_done_prop_read( "Venus didn't set any properties in SYS_INIT_DONE"); return status; } - bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done); + bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done, rem_bytes); + if (bytes_read < 0) + return VIDC_ERR_FAIL; data_ptr += bytes_read; rem_bytes -= bytes_read; num_properties--; From 6eb74699c3e20bfd70abf398f742456424d10bbd Mon Sep 17 00:00:00 2001 From: Ziyu Jian Date: Tue, 16 Jul 2019 14:45:54 +0800 Subject: [PATCH 125/281] ARM: dts: msm: Modify camera sensor power config for sdm845 rb3 device - Modify the power config as the schematic for cam-sensor@4 for sdm845 rb3 device. - Change cam-sensor@4 to be cam-sensor@6. Change-Id: I24df990fd6517cc08488445222f68ce22ac347d6 Signed-off-by: Ziyu Jian --- .../dts/qcom/sdm845-camera-sensor-rb3.dtsi | 44 +++++++++---------- arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi | 3 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi index 8aac76e8b5d2..8f25cb020c22 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi @@ -139,30 +139,30 @@ cam_clk-supply = <&titan_top_gdsc>; regulator-names = "cam_vio", "cam_clk"; rgltr-cntrl-support; - rgltr-min-voltage = <1800000 0>; - rgltr-max-voltage = <1800000 0>; - rgltr-load-current = <80000 0>; + rgltr-min-voltage = <0 0>; + rgltr-max-voltage = <0 0>; + rgltr-load-current = <0 0>; gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk0_active + pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_rear4_active>; - pinctrl-1 = <&cam_sensor_mclk0_suspend + pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_rear4_suspend>; - gpios = <&tlmm 13 0>, + gpios = <&tlmm 15 0>, <&tlmm 12 0>, <&tlmm 69 0>; gpio-reset = <1>; gpio-custom1 = <2>; gpio-req-tbl-num = <0 1 2>; gpio-req-tbl-flags = <1 0 0>; - gpio-req-tbl-label = "CAMIF_MCLK0", + gpio-req-tbl-label = "CAMIF_MCLK4", "CAM_RESET4", "CAM_CUSTOM4"; sensor-position = <0>; sensor-mode = <0>; cci-master = <1>; status = "ok"; - clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; clock-names = "cam_clk"; clock-cntl-level = "turbo"; clock-rates = <24000000>; @@ -261,9 +261,9 @@ cam_clk-supply = <&titan_top_gdsc>; regulator-names = "cam_vio", "cam_clk"; rgltr-cntrl-support; - rgltr-min-voltage = <1800000 0>; - rgltr-max-voltage = <1800000 0>; - rgltr-load-current = <100000 0>; + rgltr-min-voltage = <0 0>; + rgltr-max-voltage = <0 0>; + rgltr-load-current = <0 0>; gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk3_active @@ -286,10 +286,10 @@ clock-rates = <24000000>; }; - qcom,cam-sensor@4 { - cell-index = <4>; + qcom,cam-sensor@6 { + cell-index = <6>; compatible = "qcom,cam-sensor"; - reg = <0x4>; + reg = <0x6>; csiphy-sd-index = <2>; sensor-position-roll = <270>; sensor-position-pitch = <0>; @@ -303,29 +303,29 @@ cam_clk-supply = <&titan_top_gdsc>; regulator-names = "cam_vio", "cam_clk"; rgltr-cntrl-support; - rgltr-min-voltage = <1800000 0>; - rgltr-max-voltage = <1800000 0>; - rgltr-load-current = <80000 0>; + rgltr-min-voltage = <0 0>; + rgltr-max-voltage = <0 0>; + rgltr-load-current = <0 0>; gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk0_active + pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_rear4_active>; - pinctrl-1 = <&cam_sensor_mclk0_suspend + pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_rear4_suspend>; - gpios = <&tlmm 13 0>, + gpios = <&tlmm 15 0>, <&tlmm 12 0>, <&tlmm 69 0>; gpio-reset = <1>; gpio-custom1 = <2>; gpio-req-tbl-num = <0 1 2>; gpio-req-tbl-flags = <1 0 0>; - gpio-req-tbl-label = "CAMIF_MCLK0", + gpio-req-tbl-label = "CAMIF_MCLK4", "CAM_RESET4", "CAM_CUSTOM4"; sensor-mode = <0>; cci-master = <1>; status = "ok"; - clocks = <&clock_camcc CAM_CC_MCLK0_CLK>; + clocks = <&clock_camcc CAM_CC_MCLK2_CLK>; clock-names = "cam_clk"; clock-cntl-level = "turbo"; clock-rates = <24000000>; diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi index 9f3bd2b1c0dc..dbc69f929c7c 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi @@ -171,9 +171,8 @@ config { pins = "gpio12","gpio69"; - bias-pull-down; /* PULL DOWN */ + bias-disable; /* No PULL */ drive-strength = <2>; /* 2 MA */ - output-low; }; }; }; From 888de7643cd807339c83b15764446ed7c1be9ba1 Mon Sep 17 00:00:00 2001 From: Chaoli Zhou Date: Fri, 12 Jul 2019 14:38:06 +0800 Subject: [PATCH 126/281] ARM: dts: msm: Enable SMMU for WLAN IPA Since sa415 has its own target dts file now, so add the cnss dts node in the sa415m-ttp.dtsi to override the cnss configuration in the sdxpoorwills, which also enable SMMU for Rome. And then cnss2 can parse them. Change-Id: I96e312e560d640fb7a725024d58d4dbc9b0fda4c Signed-off-by: Chaoli Zhou --- arch/arm/boot/dts/qcom/sa415m-ttp.dtsi | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi index e8fdc08c3174..27d4437cb67d 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi +++ b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi @@ -44,6 +44,36 @@ enable-active-high; gpio = <&tlmm 71 GPIO_ACTIVE_HIGH>; }; + cnss_pcie: qcom,cnss { + compatible = "qcom,cnss"; + reg = <0x10000000 0x10000000>, + <0x20000000 0x10000>; + reg-names = "smmu_iova_base", "smmu_iova_ipa"; + + wlan-en-gpio = <&tlmm 52 0>; + vdd-wlan-supply = <&vreg_wlan>; + vdd-wlan-xtal-supply = <&pmxpoorwills_l6>; + vdd-wlan-io-supply = <&pmxpoorwills_l6>; + qcom,notify-modem-status; + pinctrl-names = "wlan_en_active", "wlan_en_sleep"; + pinctrl-0 = <&cnss_wlan_en_active>; + pinctrl-1 = <&cnss_wlan_en_sleep>; + qcom,wlan-rc-num = <0>; + qcom,wlan-ramdump-dynamic = <0x200000>; + qcom,smmu-s1-enable; + qcom,msm-bus,name = "msm-cnss"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, <1 512 0 0>, + /* Upto 200 Mbps */ + <45 512 41421 655360>, <1 512 41421 655360>, + /* Upto 400 Mbps */ + <45 512 98572 655360>, <1 512 98572 1600000>, + /* Upto 800 Mbps */ + <45 512 207108 1146880>, <1 512 207108 3124992>; + + }; }; &i2c_3 { From 9a0840c02254145be95cf795781532ae0918cca6 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Wed, 17 Jul 2019 11:09:01 -0700 Subject: [PATCH 127/281] defconfig: msm: Configure IPC_ROUTER Node ID for sdxpoorwills-auto Configure the IPC_ROUTER Node ID as 2 for sdxpoorwills-auto since this target may be used as a device to an APQ or MSM host. Change-Id: I16cac4c3037668e0b609d4fabc131d1b9179fa35 Signed-off-by: Gustavo Solaira --- arch/arm/configs/sdxpoorwills-auto-perf_defconfig | 1 + arch/arm/configs/sdxpoorwills-auto_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig index 1af9a91218e7..b04fd97db0be 100644 --- a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig +++ b/arch/arm/configs/sdxpoorwills-auto-perf_defconfig @@ -180,6 +180,7 @@ CONFIG_CFG80211_WEXT=y CONFIG_RFKILL=y CONFIG_IPC_ROUTER=y CONFIG_IPC_ROUTER_SECURITY=y +CONFIG_IPC_ROUTER_NODE_ID=2 CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=12 diff --git a/arch/arm/configs/sdxpoorwills-auto_defconfig b/arch/arm/configs/sdxpoorwills-auto_defconfig index 572c46b2551a..3d0cca3cb4b9 100644 --- a/arch/arm/configs/sdxpoorwills-auto_defconfig +++ b/arch/arm/configs/sdxpoorwills-auto_defconfig @@ -181,6 +181,7 @@ CONFIG_CFG80211_WEXT=y CONFIG_RFKILL=y CONFIG_IPC_ROUTER=y CONFIG_IPC_ROUTER_SECURITY=y +CONFIG_IPC_ROUTER_NODE_ID=2 CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=12 From 44184f06645298a8a2a1cec093e1780386ed5496 Mon Sep 17 00:00:00 2001 From: zhaochen Date: Wed, 3 Jul 2019 20:07:23 +0800 Subject: [PATCH 128/281] ARM: qcom: add board config support for sdm429w Add new board config to support new soc-id on sdm429w. Change-Id: I25542ca98436952250b0592ab4248d43e103df15 Signed-off-by: Zhaoyuan Cheng --- arch/arm/mach-qcom/board-sdm429.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-qcom/board-sdm429.c b/arch/arm/mach-qcom/board-sdm429.c index 6bdf0f4eb957..3638c37be474 100644 --- a/arch/arm/mach-qcom/board-sdm429.c +++ b/arch/arm/mach-qcom/board-sdm429.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, 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 @@ -18,6 +18,7 @@ static const char *sdm429_dt_match[] __initconst = { "qcom,sdm429", "qcom,sda429", + "qcom,sdm429w", NULL }; From a6e8a0736863ce911d4cd27e0c04a4be04c9e553 Mon Sep 17 00:00:00 2001 From: Hardik Arya Date: Wed, 17 Jul 2019 15:16:32 +0530 Subject: [PATCH 129/281] diag: Close cmd socket after receiving remove channel Closing of the cmd socket channel after receiving remove channel from IPC router is dependent on restart notifier, which can cause not closing cmd channel client when peripheral is up and channel will keep using the old server address. The patch closes the command channel after receiving notification from IPC router without checking status of peripheral. Change-Id: I0ce99550d2505731a1659ae57c6c4a166cd5cb48 Signed-off-by: Hardik Arya --- drivers/char/diag/diagfwd_socket.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/char/diag/diagfwd_socket.c b/drivers/char/diag/diagfwd_socket.c index 401dbb0f7c25..d7d73668b7b8 100644 --- a/drivers/char/diag/diagfwd_socket.c +++ b/drivers/char/diag/diagfwd_socket.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, 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 @@ -496,7 +496,8 @@ static void __socket_close_channel(struct diag_socket_info *info) if (!atomic_read(&info->opened)) return; - if (bootup_req[info->peripheral] == PEPIPHERAL_SSR_UP) { + if ((bootup_req[info->peripheral] == PEPIPHERAL_SSR_UP) && + (info->port_type == PORT_TYPE_SERVER)) { DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "diag: %s is up, stopping cleanup: bootup_req = %d\n", info->name, (int)bootup_req[info->peripheral]); From f18104ef267bf2be0fdda667b0fde6409ea09f05 Mon Sep 17 00:00:00 2001 From: Raja Mallik Date: Mon, 8 Jul 2019 16:36:28 +0530 Subject: [PATCH 130/281] msm: camera: eeprom: Fix OOB read/write in EEPROM Adding OOB check for memory map parser in order to access correct memory map. Change-Id: Iec5e8642531c586f7db96195803f0505c4648b50 Signed-off-by: Jigarkumar Zala Signed-off-by: Raja Mallik --- .../cam_eeprom/cam_eeprom_core.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 8f59ca36d5d8..35a36f3821be 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -439,17 +439,29 @@ static int32_t cam_eeprom_parse_memory_map( else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) validate_size = sizeof(struct cam_cmd_unconditional_wait); - if (remain_buf_len < validate_size) { + if (remain_buf_len < validate_size || + *num_map >= MSM_EEPROM_MAX_MEM_MAP_CNT) { CAM_ERR(CAM_EEPROM, "not enough buffer"); return -EINVAL; } switch (cmm_hdr->cmd_type) { case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR: i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf; + + if (i2c_random_wr->header.count == 0 || + i2c_random_wr->header.count >= MSM_EEPROM_MAX_MEM_MAP_CNT || + (size_t)*num_map > U16_MAX - i2c_random_wr->header.count) { + CAM_ERR(CAM_EEPROM, "OOB Error"); + return -EINVAL; + } cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_random_wr) + ((i2c_random_wr->header.count - 1) * sizeof(struct i2c_random_wr_payload)); + if (cmd_length_in_bytes > remain_buf_len) { + CAM_ERR(CAM_EEPROM, "Not enough buffer remaining"); + return -EINVAL; + } for (cnt = 0; cnt < (i2c_random_wr->header.count); cnt++) { map[*num_map + cnt].page.addr = @@ -472,6 +484,11 @@ static int32_t cam_eeprom_parse_memory_map( i2c_cont_rd = (struct cam_cmd_i2c_continuous_rd *)cmd_buf; cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd); + if (i2c_cont_rd->header.count >= U32_MAX - data->num_data) { + CAM_ERR(CAM_EEPROM, + "int overflow on eeprom memory block"); + return -EINVAL; + } map[*num_map].mem.addr = i2c_cont_rd->reg_addr; map[*num_map].mem.addr_type = i2c_cont_rd->header.addr_type; map[*num_map].mem.data_type = i2c_cont_rd->header.data_type; From 2fa3ca67f30b4aded8396b9f02793062048ac2f7 Mon Sep 17 00:00:00 2001 From: Raja Mallik Date: Thu, 18 Jul 2019 17:36:25 +0530 Subject: [PATCH 131/281] msm: camera_v3: eeprom: Fix OOB condition for memory map count Fix OOB check for memory map count to access correct memory map. Change-Id: Ib41d1582d8fb0dbdc0a2e3e09873a84d74f55bce Signed-off-by: Jigarkumar Zala Signed-off-by: Sridhar Gujje Signed-off-by: Raja Mallik --- .../cam_sensor_module/cam_eeprom/cam_eeprom_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 35a36f3821be..06d6bd49b3b0 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -440,7 +440,8 @@ static int32_t cam_eeprom_parse_memory_map( validate_size = sizeof(struct cam_cmd_unconditional_wait); if (remain_buf_len < validate_size || - *num_map >= MSM_EEPROM_MAX_MEM_MAP_CNT) { + *num_map >= (MSM_EEPROM_MAX_MEM_MAP_CNT * + MSM_EEPROM_MEMORY_MAP_MAX_SIZE)) { CAM_ERR(CAM_EEPROM, "not enough buffer"); return -EINVAL; } @@ -450,7 +451,9 @@ static int32_t cam_eeprom_parse_memory_map( if (i2c_random_wr->header.count == 0 || i2c_random_wr->header.count >= MSM_EEPROM_MAX_MEM_MAP_CNT || - (size_t)*num_map > U16_MAX - i2c_random_wr->header.count) { + (size_t)*num_map >= ((MSM_EEPROM_MAX_MEM_MAP_CNT * + MSM_EEPROM_MEMORY_MAP_MAX_SIZE) - + i2c_random_wr->header.count)) { CAM_ERR(CAM_EEPROM, "OOB Error"); return -EINVAL; } From 773c709eec104ecc96c98645222be4d56d478cbc Mon Sep 17 00:00:00 2001 From: shaoxing Date: Wed, 17 Jul 2019 21:37:13 +0800 Subject: [PATCH 132/281] ARM: dts: msm: Add smp2p devices for msm8937 Add SMP2P sleepstate device support for msm8937 to ADSP Change-Id: I1d4a7adbd2027612d3f17863d94e4d229dee53e9 Signed-off-by: Shaoxing --- arch/arm64/boot/dts/qcom/msm8937-smp2p.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8937-smp2p.dtsi b/arch/arm64/boot/dts/qcom/msm8937-smp2p.dtsi index d5537e96f9b6..7b6d4d1ae3c5 100644 --- a/arch/arm64/boot/dts/qcom/msm8937-smp2p.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8937-smp2p.dtsi @@ -158,6 +158,21 @@ gpios = <&smp2pgpio_smp2p_2_out 0 0>; }; + smp2pgpio_sleepstate_2_out: qcom,smp2pgpio-sleepstate-gpio-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "sleepstate"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio-sleepstate-2-out { + compatible = "qcom,smp2pgpio-sleepstate-out"; + gpios = <&smp2pgpio_sleepstate_2_out 0 0>; + }; + /* ssr - inbound entry from mss. */ smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in { compatible = "qcom,smp2pgpio"; From 2e036f0d8c598996d248004cd2f5a9f30eea6a4c Mon Sep 17 00:00:00 2001 From: zhaochen Date: Thu, 20 Jun 2019 14:42:29 +0800 Subject: [PATCH 133/281] usb: xhci: Add support UPD720201K8 PCI to USB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The µPD720201 is a USB host controller LSI compatible with the USB 3.0 and xHCI (eXtensible Host Controller Interface) 1.0 specifications.The system bus is compatible with the PCIe Gen2 specification.The controller provides four USB ports with LS (low-Speed) / FS (full-Speed) / HS (high-Speed) / SS (SuperSpeed) support. The µPD720201 comes in a 68-pin QFN package and has the following improvements over previous products. Change-Id: Ie77c2d6d57e88c91d493f5055bef15a7d6b537a8 Signed-off-by: zhaochen --- drivers/usb/host/Kconfig | 6 + drivers/usb/host/Makefile | 1 + drivers/usb/host/pci-quirks.h | 6 + drivers/usb/host/xhci-fwdload.c | 228 ++++++++++++++++++++++++++++++++ drivers/usb/host/xhci-pci.c | 4 +- 5 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/host/xhci-fwdload.c diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 0e7cc71b34a9..d44905bcf71b 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -804,3 +804,9 @@ config USB_HCD_TEST_MODE This option is of interest only to developers who need to validate their USB hardware designs. It is not needed for normal use. If unsure, say N. + +config USB_UPD720X + tristate "Support for Renesas UPD720X XHCI USB controller" + ---help--- + Enables support for the USB Host controller present on the + Renesas UPD720X chipsets. diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 6ef785b0ea8f..fc6981a602c4 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -82,3 +82,4 @@ obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o obj-$(CONFIG_USB_MAX3421_HCD) += max3421-hcd.o +obj-$(CONFIG_USB_UPD720X) += xhci-fwdload.o diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 6463fdb403c2..38a91d829aa0 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -15,6 +15,11 @@ void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev); void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev); void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); void sb800_prefetch(struct device *dev, int on); +#ifdef CONFIG_USB_UPD720X +void upd720x_finish_download(struct pci_dev *pDev); +#else +#define upd720x_finish_download(pDev) +#endif #else struct pci_dev; static inline void usb_amd_quirk_pll_disable(void) {} @@ -23,6 +28,7 @@ static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {} static inline void usb_amd_dev_put(void) {} static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} static inline void sb800_prefetch(struct device *dev, int on) {} +#define upd720x_finish_download(pDev) #endif /* CONFIG_PCI */ #endif /* __LINUX_USB_PCI_QUIRKS_H */ diff --git a/drivers/usb/host/xhci-fwdload.c b/drivers/usb/host/xhci-fwdload.c new file mode 100644 index 000000000000..f214e03be659 --- /dev/null +++ b/drivers/usb/host/xhci-fwdload.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2019 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 +#include +#include +#include +#include +#include +#include + +#define upd720x_firmware "K2026090.mem" + +#define UPD_PCI_F4 0xF4 + +#define UPD_PCI_F4_FWDOWNLOADENABLE (0x0001) +#define UPD_PCI_F4_FWDOWNLOADLOCK (0x0002) +#define UPD_PCI_F4_SETDATA0 (0x0100) +#define UPD_PCI_F4_SETDATA1 (0x0200) +#define UPD_PCI_F4_RESULT (0x0070) + +#define UPD_PCI_F8 0xF8 + +#define UPD_PCI_FC 0xFC + +enum SET_DATA { + SET_DATA_PAGE0, + SET_DATA_PAGE1 +}; + +#define SMMU_BASE 0x10000000 +#define SMMU_SIZE 0x40000000 + +struct firmware *fw_pointer; +static struct dma_iommu_mapping *upd720x_smmu_init(struct device *dev) +{ + int rc = 0; + int atomic_ctx = 1; + int bypass_enable = 1; + struct dma_iommu_mapping *mapping = NULL; + + mapping = arm_iommu_create_mapping(&platform_bus_type, + SMMU_BASE, SMMU_SIZE); + if (IS_ERR(mapping)) { + rc = PTR_ERR(mapping); + dev_err(dev, "create mapping failed, err = %d\n", rc); + return NULL; + } + + rc = iommu_domain_set_attr(mapping->domain, + DOMAIN_ATTR_ATOMIC, &atomic_ctx); + if (rc) { + dev_err(dev, "Set atomic attribute to SMMU failed (%d)\n", rc); + arm_iommu_release_mapping(mapping); + return NULL; + } + + rc = iommu_domain_set_attr(mapping->domain, + DOMAIN_ATTR_S1_BYPASS, &bypass_enable); + if (rc) { + dev_err(dev, "Set bypass attribute to SMMU failed (%d)\n", rc); + arm_iommu_release_mapping(mapping); + return NULL; + } + + rc = arm_iommu_attach_device(dev, mapping); + if (rc) { + dev_err(dev, "arm_iommu_attach_device failed (%d)\n", rc); + arm_iommu_release_mapping(mapping); + return NULL; + } + + pr_info("attached to IOMMU\n"); + return mapping; +} + +static void upd720x_smmu_deinit(struct device *dev) +{ + arm_iommu_detach_device(dev); + arm_iommu_release_mapping(to_dma_iommu_mapping(dev)); +} + + +static int upd720x_download_enable(struct pci_dev *pDev) +{ + unsigned int read_data; + int result; + + result = pci_read_config_dword(pDev, UPD_PCI_F4, &read_data); + pr_info("Set FW Download enable\n"); + result = pci_write_config_dword(pDev, UPD_PCI_F4, read_data | + UPD_PCI_F4_FWDOWNLOADENABLE); + return result; +} + +static int upd720x_download_lock(struct pci_dev *pDev) +{ + unsigned int read_data; + int result; + + result = pci_read_config_dword(pDev, UPD_PCI_F4, &read_data); + pr_info("Set FW Download lock\n"); + result = pci_write_config_dword(pDev, UPD_PCI_F4, read_data | + UPD_PCI_F4_FWDOWNLOADLOCK); + return result; +} + +static int upd720x_set_data0(struct pci_dev *pDev) +{ + unsigned int read_data; + int result; + + result = pci_read_config_dword(pDev, UPD_PCI_F4, &read_data); + result = pci_write_config_dword(pDev, UPD_PCI_F4, + (read_data & ~UPD_PCI_F4_SETDATA1) | + UPD_PCI_F4_SETDATA0); + + return result; +} + +static int upd720x_set_data1(struct pci_dev *pDev) +{ + unsigned int read_data; + int result; + + result = pci_read_config_dword(pDev, UPD_PCI_F4, &read_data); + result = pci_write_config_dword(pDev, UPD_PCI_F4, + (read_data & ~UPD_PCI_F4_SETDATA0) | + UPD_PCI_F4_SETDATA1); + + return result; +} + +static int upd720x_download_clearcontrol(struct pci_dev *pDev) +{ + int read_buf; + int rc; + + rc = pci_read_config_dword(pDev, UPD_PCI_F4, &read_buf); + if (rc == 0) { + rc = pci_write_config_dword(pDev, UPD_PCI_F4, read_buf & + ~UPD_PCI_F4_FWDOWNLOADENABLE); + } + return rc; +} +int upd720x_firmware_download(struct pci_dev *pDev, + unsigned char *pFWImage, unsigned int firmware_size) +{ + enum SET_DATA page = SET_DATA_PAGE0; + int offset; + unsigned int *image = (unsigned int *)pFWImage; + unsigned int fw_dwordsize = firmware_size / + (sizeof(unsigned int) / sizeof(unsigned char)); + + if ((firmware_size % + (sizeof(unsigned int) / sizeof(unsigned char))) != 0) + fw_dwordsize++; + + if (upd720x_download_enable(pDev) == -EFAULT) { + pr_info("Set FW Download Enable is timeout"); + return -EFAULT; + } + + for (offset = 0; offset < fw_dwordsize; offset++) { + switch (page) { + case SET_DATA_PAGE0: + pci_write_config_dword(pDev, UPD_PCI_F8, image[offset]); + + if (upd720x_set_data0(pDev) == -EFAULT) + return -EFAULT; + page = SET_DATA_PAGE1; + break; + + case SET_DATA_PAGE1: + pci_write_config_dword(pDev, UPD_PCI_FC, image[offset]); + if (upd720x_set_data1(pDev) == -EFAULT) + return -EFAULT; + page = SET_DATA_PAGE0; + break; + default: + break; + } + } + + if (upd720x_download_clearcontrol(pDev) == -EFAULT) + return -EFAULT; + + if (upd720x_download_lock(pDev) == -EFAULT) + return -EFAULT; + + return 0; +} + +int upd720x_finish_download(struct pci_dev *pDev) +{ + int result = -EFAULT; + char *firmwarename = upd720x_firmware; + int lc; + int ret; + + if (!upd720x_smmu_init(&pDev->dev)) + return -EFAULT; + + for (lc = 0; (lc < 2) && (fw_pointer == NULL); lc++) { + ret = request_firmware((const struct firmware **)&fw_pointer, + firmwarename, &pDev->bus->dev); + if (ret == 0) { + result = upd720x_firmware_download(pDev, + (unsigned char *)fw_pointer->data, + fw_pointer->size); + break; + } + result = ret; + } + return result; +} + + + diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b5140555a8d5..3e6c4372848c 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -192,8 +192,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_BROKEN_STREAMS; } if (pdev->vendor == PCI_VENDOR_ID_RENESAS && - pdev->device == 0x0014) + pdev->device == 0x0014) { xhci->quirks |= XHCI_TRUST_TX_LENGTH; + upd720x_finish_download(pdev); + } if (pdev->vendor == PCI_VENDOR_ID_RENESAS && pdev->device == 0x0015) xhci->quirks |= XHCI_RESET_ON_RESUME; From 153f7d7a171382b20a8afb7fb02e0da187322625 Mon Sep 17 00:00:00 2001 From: Srinivasarao P Date: Fri, 19 Jul 2019 17:49:43 +0530 Subject: [PATCH 134/281] defconfig: msm: Enable CONFIG_DM_BOW for SDM670/710 Enable DM-BOW for Android userdata check point feature. Change-Id: I107bcde9605afa8891fa97268ba921a1d874c034 Signed-off-by: Srinivasarao P --- arch/arm64/configs/sdm670-perf_defconfig | 1 + arch/arm64/configs/sdm670_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig index 58aabffd6c6c..d80e60357617 100755 --- a/arch/arm64/configs/sdm670-perf_defconfig +++ b/arch/arm64/configs/sdm670-perf_defconfig @@ -276,6 +276,7 @@ CONFIG_DM_DEFAULT_KEY=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig index a9f8f6532276..33deb5107996 100755 --- a/arch/arm64/configs/sdm670_defconfig +++ b/arch/arm64/configs/sdm670_defconfig @@ -284,6 +284,7 @@ CONFIG_DM_DEFAULT_KEY=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y From 01e8422e19ee8d65fdcf2ad7c66054c54f2487b3 Mon Sep 17 00:00:00 2001 From: Bo Zhang Date: Thu, 11 Jul 2019 12:22:08 +0800 Subject: [PATCH 135/281] defconfig: msm: Enable USB ACM for sdm845 add config to enable USB ACM for sdm845. Change-Id: I1f9adf9df7055fd4042fedf933b5097d1b138e1a Signed-off-by: Bo Zhang --- arch/arm64/configs/sdm845-perf_defconfig | 1 + arch/arm64/configs/sdm845_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index 9e0c7a888afd..4529bfb899c0 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -419,6 +419,7 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_ACM=y CONFIG_USB_STORAGE=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_MSM=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index 99b464a1c3dc..c06356427028 100755 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -423,6 +423,7 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_ACM=y CONFIG_USB_STORAGE=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_MSM=y From c4bfd4a87d2f74925fcbb4e44efab8e383ef7075 Mon Sep 17 00:00:00 2001 From: Raja Mallik Date: Mon, 10 Jun 2019 17:32:14 +0530 Subject: [PATCH 136/281] msm: camera: icp: Prevent out of bound access in acquire In ICP during acquire, number of output resources can change from usespace. Change in number of output resources after the memory allocation may result in out of bound access. This can be avoided by checking value of number of output resources during the allocation to the value copied from userspace after allocation. Change-Id: Ifaf5039c13809923b4ce35f369506d5937f3b3f4 Signed-off-by: Prakasha Nayak Signed-off-by: Raja Mallik --- .../camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 2b764d1b97a7..cfc474afc633 100644 --- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -4686,6 +4686,13 @@ static int cam_icp_get_acquire_info(struct cam_icp_hw_mgr *hw_mgr, return -EFAULT; } + /* To make sure num_out_res is same as allocated */ + if (ctx_data->icp_dev_acquire_info->num_out_res != + icp_dev_acquire_info.num_out_res) { + CAM_ERR(CAM_ICP, "num_out_res got changed"); + return -EFAULT; + } + CAM_DBG(CAM_ICP, "%x %x %x %x %x %x %x", ctx_data->icp_dev_acquire_info->dev_type, ctx_data->icp_dev_acquire_info->in_res.format, From c5584a0f24066c79458ed63b3148d25d63b6c790 Mon Sep 17 00:00:00 2001 From: Xipeng Gu Date: Mon, 15 Jul 2019 11:23:51 +0800 Subject: [PATCH 137/281] defconfig: spyro: Remove ImproveTouch support ImproveTouch is not used on spyro device, so remove hbtp driver config. Change-Id: I4176f9b50153ab6b66c4fab25bf0bce9af1f7443 Signed-off-by: Xipeng Gu --- arch/arm/configs/spyro-perf_defconfig | 1 - arch/arm/configs/spyro_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/configs/spyro-perf_defconfig b/arch/arm/configs/spyro-perf_defconfig index d0c6b0505e6f..70a0646aadc9 100644 --- a/arch/arm/configs/spyro-perf_defconfig +++ b/arch/arm/configs/spyro-perf_defconfig @@ -303,7 +303,6 @@ CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26=y CONFIG_INPUT_MISC=y -CONFIG_INPUT_HBTP_INPUT=y CONFIG_INPUT_QPNP_POWER_ON=y CONFIG_INPUT_QTI_HAPTICS=y CONFIG_INPUT_UINPUT=y diff --git a/arch/arm/configs/spyro_defconfig b/arch/arm/configs/spyro_defconfig index 0e10212669a4..a971fa1136a4 100644 --- a/arch/arm/configs/spyro_defconfig +++ b/arch/arm/configs/spyro_defconfig @@ -310,7 +310,6 @@ CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26=y CONFIG_INPUT_MISC=y -CONFIG_INPUT_HBTP_INPUT=y CONFIG_INPUT_QPNP_POWER_ON=y CONFIG_INPUT_QTI_HAPTICS=y CONFIG_INPUT_UINPUT=y From 80d0e2af9cf45df85ce24dd1996fe76c52f644fe Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Mon, 10 Jun 2019 14:11:42 +0530 Subject: [PATCH 138/281] msm: ipa: Update ep info for auto use case on ipav4.0 For Auto use case we need an additional pair of USB and MHI end points. Update ipa driver's ep_mapping accordingly to support auto use case by reading device node from device tree. Change-Id: If4e73c1f6793d8ee89f76518a2da28257381fe34 Signed-off-by: Mohammed Javid --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 9 + drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 3 + drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 489 ++++++++++++++++++++ include/uapi/linux/msm_ipa.h | 10 +- 4 files changed, 510 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index f8fdefd02abd..6de07dc79c59 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -5130,6 +5130,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, ipa3_ctx->use_ipa_teth_bridge = resource_p->use_ipa_teth_bridge; ipa3_ctx->modem_cfg_emb_pipe_flt = resource_p->modem_cfg_emb_pipe_flt; ipa3_ctx->ipa_wdi2 = resource_p->ipa_wdi2; + ipa3_ctx->ipa_config_is_auto = resource_p->ipa_config_is_auto; ipa3_ctx->use_64_bit_dma_mask = resource_p->use_64_bit_dma_mask; ipa3_ctx->wan_rx_ring_size = resource_p->wan_rx_ring_size; ipa3_ctx->lan_rx_ring_size = resource_p->lan_rx_ring_size; @@ -5701,6 +5702,7 @@ static int get_ipa_dts_configuration(struct platform_device *pdev, ipa_drv_res->ipa3_hw_mode = 0; ipa_drv_res->modem_cfg_emb_pipe_flt = false; ipa_drv_res->ipa_wdi2 = false; + ipa_drv_res->ipa_config_is_auto = false; ipa_drv_res->ipa_mhi_dynamic_config = false; ipa_drv_res->use_64_bit_dma_mask = false; ipa_drv_res->use_bw_vote = false; @@ -5785,6 +5787,13 @@ static int get_ipa_dts_configuration(struct platform_device *pdev, ipa_drv_res->ipa_wdi2 ? "True" : "False"); + ipa_drv_res->ipa_config_is_auto = + of_property_read_bool(pdev->dev.of_node, + "qcom,ipa-config-is-auto"); + IPADBG(": ipa-config-is-auto = %s\n", + ipa_drv_res->ipa_config_is_auto + ? "True" : "False"); + ipa_drv_res->use_64_bit_dma_mask = of_property_read_bool(pdev->dev.of_node, "qcom,use-64-bit-dma-mask"); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index d145a4b32927..2caa54eae538 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1446,6 +1446,7 @@ struct ipa3_char_device_context { * @logbuf: ipc log buffer for high priority messages * @logbuf_low: ipc log buffer for low priority messages * @ipa_wdi2: using wdi-2.0 + * @ipa_config_is_auto: is this AUTO use case * @use_64_bit_dma_mask: using 64bits dma mask * @ipa_bus_hdl: msm driver handle for the data path bus * @ctrl: holds the core specific operations based on @@ -1547,6 +1548,7 @@ struct ipa3_context { bool use_ipa_teth_bridge; bool modem_cfg_emb_pipe_flt; bool ipa_wdi2; + bool ipa_config_is_auto; bool use_64_bit_dma_mask; /* featurize if memory footprint becomes a concern */ struct ipa3_stats stats; @@ -1628,6 +1630,7 @@ struct ipa3_plat_drv_res { u32 ee; bool modem_cfg_emb_pipe_flt; bool ipa_wdi2; + bool ipa_config_is_auto; bool use_64_bit_dma_mask; bool use_bw_vote; u32 wan_rx_ring_size; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 3e6b365bccb6..03b0c726d2f6 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -144,6 +144,7 @@ #define IPA_v4_0_GROUP_UL_DL (1) #define IPA_v4_0_MHI_GROUP_DDR (1) #define IPA_v4_0_MHI_GROUP_DMA (2) +#define IPA_v4_0_GROUP_CV2X (2) #define IPA_v4_0_GROUP_UC_RX_Q (3) #define IPA_v4_0_SRC_GROUP_MAX (4) #define IPA_v4_0_DST_GROUP_MAX (4) @@ -216,6 +217,8 @@ enum ipa_ver { IPA_3_5_1, IPA_4_0, IPA_4_0_MHI, + IPA_4_0_AUTO, + IPA_4_0_AUTO_MHI, IPA_VER_MAX, }; @@ -305,6 +308,32 @@ static const struct rsrc_min_max ipa3_rsrc_src_grp_config [IPA_v4_0_RSRC_GRP_TYPE_SRC_ACK_ENTRIES] = { {14, 14}, {14, 14}, {14, 14}, {0, 0}, {0, 0}, {0, 0} }, }, + [IPA_4_0_AUTO] = { + /*not-used UL_DL CV2X not-used, other are invalid */ + [IPA_v4_0_RSRC_GRP_TYPE_SRC_PKT_CONTEXTS] = { + {0, 0}, {1, 255}, {1, 1}, {0, 0}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRS_DESCRIPTOR_LISTS] = { + {0, 0}, {10, 10}, {8, 8}, {0, 0}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRC_DESCRIPTOR_BUFF] = { + {0, 0}, {14, 14}, {8, 8}, {0, 0}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRC_HPS_DMARS] = { + {0, 255}, {0, 255}, {0, 255}, {0, 255}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRC_ACK_ENTRIES] = { + {0, 0}, {20, 20}, {14, 14}, {0, 0}, {0, 0}, {0, 0} }, + }, + [IPA_4_0_AUTO_MHI] = { + /* PCIE DDR DMA/CV2X not used, other are invalid */ + [IPA_v4_0_RSRC_GRP_TYPE_SRC_PKT_CONTEXTS] = { + {4, 4}, {5, 5}, {1, 1}, {0, 0}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRS_DESCRIPTOR_LISTS] = { + {10, 10}, {10, 10}, {8, 8}, {0, 0}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRC_DESCRIPTOR_BUFF] = { + {12, 12}, {12, 12}, {8, 8}, {0, 0}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRC_HPS_DMARS] = { + {0, 255}, {0, 255}, {0, 255}, {0, 255}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_SRC_ACK_ENTRIES] = { + {14, 14}, {14, 14}, {14, 14}, {0, 0}, {0, 0}, {0, 0} }, + }, }; static const struct rsrc_min_max ipa3_rsrc_dst_grp_config @@ -353,6 +382,20 @@ static const struct rsrc_min_max ipa3_rsrc_dst_grp_config [IPA_v4_0_RSRC_GRP_TYPE_DST_DPS_DMARS] = { {2, 255}, {1, 255}, {1, 2}, {0, 2}, {0, 0}, {0, 0} }, }, + [IPA_4_0_AUTO] = { + /*PCIE UL/DL/DPL DMA/CV2X, other are invalid */ + [IPA_v4_0_RSRC_GRP_TYPE_DST_DATA_SECTORS] = { + {4, 4}, {4, 4}, {3, 3}, {2, 2}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_DST_DPS_DMARS] = { + {2, 255}, {1, 255}, {1, 2}, {0, 2}, {0, 0}, {0, 0} }, + }, + [IPA_4_0_AUTO_MHI] = { + /*PCIE DDR DMA/CV2X, other are invalid */ + [IPA_v4_0_RSRC_GRP_TYPE_DST_DATA_SECTORS] = { + {4, 4}, {4, 4}, {3, 3}, {2, 2}, {0, 0}, {0, 0} }, + [IPA_v4_0_RSRC_GRP_TYPE_DST_DPS_DMARS] = { + {2, 255}, {1, 255}, {1, 2}, {0, 2}, {0, 0}, {0, 0} }, + }, }; static const struct rsrc_min_max ipa3_rsrc_rx_grp_config @@ -387,6 +430,16 @@ static const struct rsrc_min_max ipa3_rsrc_rx_grp_config [IPA_RSRC_GRP_TYPE_RX_HPS_CMDQ] = { { 3, 3 }, { 7, 7 }, { 2, 2 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, }, + [IPA_4_0_AUTO] = { + /*not-used UL_DL CV2X not-used, other are invalid */ + [IPA_RSRC_GRP_TYPE_RX_HPS_CMDQ] = { + {0, 0}, {7, 7}, {2, 2}, {0, 0}, {0, 0}, {0, 0} }, + }, + [IPA_4_0_AUTO_MHI] = { + /* PCIE DDR DMA/CV2X not used, other are invalid */ + [IPA_RSRC_GRP_TYPE_RX_HPS_CMDQ] = { + { 3, 3 }, { 7, 7 }, { 2, 2 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + }, }; static const u32 ipa3_rsrc_rx_grp_hps_weight_config @@ -415,6 +468,14 @@ static const u32 ipa3_rsrc_rx_grp_hps_weight_config /* PCIE DDR DMA unused N/A N/A */ [IPA_RSRC_GRP_TYPE_RX_HPS_WEIGHT_CONFIG] = { 3, 5, 1, 1, 0, 0 }, }, + [IPA_4_0_AUTO] = { + /*not-used UL_DL CV2X not-used, other are invalid */ + [IPA_RSRC_GRP_TYPE_RX_HPS_WEIGHT_CONFIG] = { 0, 1, 1, 0, 0, 0 }, + }, + [IPA_4_0_AUTO_MHI] = { + /* PCIE DDR DMA/CV2X not used, other are invalid */ + [IPA_RSRC_GRP_TYPE_RX_HPS_WEIGHT_CONFIG] = { 3, 5, 1, 0, 0, 0 }, + }, }; enum ipa_ees { @@ -1494,6 +1555,417 @@ static const struct ipa_ep_configuration ipa3_ep_mapping IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR, { 31, 31, 8, 8, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + + /* IPA_4_0_AUTO */ + [IPA_4_0_AUTO][IPA_CLIENT_WLAN1_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, + QMB_MASTER_SELECT_DDR, + { 6, 2, 8, 16, IPA_EE_UC, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO][IPA_CLIENT_USB_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, + QMB_MASTER_SELECT_DDR, + { 0, 0, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_USB2_PROD] = { + true, IPA_v4_0_GROUP_CV2X, + true, + IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY, + QMB_MASTER_SELECT_DDR, + { 7, 3, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_APPS_LAN_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 8, 11, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_APPS_WAN_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, + QMB_MASTER_SELECT_DDR, + { 2, 4, 16, 32, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_APPS_CMD_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY, + QMB_MASTER_SELECT_DDR, + { 5, 7, 20, 24, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO][IPA_CLIENT_ODU_PROD] = { + false, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, + QMB_MASTER_SELECT_DDR, + { 1, 0, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_ETHERNET_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, + QMB_MASTER_SELECT_DDR, + { 9, 0, 8, 16, IPA_EE_UC, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO][IPA_CLIENT_Q6_WAN_PROD] = { + false, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 3, 0, 16, 32, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO][IPA_CLIENT_Q6_CMD_PROD] = { + false, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_PKT_PROCESS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 4, 1, 20, 24, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + /* Only for test purpose */ + [IPA_4_0_AUTO][IPA_CLIENT_TEST_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + {0, 8, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_TEST1_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + {0, 8, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_TEST2_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 1, 0, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_TEST3_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 7, 9, 8, 16, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO][IPA_CLIENT_TEST4_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + {8, 10, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + + + [IPA_4_0_AUTO][IPA_CLIENT_WLAN1_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 18, 3, 6, 9, IPA_EE_UC, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO][IPA_CLIENT_WLAN2_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 20, 12, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_WLAN3_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 21, 13, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_USB_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 19, 6, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_USB_DPL_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 15, 10, 5, 5, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_MHI_DPL_CONS] = { + false, IPA_v4_0_MHI_GROUP_PCIE, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_PCIE, + { 12, 2, 5, 5, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_APPS_LAN_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 10, 8, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_APPS_WAN_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 11, 9, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_USB2_CONS] = { + true, IPA_v4_0_GROUP_CV2X, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 17, 1, 9, 9, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO][IPA_CLIENT_ETHERNET_CONS] = { + true, IPA_v4_0_ETHERNET, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 22, 1, 9, 9, IPA_EE_UC, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO][IPA_CLIENT_Q6_LAN_CONS] = { + false, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 14, 4, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO][IPA_CLIENT_Q6_WAN_CONS] = { + false, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 13, 3, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO][IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS] = { + false, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 16, 5, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + /* Only for test purpose */ + /* MBIM aggregation test pipes should have the same QMB as USB_CONS */ + [IPA_4_0_AUTO][IPA_CLIENT_TEST_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 11, 6, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_TEST1_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 11, 6, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_TEST2_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 12, 2, 5, 5, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_TEST3_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 19, 12, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO][IPA_CLIENT_TEST4_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 21, 14, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + /* Dummy consumer (pipe 31) is used in L2TP rt rule */ + [IPA_4_0_AUTO][IPA_CLIENT_DUMMY_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 31, 31, 8, 8, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + + /* IPA_4_0_AUTO_MHI */ + [IPA_4_0_AUTO_MHI][IPA_CLIENT_APPS_WAN_PROD] = { + true, IPA_v4_0_MHI_GROUP_DDR, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 2, 4, 16, 32, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_APPS_CMD_PROD] = { + true, IPA_v4_0_MHI_GROUP_DDR, + false, + IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY, + QMB_MASTER_SELECT_DDR, + { 5, 7, 20, 24, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_MHI_PROD] = { + true, IPA_v4_0_MHI_GROUP_PCIE, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_PCIE, + { 0, 0, 8, 16, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_MHI2_PROD] = { + true, IPA_v4_0_GROUP_CV2X, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_PCIE, + { 6, 5, 8, 16, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_ETHERNET_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, + QMB_MASTER_SELECT_DDR, + { 9, 0, 8, 16, IPA_EE_UC, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_WAN_PROD] = { + false, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_PKT_PROCESS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 3, 0, 16, 32, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_CMD_PROD] = { + false, IPA_v4_0_MHI_GROUP_PCIE, + false, + IPA_DPS_HPS_SEQ_TYPE_PKT_PROCESS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 4, 1, 20, 24, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_MEMCPY_DMA_SYNC_PROD] = { + true, IPA_v4_0_MHI_GROUP_DMA, + false, + IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY, + QMB_MASTER_SELECT_DDR, + { 7, 3, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_MEMCPY_DMA_ASYNC_PROD] = { + true, IPA_v4_0_MHI_GROUP_DMA, + false, + IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY, + QMB_MASTER_SELECT_DDR, + { 8, 11, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + /* Only for test purpose */ + [IPA_4_0_AUTO_MHI][IPA_CLIENT_TEST_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + {0, 8, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_TEST1_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + {0, 8, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_TEST2_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 1, 0, 8, 16, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_TEST3_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + {7, 9, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_TEST4_PROD] = { + true, IPA_v4_0_GROUP_UL_DL, + true, + IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, + QMB_MASTER_SELECT_DDR, + { 8, 10, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + + + [IPA_4_0_AUTO_MHI][IPA_CLIENT_APPS_LAN_CONS] = { + true, IPA_v4_0_MHI_GROUP_DDR, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 10, 8, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_APPS_WAN_CONS] = { + true, IPA_v4_0_MHI_GROUP_DDR, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 11, 9, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_MHI_CONS] = { + true, IPA_v4_0_MHI_GROUP_PCIE, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_PCIE, + { 17, 1, 17, 17, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_MHI2_CONS] = { + true, IPA_v4_0_GROUP_CV2X, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_PCIE, + { 19, 6, 9, 9, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_ETHERNET_CONS] = { + true, IPA_v4_0_ETHERNET, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 22, 1, 9, 9, IPA_EE_UC, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_LAN_CONS] = { + false, IPA_v4_0_MHI_GROUP_DDR, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 14, 4, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_WAN_CONS] = { + false, IPA_v4_0_MHI_GROUP_DDR, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 13, 3, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_MEMCPY_DMA_SYNC_CONS] = { + true, IPA_v4_0_MHI_GROUP_DMA, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_PCIE, + { 20, 12, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_MEMCPY_DMA_ASYNC_CONS] = { + true, IPA_v4_0_MHI_GROUP_DMA, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_PCIE, + { 21, 13, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS] = { + false, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 16, 5, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_USB_DPL_CONS] = { + false, IPA_v4_0_MHI_GROUP_DDR, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 15, 10, 5, 5, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_MHI_DPL_CONS] = { + true, IPA_v4_0_MHI_GROUP_PCIE, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_PCIE, + { 12, 2, 5, 5, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + /* Only for test purpose */ + [IPA_4_0_AUTO_MHI][IPA_CLIENT_TEST_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_PCIE, + { 11, 6, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_TEST1_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_PCIE, + { 11, 6, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_TEST2_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 12, 2, 5, 5, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_TEST3_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_PCIE, + { 19, 12, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_TEST4_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_PCIE, + { 21, 14, 9, 9, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + /* Dummy consumer (pipe 31) is used in L2TP rt rule */ + [IPA_4_0_AUTO_MHI][IPA_CLIENT_DUMMY_CONS] = { + true, IPA_v4_0_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 31, 31, 8, 8, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, }; /** @@ -2131,6 +2603,14 @@ u8 ipa3_get_hw_type_index(void) */ if (ipa3_ctx->ipa_config_is_mhi) hw_type_index = IPA_4_0_MHI; + + if (ipa3_ctx->ipa_config_is_auto) + hw_type_index = IPA_4_0_AUTO; + + if (ipa3_ctx->ipa_config_is_auto && + ipa3_ctx->ipa_config_is_mhi) + hw_type_index = IPA_4_0_AUTO_MHI; + break; default: IPAERR("Incorrect IPA version %d\n", ipa3_ctx->ipa_hw_type); @@ -4777,6 +5257,8 @@ static void ipa3_write_rsrc_grp_type_reg(int group_index, break; case IPA_4_0: case IPA_4_0_MHI: + case IPA_4_0_AUTO: + case IPA_4_0_AUTO_MHI: if (src) { switch (group_index) { case IPA_v4_0_GROUP_LWA_DL: @@ -4926,6 +5408,13 @@ void ipa3_set_resorce_groups_min_max_limits(void) src_grp_idx_max = IPA_v4_0_SRC_GROUP_MAX; dst_grp_idx_max = IPA_v4_0_DST_GROUP_MAX; break; + case IPA_4_0_AUTO: + case IPA_4_0_AUTO_MHI: + src_rsrc_type_max = IPA_v4_0_RSRC_GRP_TYPE_SRC_MAX; + dst_rsrc_type_max = IPA_v4_0_RSRC_GRP_TYPE_DST_MAX; + src_grp_idx_max = IPA_v4_0_GROUP_CV2X; + dst_grp_idx_max = IPA_v4_0_GROUP_CV2X; + break; default: IPAERR("invalid hw type index\n"); WARN_ON(1); diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h index 96523b55d06c..e64942af11d4 100644 --- a/include/uapi/linux/msm_ipa.h +++ b/include/uapi/linux/msm_ipa.h @@ -151,6 +151,11 @@ */ #define QMI_IPA_MAX_CLIENT_DST_PIPES 4 +/** + * New feature flag for CV2X config + */ +#define IPA_CV2X_SUPPORT + /** * the attributes of the rule (routing or filtering) */ @@ -326,11 +331,14 @@ enum ipa_client_type { /* RESERVERD PROD = 84, */ IPA_CLIENT_WIGIG4_CONS = 85, + + IPA_CLIENT_MHI2_PROD = 86, + IPA_CLIENT_MHI2_CONS = 87, }; #define IPA_CLIENT_DUMMY_CONS IPA_CLIENT_DUMMY_CONS1 #define IPA_CLIENT_WIGIG4_CONS IPA_CLIENT_WIGIG4_CONS -#define IPA_CLIENT_MAX (IPA_CLIENT_WIGIG4_CONS + 1) +#define IPA_CLIENT_MAX (IPA_CLIENT_MHI2_CONS + 1) #define IPA_CLIENT_IS_APPS_CONS(client) \ ((client) == IPA_CLIENT_APPS_LAN_CONS || \ From d206afbc7ffed1ad95e363bfbe6939a7be53cd8b Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Mon, 22 Jul 2019 11:03:57 -0700 Subject: [PATCH 139/281] ARM: dts: msm: Enable dual-CAN for SA415M CCARD Enable 2 CAN interfaces for SA415M CCARD boards using the qti-can driver. Change-Id: I0a07722b7692995f1359a70f5030bab156bc0b26 Signed-off-by: Gustavo Solaira --- arch/arm/boot/dts/qcom/sa415m-ccard.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi index aa708e6d43d1..d2e597da08bf 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi +++ b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi @@ -54,6 +54,12 @@ }; }; +&spi_2 { + can-controller@0 { + qcom,max-can-channels = <2>; + }; +}; + &wcd934x_cdc { status = "disabled"; }; From 72d01d15e6543528077b1598ac78a75c8de412d5 Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Fri, 19 Jul 2019 19:25:09 +0800 Subject: [PATCH 140/281] sched/fair: Only strict skip for current task Fix the issue that when a task called yield, it is not going to schedule again if there is always have task running in that cpu. Change-Id: I7ec037ac5ea9be159ccb9e9db676d1b8d677746d Signed-off-by: Maria Yu --- kernel/sched/fair.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6f7d15aac082..87e674b85fbd 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3914,6 +3914,7 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr) { struct sched_entity *left = __pick_first_entity(cfs_rq); struct sched_entity *se; + bool strict_skip = false; /* * If curr is set we have to see if its left of the leftmost entity @@ -3933,13 +3934,15 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr) if (se == curr) { second = __pick_first_entity(cfs_rq); + if (sched_feat(STRICT_SKIP_BUDDY)) + strict_skip = true; } else { second = __pick_next_entity(se); if (!second || (curr && entity_before(curr, second))) second = curr; } - if (second && (sched_feat(STRICT_SKIP_BUDDY) || + if (second && (strict_skip || wakeup_preempt_entity(second, left) < 1)) se = second; } From ab794fee32d642697be434624dade970ad53cf29 Mon Sep 17 00:00:00 2001 From: Sriharsha Allenki Date: Mon, 22 Jul 2019 14:51:13 +0530 Subject: [PATCH 141/281] usb: dwc3: Disable device events after maximum error retries Currently if the core could not recover even after maximum number of error retries there can storm of error interrupts generated since the interrupts are not handled because of dwc->err_evt_seen being set on first error event seen. Hence after maximum error retries disable the device events and keep the core in softreset state. Also, reset the err_evt_seen on run/stop clear to ensure that the interrupts on the next connect/session are processed properly. Change-Id: I760e163733bdcc6230d926fa548aa93a5da918a5 Signed-off-by: Sriharsha Allenki --- drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/dwc3-msm.c | 9 +++++++-- drivers/usb/dwc3/gadget.c | 15 ++++++++------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 89d7ee0f459e..e9083d63b443 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -44,6 +44,7 @@ #define DWC3_EP0_BOUNCE_SIZE 512 #define DWC3_ENDPOINTS_NUM 32 #define DWC3_XHCI_RESOURCES_NUM 2 +#define MAX_ERROR_RECOVERY_TRIES 3 #define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */ #define DWC3_EVENT_BUFFERS_SIZE 4096 diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index af704b7228d5..3a47c37d2c26 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1950,8 +1950,13 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, reg |= DWC3_GCTL_CORESOFTRESET; dwc3_msm_write_reg(mdwc->base, DWC3_GCTL, reg); - /* restart USB which performs full reset and reconnect */ - schedule_work(&mdwc->restart_usb_work); + /* + * If the core could not recover after MAX_ERROR_RECOVERY_TRIES, + * skip the restart USB work and keep the core in softreset + * state. + */ + if (dwc->retries_on_error < MAX_ERROR_RECOVERY_TRIES) + schedule_work(&mdwc->restart_usb_work); break; case DWC3_CONTROLLER_RESET_EVENT: dev_dbg(mdwc->dev, "DWC3_CONTROLLER_RESET_EVENT received\n"); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index e8d270dceed0..67b94369dc0b 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -37,8 +37,6 @@ #include "gadget.h" #include "io.h" -#define MAX_ERROR_RECOVERY_TRIES 3 - static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc, bool remote_wakeup); static int dwc3_gadget_wakeup_int(struct dwc3 *dwc); static void dwc3_stop_active_transfers(struct dwc3 *dwc); @@ -1954,6 +1952,11 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) reg1 |= DWC3_GEVNTSIZ_INTMASK; dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg1); + /* + * Reset the err_evt_seen so that the interrupts on + * next connect/session is processed correctly. + */ + dwc->err_evt_seen = false; dwc->pullups_connected = false; __dwc3_gadget_ep_disable(dwc->eps[0]); @@ -3638,12 +3641,10 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc) evt->lpos = (evt->lpos + left) % DWC3_EVENT_BUFFERS_SIZE; dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), left); - if (dwc->retries_on_error < MAX_ERROR_RECOVERY_TRIES) { - if (dwc3_notify_event(dwc, + if (dwc3_notify_event(dwc, DWC3_CONTROLLER_ERROR_EVENT, 0)) - dwc->err_evt_seen = 0; - dwc->retries_on_error++; - } + dwc->err_evt_seen = 0; + dwc->retries_on_error++; break; } From 86e6b90f0a0c51d5213350716e841fb8b36acd83 Mon Sep 17 00:00:00 2001 From: xiaolin Date: Mon, 22 Jul 2019 16:05:20 +0800 Subject: [PATCH 142/281] ARM: dts: msm: Change the max voltage of S5 We need the 1.4v of s5 at least for camera, which can conform to the power grid. And the max voltage of S5 is 1.35v now. Change-Id: I9a4ed75e47298814ec89b5e4b19c884db053177e Signed-off-by: xiaolin --- arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi index 0a06e2da6a7c..b4dd41eaef08 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi @@ -111,7 +111,7 @@ status = "okay"; S5A: pm660_s5: regulator-s5 { regulator-min-microvolt = <1040000>; - regulator-max-microvolt = <1350000>; + regulator-max-microvolt = <1420000>; qcom,init-voltage = <1040000>; status = "okay"; }; From a64142eb2066536b5000de93d0aac8502f3a2e5b Mon Sep 17 00:00:00 2001 From: Sanjay Dwivedi Date: Tue, 23 Jul 2019 13:59:33 +0530 Subject: [PATCH 143/281] soc: qcom: pil: Add support to load PIL blobs in parallel Loading of the subsystem firmware blobs into the memory is one of the major bottlenecks during the subsystem's boot operation. Hence, optimizing the path such that the blobs are loaded in parallel and making the operation faster. Fix use-after-free issue when loading firmware images. Currently, the function pil_load_segs() allocates memory, creates kthreads, and calls wait_for_completion_interruptible() to synchronize the threads. However, if the completion received a terminate signal, the allocated memory that is being used by the threads (under execution) is freed. When the thread(s) tries to access this memory, it leads to a use-after-free issue. As a solution, replace the kthreads and completions with work items as this provides an implicit synchronization. After spawning the work items, we simply now call flush_work() which waits until the thread's execution is finished, thus avoiding the use-after-free issue. The PIL code creates it own high priority & unbounded workqueue to schedule the work items. Change-Id: I6a28f46a53c05e16e5f29ad975879e336a16f0cd Signed-off-by: Sanjay Dwivedi --- .../devicetree/bindings/pil/subsys-pil-tz.txt | 6 + drivers/soc/qcom/peripheral-loader.c | 115 +++++++++++++++++- drivers/soc/qcom/peripheral-loader.h | 5 +- 3 files changed, 121 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/pil/subsys-pil-tz.txt b/Documentation/devicetree/bindings/pil/subsys-pil-tz.txt index f8329a95b3e8..31c5660ab590 100644 --- a/Documentation/devicetree/bindings/pil/subsys-pil-tz.txt +++ b/Documentation/devicetree/bindings/pil/subsys-pil-tz.txt @@ -70,6 +70,12 @@ Optional properties: - qcom,ignore-ssr-failure: Boolean. If set, SSR failures are not considered fatal. - qcom,mas-crypto: Reference to the bus master of crypto core. +- qcom,sequential-fw-load: Boolean. If set, PIL loads the firmware image blobs in a + serial fashion. Else, they are loaded in + parallel. The property is specially useful for + low-end (single core) systems to prevent it from + degrading the performance. + Example: qcom,venus@fdce0000 { compatible = "qcom,pil-tz-generic"; diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c index 384ac58ae96a..1d5284e82b5b 100644 --- a/drivers/soc/qcom/peripheral-loader.c +++ b/drivers/soc/qcom/peripheral-loader.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2019, 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 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -70,6 +71,9 @@ static int proxy_timeout_ms = -1; module_param(proxy_timeout_ms, int, 0644); static bool disable_timeouts; + +static struct workqueue_struct *pil_wq; + /** * struct pil_mdt - Representation of .mdt file in memory * @hdr: ELF32 header @@ -127,6 +131,7 @@ struct pil_priv { struct wakeup_source ws; char wname[32]; struct pil_desc *desc; + int num_segs; struct list_head segs; phys_addr_t entry_addr; phys_addr_t base_addr; @@ -723,6 +728,7 @@ static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt, pil_info(desc, "loading from %pa to %pa\n", &priv->region_start, &priv->region_end); + priv->num_segs = 0; for (i = 0; i < mdt->hdr.e_phnum; i++) { phdr = &mdt->phdr[i]; if (!segment_is_loadable(phdr)) @@ -733,6 +739,7 @@ static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt, return PTR_ERR(seg); list_add_tail(&seg->list, &priv->segs); + priv->num_segs++; } list_sort(NULL, &priv->segs, pil_cmp_seg); @@ -922,6 +929,9 @@ static int pil_parse_devicetree(struct pil_desc *desc) } } desc->proxy_unvote_irq = clk_ready; + + desc->sequential_load = of_property_read_bool(ofnode, + "qcom,sequential-fw-load"); return 0; } @@ -945,6 +955,89 @@ static int pil_notify_aop(struct pil_desc *desc, char *status) /* Synchronize request_firmware() with suspend */ static DECLARE_RWSEM(pil_pm_rwsem); +struct pil_seg_data { + struct pil_desc *desc; + struct pil_seg *seg; + struct work_struct load_seg_work; + int retval; +}; + +static void pil_load_seg_work_fn(struct work_struct *work) +{ + struct pil_seg_data *pil_seg_data = container_of(work, + struct pil_seg_data, + load_seg_work); + struct pil_desc *desc = pil_seg_data->desc; + struct pil_seg *seg = pil_seg_data->seg; + + pil_seg_data->retval = pil_load_seg(desc, seg); +} + +static int pil_load_segs(struct pil_desc *desc) +{ + int ret = 0; + int seg_id = 0; + struct pil_priv *priv = desc->priv; + struct pil_seg_data *pil_seg_data; + struct pil_seg *seg; + unsigned long *err_map; + + err_map = kcalloc(BITS_TO_LONGS(priv->num_segs), sizeof(unsigned long), + GFP_KERNEL); + if (!err_map) + return -ENOMEM; + + pil_seg_data = kcalloc(priv->num_segs, sizeof(*pil_seg_data), + GFP_KERNEL); + if (!pil_seg_data) { + ret = -ENOMEM; + goto out; + } + + /* Initialize and spawn a thread for each segment */ + list_for_each_entry(seg, &desc->priv->segs, list) { + pil_seg_data[seg_id].desc = desc; + pil_seg_data[seg_id].seg = seg; + + INIT_WORK(&pil_seg_data[seg_id].load_seg_work, + pil_load_seg_work_fn); + queue_work(pil_wq, &pil_seg_data[seg_id].load_seg_work); + + seg_id++; + } + + bitmap_zero(err_map, priv->num_segs); + + /* Wait for the parallel loads to finish */ + seg_id = 0; + list_for_each_entry(seg, &desc->priv->segs, list) { + flush_work(&pil_seg_data[seg_id].load_seg_work); + + /* + * Don't exit if one of the thread fails. Wait for others to + * complete. Bitmap the return codes we get from the threads. + */ + if (pil_seg_data[seg_id].retval) { + pil_err(desc, + "Failed to load the segment[%d]. ret = %d\n", + seg_id, pil_seg_data[seg_id].retval); + __set_bit(seg_id, err_map); + } + + seg_id++; + } + + kfree(pil_seg_data); + + /* Each segment can fail due to different reason. Send a generic err */ + if (!bitmap_empty(err_map, priv->num_segs)) + ret = -EFAULT; + +out: + kfree(err_map); + return ret; +} + /** * pil_boot() - Load a peripheral image into memory and boot it * @desc: descriptor from pil_desc_init() @@ -955,9 +1048,9 @@ int pil_boot(struct pil_desc *desc) { int ret; char fw_name[30]; + struct pil_seg *seg; const struct pil_mdt *mdt; const struct elf32_hdr *ehdr; - struct pil_seg *seg; const struct firmware *fw; struct pil_priv *priv = desc->priv; bool mem_protect = false; @@ -1066,8 +1159,15 @@ int pil_boot(struct pil_desc *desc) } trace_pil_event("before_load_seg", desc); - list_for_each_entry(seg, &desc->priv->segs, list) { - ret = pil_load_seg(desc, seg); + + if (desc->sequential_load) { + list_for_each_entry(seg, &desc->priv->segs, list) { + ret = pil_load_seg(desc, seg); + if (ret) + goto err_deinit_image; + } + } else { + ret = pil_load_segs(desc); if (ret) goto err_deinit_image; } @@ -1364,6 +1464,11 @@ static int __init msm_pil_init(void) pr_err("SMEM is not initialized.\n"); return -EPROBE_DEFER; } + + pil_wq = alloc_workqueue("pil_workqueue", WQ_HIGHPRI | WQ_UNBOUND, 0); + if (!pil_wq) + pr_warn("pil: Defaulting to sequential firmware loading.\n"); + out: return register_pm_notifier(&pil_pm_notifier); } @@ -1371,6 +1476,8 @@ device_initcall(msm_pil_init); static void __exit msm_pil_exit(void) { + if (pil_wq) + destroy_workqueue(pil_wq); unregister_pm_notifier(&pil_pm_notifier); if (pil_info_base) iounmap(pil_info_base); diff --git a/drivers/soc/qcom/peripheral-loader.h b/drivers/soc/qcom/peripheral-loader.h index 6ea6b2a7648d..9f3e006e1262 100644 --- a/drivers/soc/qcom/peripheral-loader.h +++ b/drivers/soc/qcom/peripheral-loader.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -41,6 +41,8 @@ struct pil_priv; * @modem_ssr: true if modem is restarting, false if booting for first time. * @clear_fw_region: Clear fw region on failure in loading. * @subsys_vmid: memprot id for the subsystem. + * @sequential_load: Load the firmware blobs sequentially if set. Else, load + * them in parallel. */ struct pil_desc { const char *name; @@ -67,6 +69,7 @@ struct pil_desc { struct md_ss_toc *minidump_ss; struct md_ss_toc *minidump_pdr; int minidump_id; + bool sequential_load; }; /** From e5ce202dde7d5b0a947e56fa2a97af14aadfcc6c Mon Sep 17 00:00:00 2001 From: Sanjay Dwivedi Date: Tue, 23 Jul 2019 14:18:40 +0530 Subject: [PATCH 144/281] ARM: dts: Enable sequential load for pil firmware image on sdm845 target sdm845 target is enabled with sequential load of pil firmware blobs image, parallel pil loading is not supported. Change-Id: I38b09641ade72d8e46e4c4a003fc35019b0136b2 Signed-off-by: Sanjay Dwivedi --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 2d3626575ef2..9bf544d06426 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -1549,6 +1549,7 @@ vdd_mss-supply = <&pm8005_s2_level>; vdd_mss-uV = ; qcom,firmware-name = "modem"; + qcom,sequential-fw-load; qcom,pil-self-auth; qcom,sysmon-id = <0>; qcom,minidump-id = <3>; From 52f7f3cba279bb230d85990f12eea9e998e252e9 Mon Sep 17 00:00:00 2001 From: Chaojun Wang Date: Tue, 23 Jul 2019 17:06:03 +0800 Subject: [PATCH 145/281] driver: net: usb: add support AX88179 for SDM845 RB3 enable AX88179 compile for rb3 platform, which is usb to ethernet convert chip. Change-Id: I6a7f6c804d36bc4768be7779c31229e326ade2b3 Signed-off-by: Chaojun Wang --- drivers/net/usb/ax88179_178a.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 531536abf4a3..cb46d9680c43 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -1660,6 +1660,19 @@ static const struct driver_info ax88178a_info = { .tx_fixup = ax88179_tx_fixup, }; +static const struct driver_info ax88178b_info = { + .description = "ASIX AX88178B USB 2.0 Gigabit Ethernet", + .bind = ax88179_bind, + .unbind = ax88179_unbind, + .status = ax88179_status, + .link_reset = ax88179_link_reset, + .reset = ax88179_reset, + .stop = ax88179_stop, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .rx_fixup = ax88179_rx_fixup, + .tx_fixup = ax88179_tx_fixup, +}; + static const struct driver_info cypress_GX3_info = { .description = "Cypress GX3 SuperSpeed to Gigabit Ethernet Controller", .bind = ax88179_bind, @@ -1734,6 +1747,10 @@ static const struct usb_device_id products[] = { /* ASIX AX88178A 10/100/1000 */ USB_DEVICE(0x0b95, 0x178a), .driver_info = (unsigned long)&ax88178a_info, +}, { + /* ASIX AX88178A 10/100/1000 */ + USB_DEVICE(0x0b95, 0x178b), + .driver_info = (unsigned long)&ax88178b_info, }, { /* Cypress GX3 SuperSpeed to Gigabit Ethernet Bridge Controller */ USB_DEVICE(0x04b4, 0x3610), From 5d9110818c147cafb712ec6eb6f2c57c0855e174 Mon Sep 17 00:00:00 2001 From: Fei Mao Date: Tue, 23 Jul 2019 16:53:26 +0800 Subject: [PATCH 146/281] input: touchscreen: cyttsp5: change timeout value for Gesture Wake Reduce timeout value for Gesture Wake, it will speed up device resume. Change-Id: I55bdd4998f0293257c8ae9f580c6769b362300b6 Signed-off-by: Fei Mao --- drivers/input/touchscreen/cyttsp5/cyttsp5_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c index 6fe8851095c3..64cc51060fb1 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c @@ -4099,7 +4099,7 @@ static int cyttsp5_read_input(struct cyttsp5_core_data *cd) goto read; t = wait_event_timeout(cd->wait_q, (cd->wait_until_wake == 1), - msecs_to_jiffies(2000)); + msecs_to_jiffies(20)); if (IS_TMO(t)) cyttsp5_queue_startup(cd); goto read; From 120630462f44ed18b234998567634c3c74af376d Mon Sep 17 00:00:00 2001 From: zhaochen Date: Mon, 15 Jul 2019 11:22:04 +0800 Subject: [PATCH 147/281] ARM: dts: msm: add device tree for SDM429 spyro EVT and DVT Add device tree for SDM429 spyro EVT and DVT devices. Change-Id: I4ca078fa904f81b269414f2bc74036c7d06c58d3 Signed-off-by: zhaochen --- arch/arm64/boot/dts/qcom/Makefile | 11 +- arch/arm64/boot/dts/qcom/sdm429-spyro-dvt.dts | 24 + .../dts/qcom/sdm429-spyro-qrd-dvt-overlay.dts | 37 ++ .../dts/qcom/sdm429-spyro-qrd-evt-audio.dtsi | 163 +++++++ .../dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi | 418 ++++++++++++++++++ .../dts/qcom/sdm429-spyro-qrd-evt-overlay.dts | 22 + .../boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi | 331 ++++++++++++++ .../qcom/sdm429-spyro-qrd-mdss-panels.dtsi | 85 ++++ arch/arm64/boot/dts/qcom/sdm429-spyro.dts | 23 + arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi | 15 + arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 8 - 11 files changed, 1125 insertions(+), 12 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro-dvt.dts create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-dvt-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-audio.dtsi create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro.dts create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index b0c6499eb20e..641ad02e4780 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -393,7 +393,8 @@ dtbo-$(CONFIG_ARCH_SDM439) += sdm439-mtp-overlay.dtbo \ dtbo-$(CONFIG_ARCH_SDM429) += sdm429-mtp-overlay.dtbo \ sdm429-cdp-overlay.dtbo \ sdm429-qrd-overlay.dtbo \ - sdm429-qrd-spyro-evt-overlay.dtbo + sdm429-spyro-qrd-evt-overlay.dtbo \ + sdm429-spyro-qrd-dvt-overlay.dtbo msm8940-mtp-overlay.dtbo-base := msm8940-pmi8950.dtb \ msm8940-pmi8937.dtb \ @@ -512,8 +513,8 @@ sdm429-cdp-overlay.dtbo-base := sdm429.dtb \ msm8937-interposer-sdm429.dtb sdm429-qrd-overlay.dtbo-base := sdm429.dtb \ msm8937-interposer-sdm429.dtb -sdm429-qrd-spyro-evt-overlay.dtbo-base := sdm429.dtb \ - msm8937-interposer-sdm429.dtb +sdm429-spyro-qrd-evt-overlay.dtbo-base := sdm429-spyro.dtb +sdm429-spyro-qrd-dvt-overlay.dtbo-base := sdm429-spyro-dvt.dtb else dtb-$(CONFIG_ARCH_MSM8953) += msm8953-cdp.dtb \ msm8953-mtp.dtb \ @@ -644,7 +645,9 @@ dtb-$(CONFIG_ARCH_SDM429) += sdm429-mtp.dtb \ sdm429-cdp.dtb \ sdm429-qrd.dtb \ sda429-mtp.dtb \ - sda429-cdp.dtb + sda429-cdp.dtb \ + sdm429-spyro.dtb \ + sdm429-spyro-dvt.dtb endif diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-dvt.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-dvt.dts new file mode 100644 index 000000000000..f9a62f04de68 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-dvt.dts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019, 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 "sdm429-spyro.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDM429 QRD DVT Spyro"; + compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd"; + qcom,msm-id = <416 0x0>; + qcom,board-id = <0x01000b 6>; + qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-dvt-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-dvt-overlay.dts new file mode 100644 index 000000000000..4ddf6d19834e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-dvt-overlay.dts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019, 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/; +/plugin/; + +#include "sdm429-spyro-qrd-evt.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDM429 QRD Spyro DVT Overlay"; + compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd"; + qcom,msm-id = <416 0x0>; + qcom,board-id = <0x01000b 6>; + qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; +}; + +&usb_otg { + HSUSB_3p3-supply = <&L16A>; +}; + +&msm_dig_codec { + cdc-vdd-digital-supply = <&pm660_l11>; +}; + +&ext_smart_pa { + dvdd-supply = <&pm660_l11>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-audio.dtsi new file mode 100644 index 000000000000..0c61f71a92dc --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-audio.dtsi @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2019, 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. + */ + +&int_codec { + compatible = "qcom,msm8952-dig-asoc-snd"; + status = "okay"; + qcom,model = "sdm429-qrd-snd-card"; + qcom,msm-ext-pa = "quaternary"; + /delete-property/ qcom,split-a2dp; + asoc-wsa-codec-names; + asoc-wsa-codec-prefixes; + ext_pa_aw8896; + qcom,audio-routing = + "CDC_CONN", "MCLK", + "QUAT_MI2S_RX", "DIGITAL_REGULATOR", + "TX_I2S_CLK", "DIGITAL_REGULATOR", + "DMIC1", "Digital Mic1", + "DMIC2", "Digital Mic2"; + qcom,cdc-dmic-gpios = <&cdc_dmic_gpios>; + qcom,quat-mi2s-gpios = <&cdc_quat_mi2s_gpios>; + qcom,msm-gpios = + "quat_i2s", + "dmic"; + qcom,pinctrl-names = + "all_off", + "quat_i2s_act", + "dmic_act", + "quat_i2s_dmic_act"; + pinctrl-names = + "all_off", + "quat_i2s_act", + "dmic_act", + "quat_i2s_dmic_act"; + pinctrl-0 = <&quat_mi2s_sleep &quat_mi2s_din_sleep + &cdc_dmic0_clk_sus &cdc_dmic0_data_sus>; + pinctrl-1 = <&quat_mi2s_active &quat_mi2s_din_active + &cdc_dmic0_clk_sus &cdc_dmic0_data_sus>; + pinctrl-2 = <&quat_mi2s_sleep &quat_mi2s_din_sleep + &cdc_dmic0_clk_act &cdc_dmic0_data_act>; + pinctrl-3 = <&quat_mi2s_active &quat_mi2s_din_active + &cdc_dmic0_clk_act &cdc_dmic0_data_act>; + /delete-property/qcom,cdc-us-euro-gpios; + /delete-property/qcom,pri-mi2s-gpios; + /delete-property/qcom,cdc-us-eu-gpios; + + asoc-codec = <&stub_codec>, <&msm_dig_codec>, <&ext_smart_pa>; + asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec", "ext-smart-pa"; +}; + +&soc { + msm_dig_codec: msm_dig_codec { + compatible = "qcom,msm-digital-codec"; + reg = <0xc0f0000 0x0>; + qcom,no-analog-codec; + cdc-vdd-digital-supply = <&pm660_l9>; + qcom,cdc-vdd-digital-voltage = <1800000 1800000>; + qcom,cdc-vdd-digital-current = <10000>; + qcom,cdc-on-demand-supplies = "cdc-vdd-digital"; + }; + + cdc_dmic_gpios: cdc_dmic_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&cdc_dmic0_clk_act &cdc_dmic0_data_act>; + pinctrl-1 = <&cdc_dmic0_clk_sus &cdc_dmic0_data_sus>; + }; + + cdc_quat_mi2s_gpios: msm_cdc_pinctrl_quat { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&quat_mi2s_active &quat_mi2s_din_active>; + pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_din_sleep>; + }; +}; + +&tlmm { + smart_pa_int { + pa_int_default: pa_int_default { + mux { + pins = "gpio73", "gpio73"; + function = "gpio"; + }; + + config { + pins = "gpio73", "gpio73"; + drive-strength = <4>; + bias-disable; + }; + }; + }; + + smart_pa_rst { + pa_rst_default: pa_rst_default { + mux { + pins = "gpio68", "gpio68"; + function = "gpio"; + }; + + config { + pins = "gpio68", "gpio68"; + drive-strength = <4>; + bias-disable; + }; + }; + }; +}; + +&wsa881x_i2c_f { + status = "disabled"; +}; + +&wsa881x_i2c_45 { + status = "disabled"; +}; + +&wsa881x_analog_vi_gpio { + status = "disabled"; +}; + +&wsa881x_analog_clk_gpio { + status = "disabled"; +}; + +&wsa881x_analog_reset_gpio { + status = "disabled"; +}; + +&cdc_us_euro_sw { + status = "disabled"; +}; + +&cdc_pri_mi2s_gpios { + status = "disabled"; +}; + +&cdc_quin_mi2s_gpios { + status = "disabled"; +}; + +&i2c_2 { + ext_smart_pa: aw8896_smartpa@34 { + status = "okay"; + compatible = "awinic,aw8896_smartpa"; + reg = <0x34>; + reset-gpio = <&tlmm 68 0>; + irq-gpio = <&tlmm 73 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pa_int_default &pa_rst_default>; + dvdd-supply = <&pm660_l9>; + dvdd-voltage = <1800000 1800000>; + dvdd-current = <15000>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi new file mode 100644 index 000000000000..29d253eacccc --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2019 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 + +&cam_sensor_rear_standby { + /* STANDBY */ + mux { + /delete-property/ pins; + pins = "gpio92"; + function = "gpio"; + }; + + config { + /delete-property/ pins; + pins = "gpio92"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_rear_standby_sleep { + /* STANDBY */ + mux { + /delete-property/ pins; + pins = "gpio92"; + function = "gpio"; + }; + + config { + /delete-property/ pins; + pins = "gpio92"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_rear_vana { + /* VANA */ + mux { + /delete-property/ pins; + pins = "gpio58"; + function = "gpio"; + }; + + config { + /delete-property/ pins; + pins = "gpio58"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&cam_sensor_rear_vana_sleep { + /* VANA */ + mux { + /delete-property/ pins; + pins = "gpio58"; + function = "gpio"; + }; + + config { + /delete-property/ pins; + pins = "gpio58"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; +}; + +&soc { + /delete-node/ qcom,cci@1b0c000; + cci: qcom,cci@1b0c000 { + status = "ok"; + cell-index = <0>; + compatible = "qcom,cci"; + reg = <0x1b0c000 0x4000>; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "cci"; + interrupts = <0 50 0>; + interrupt-names = "cci"; + clocks = <&clock_gcc clk_gcc_camss_ispif_ahb_clk>, + <&clock_gcc clk_cci_clk_src>, + <&clock_gcc clk_gcc_camss_cci_ahb_clk>, + <&clock_gcc clk_gcc_camss_cci_clk>, + <&clock_gcc clk_gcc_camss_ahb_clk>, + <&clock_gcc clk_gcc_camss_top_ahb_clk>; + clock-names = "ispif_ahb_clk", "cci_src_clk", + "cci_ahb_clk", "camss_cci_clk", + "camss_ahb_clk", "camss_top_ahb_clk"; + qcom,clock-rates = <61540000 19200000 0 0 0 0>, + <61540000 37500000 0 0 0 0>; + pinctrl-names = "cci_default", "cci_suspend"; + pinctrl-0 = <&cci0_active &cci1_active>; + pinctrl-1 = <&cci0_suspend &cci1_suspend>; + gpios = <&tlmm 29 0>, + <&tlmm 30 0>, + <&tlmm 31 0>, + <&tlmm 32 0>; + qcom,gpio-tbl-num = <0 1 2 3>; + qcom,gpio-tbl-flags = <1 1 1 1>; + qcom,gpio-tbl-label = "CCI_I2C_DATA0", + "CCI_I2C_CLK0", + "CCI_I2C_DATA1", + "CCI_I2C_CLK1"; + i2c_freq_100Khz: qcom,i2c_standard_mode { + status = "disabled"; + }; + i2c_freq_400Khz: qcom,i2c_fast_mode { + status = "disabled"; + }; + i2c_freq_custom: qcom,i2c_custom_mode { + status = "disabled"; + }; + + i2c_freq_1Mhz: qcom,i2c_fast_plus_mode { + status = "disabled"; + }; + }; +}; + +&cci { + #address-cells = <1>; + #size-cells = <0>; + + actuator_spyro0: qcom,actuator@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&pm660_l19>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2850000>; + qcom,cam-vreg-max-voltage = <3200000>; + qcom,cam-vreg-op-mode = <80000>; + }; + + actuator_spyro1: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&pm660_l19>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2850000>; + qcom,cam-vreg-max-voltage = <3200000>; + qcom,cam-vreg-op-mode = <80000>; + }; + + eeprom_spyro0: qcom,eeprom@0 { + cell-index = <0>; + compatible = "qcom,eeprom"; + qcom,cci-master = <0>; + reg = <0x0>; + cam_vana-supply = <&pm660_l6>; + cam_vio-supply = <&pm660_l14>; + cam_vaf-supply = <&pm660_l19>; + cam_vdig-supply = <&pm660_l2>; + qcom,cam-vreg-name = "cam_vana", "cam_vio", + "cam_vdig", "cam_vaf"; + qcom,cam-vreg-min-voltage = <2800000 1800000 1050000 2850000>; + qcom,cam-vreg-max-voltage = <2800000 1800000 1050000 3200000>; + qcom,cam-vreg-op-mode = <80000 0 200000 100000>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_reset + &cam_sensor_rear_vana + &cam_sensor_rear_standby>; + pinctrl-1 = <&cam_sensor_mclk0_sleep + &cam_sensor_rear_reset_sleep + &cam_sensor_rear_vana_sleep + &cam_sensor_rear_standby_sleep>; + gpios = <&tlmm 26 0>, + <&tlmm 36 0>, + <&tlmm 58 0>, + <&tlmm 92 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vana = <2>; + qcom,gpio-standby = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VANA", + "CAM_STANDBY"; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + eeprom_spyro1: qcom,eeprom@1 { + cell-index = <1>; + reg = <0x1>; + qcom,eeprom-name = "sunny_8865"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0x6c>; + qcom,cci-master = <0>; + qcom,num-blocks = <8>; + + qcom,page0 = <1 0x0100 2 0x01 1 1>; + qcom,poll0 = <0 0x0 2 0x0 1 0>; + qcom,mem0 = <0 0x0 2 0x0 1 0>; + + qcom,page1 = <1 0x5002 2 0x00 1 0>; + qcom,poll1 = <0 0x0 2 0x0 1 0>; + qcom,mem1 = <0 0x0 2 0x0 1 0>; + + qcom,page2 = <1 0x3d84 2 0xc0 1 0>; + qcom,poll2 = <0 0x0 2 0x0 1 0>; + qcom,mem2 = <0 0x0 2 0x0 1 0>; + + qcom,page3 = <1 0x3d88 2 0x70 1 0>; + qcom,poll3 = <0 0x0 2 0x0 1 0>; + qcom,mem3 = <0 0x0 2 0x0 1 0>; + + qcom,page4 = <1 0x3d89 2 0x10 1 0>; + qcom,poll4 = <0 0x0 2 0x0 1 0>; + qcom,mem4 = <0 0x0 2 0x0 1 0>; + + qcom,page5 = <1 0x3d8a 2 0x70 1 0>; + qcom,poll5 = <0 0x0 2 0x0 1 0>; + qcom,mem5 = <0 0x0 2 0x0 1 0>; + + qcom,page6 = <1 0x3d8b 2 0xf4 1 0>; + qcom,poll6 = <0 0x0 2 0x0 1 0>; + qcom,mem6 = <0 0x0 2 0x0 1 0>; + + qcom,page7 = <1 0x3d81 2 0x01 1 10>; + qcom,poll7 = <0 0x0 2 0x0 1 1>; + qcom,mem7 = <1536 0x7010 2 0 1 0>; + + cam_vdig-supply = <&pm660_l3>; + cam_vana-supply = <&pm660_l7>; + cam_vio-supply = <&pm660_l6>; + cam_vaf-supply = <&pm660_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", + "cam_vana", "cam_vaf"; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 3200000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_default + &cam_sensor_front1_default>; + pinctrl-1 = <&cam_sensor_mclk2_sleep + &cam_sensor_front1_sleep>; + gpios = <&tlmm 28 0>, + <&tlmm 40 0>, + <&tlmm 39 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_STANDBY2"; + qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg", + "sensor_vreg", + "sensor_gpio", "sensor_gpio" , "sensor_clk"; + qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio", + "sensor_gpio_reset", "sensor_gpio_standby", + "sensor_cam_mclk"; + qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>; + qcom,cam-power-seq-delay = <1 1 1 30 30 5>; + status = "ok"; + clocks = <&clock_gcc clk_mclk2_clk_src>, + <&clock_gcc clk_gcc_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + qcom,camera@0 { + cell-index = <0>; + compatible = "qcom,camera"; + reg = <0x0>; + qcom,csiphy-sd-index = <0>; + qcom,csid-sd-index = <0>; + qcom,mount-angle = <90>; + qcom,eeprom-src = <&eeprom_spyro0>; + qcom,actuator-src = <&actuator_spyro0>; + cam_vio-supply = <&pm660_l14>; + cam_vaf-supply = <&L19A>; + cam_vdig-supply = <&pm660_l2>; + qcom,cam-vreg-name = "cam_vana", "cam_vio", + "cam_vdig", "cam_vaf"; + qcom,cam-vreg-min-voltage = <2800000 1800000 1050000 2850000>; + qcom,cam-vreg-max-voltage = <2800000 1800000 1050000 3200000>; + qcom,cam-vreg-op-mode = <80000 0 200000 100000>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_reset + &cam_sensor_rear_vana + &cam_sensor_rear_standby>; + pinctrl-1 = <&cam_sensor_mclk0_sleep + &cam_sensor_rear_reset_sleep + &cam_sensor_rear_vana_sleep + &cam_sensor_rear_standby_sleep>; + gpios = <&tlmm 26 0>, + <&tlmm 36 0>, + <&tlmm 58 0>, + <&tlmm 92 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vana = <2>; + qcom,gpio-standby = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VANA", + "CAM_STANDBY"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + + qcom,camera@1 { + cell-index = <1>; + compatible = "qcom,camera"; + reg = <0x1>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <270>; + cam_vdig-supply = <&pm660_l3>; + cam_vio-supply = <&pm660_l14>; + cam_vaf-supply = <&pm660_l19>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_vaf"; + qcom,cam-vreg-min-voltage = <1200000 1800000 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2800000 3200000>; + qcom,cam-vreg-op-mode = <200000 0 80000 100000>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_default + &cam_sensor_front_default>; + pinctrl-1 = <&cam_sensor_mclk1_sleep + &cam_sensor_front_sleep>; + gpios = <&tlmm 27 0>, + <&tlmm 33 0>, + <&tlmm 66 0>, + <&tlmm 38 0>; + qcom,gpio-vana= <1>; + qcom,gpio-vdig= <2>; + qcom,gpio-reset = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_AVDD1", + "CAM_DVDD1", + "CAM_RESET1"; + qcom,sensor-position = <0x1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + clocks = <&clock_gcc clk_mclk1_clk_src>, + <&clock_gcc clk_gcc_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + + qcom,camera@2 { + cell-index = <2>; + compatible = "qcom,camera"; + reg = <0x02>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <270>; + qcom,eeprom-src = <&eeprom_spyro1>; + qcom,actuator-src = <&actuator_spyro1>; + cam_vdig-supply = <&pm660_l3>; + cam_vana-supply = <&pm660_l7>; + cam_vio-supply = <&pm660_l6>; + cam_vaf-supply = <&pm660_l19>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_vaf"; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 3200000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_default + &cam_sensor_front1_default>; + pinctrl-1 = <&cam_sensor_mclk2_sleep + &cam_sensor_front1_sleep>; + gpios = <&tlmm 27 0>, + <&tlmm 38 0>, + <&tlmm 39 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_STANDBY2"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_gcc clk_mclk2_clk_src>, + <&clock_gcc clk_gcc_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-overlay.dts new file mode 100644 index 000000000000..f33fd0e7ff60 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-overlay.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019, 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/; +/plugin/; + +#include "sdm429-spyro-qrd-evt.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDM429 QRD Spyro Overlay"; + qcom,board-id = <0xb 6>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi new file mode 100644 index 000000000000..cc104988b351 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2019, 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 "sdm429-spyro-qrd-mdss-panels.dtsi" +#include "sdm429-spyro-qrd-evt-camera.dtsi" +#include "sdm429-spyro-qrd-evt-audio.dtsi" + +&gpio_key_active { + mux { + pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; + function = "gpio"; + }; + + config { + pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; + drive-strength = <2>; + bias-pull-up; + }; +}; + +&gpio_key_suspend { + mux { + pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; + function = "gpio"; + }; + + config { + pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; + drive-strength = <2>; + bias-pull-up; + }; +}; + +&soc { + gpio_keys: gpio_keys { + compatible = "gpio-keys"; + label = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_key_active>; + pinctrl-1 = <&gpio_key_suspend>; + + vol_up: vol_up { + label = "volume_up"; + gpios = <&tlmm 35 0x1>; + linux,input-type = <1>; + linux,code = <115>; + debounce-interval = <15>; + linux,can-disable; + gpio-key,wakeup; + }; + + function_1: function_1 { + label = "function_1"; + gpios = <&tlmm 127 0x1>; + linux,input-type = <1>; + linux,code = <116>; + debounce-interval = <15>; + linux,can-disable; + gpio-key,wakeup; + }; + + function_2: function_2 { + label = "function_2"; + gpios = <&tlmm 126 0x1>; + linux,input-type = <1>; + linux,code = <117>; + debounce-interval = <15>; + linux,can-disable; + gpio-key,wakeup; + }; + }; +}; + +&blsp1_uart2 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_active>; +}; + +&sdhc_1 { + /* device core power supply */ + vdd-supply = <&L19A>; + qcom,vdd-voltage-level = <2900000 3200000>; + qcom,vdd-current-level = <200 570000>; + + /* device communication power supply */ + vdd-io-supply = <&L13A>; + qcom,vdd-io-always-on; + qcom,vdd-io-lpm-sup; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <0 60000>; + + 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 100000000 192000000 + 384000000>; + qcom,nonremovable; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + + status = "ok"; +}; + +&sdhc_2 { + /* device core power supply for sd card*/ + vdd-supply = <&vreg_sd_vdd>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <15000 800000>; + + /* device communication power supply for msm_io*/ + vdd-io-supply = <&vreg_sd_pad>; + qcom,vdd-io-voltage-level = <1800000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + + cd-gpios = <&tlmm 67 0x0>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 + 200000000>; + + qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104"; + + status = "ok"; +}; + +&firmware { + android { + compatible = "android,firmware"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor,dtbo,recovery"; + }; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev = + "/dev/block/platform/soc/7824900.sdhci/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait,avb"; + status = "ok"; + }; + system { + compatible = "android,system"; + dev = + "/dev/block/platform/soc/7824900.sdhci/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait,avb"; + status = "ok"; + }; + }; + }; +}; + +&modem_mem { + reg = <0x0 0x86800000 0x0 0x5000000>; +}; + +&adsp_fw_mem { + reg = <0x0 0x8b800000 0x0 0x1400000>; +}; + +&wcnss_fw_mem { + reg = <0x0 0x8cc00000 0x0 0x700000>; +}; + +&i2c_4 { + status = "ok"; + + tsc@24 { + compatible = "cy,cyttsp5_i2c_adapter"; + reg = <0x24>; + + interrupt-parent = <&tlmm>; + interrupts = <65 0x2008>; + cy,adapter_id = "cyttsp5_i2c_adapter"; + vcc_i2c-supply = <&L13A>; + vdd-supply = <&L15A>; + pinctrl-names = "pmx_ts_active", "pmx_ts_suspend", + "pmx_ts_release"; + pinctrl-0 = <&ts_int_active &ts_reset_active>; + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; + pinctrl-2 = <&ts_release>; + + cy,core { + cy,name = "cyttsp5_core"; + cy,irq_gpio = <65>; + cy,rst_gpio = <64>; + cy,hid_desc_register = <1>; + cy,flags = <4>; + cy,easy_wakeup_gesture = <1>; + cy,btn_keys = <172 139 158 217 114 115 212 116>; + cy,btn_keys-tag = <0>; + + cy,mt { + cy,name = "cyttsp5_mt"; + + cy,inp_dev_name = "cyttsp5_mt"; + cy,flags = <0x28>; + cy,abs = + <0x35 0 320 0 0 + 0x36 0 360 0 0 + 0x3a 0 255 0 0 + 0xffff 0 255 0 0 + 0x39 0 15 0 0 + 0x30 0 255 0 0 + 0x31 0 255 0 0 + 0x34 0xffffff81 127 0 0 + 0x37 0 1 0 0 + 0x3b 0 255 0 0>; + + cy,vkeys_x = <320>; + cy,vkeys_y = <360>; + + cy,virtual_keys = + <158 1360 90 160 180 + 139 1360 270 160 180 + 172 1360 450 160 180 + 217 1360 630 160 180>; + }; + + cy,btn { + cy,name = "cyttsp5_btn"; + + cy,inp_dev_name = "cyttsp5_btn"; + }; + + cy,proximity { + cy,name = "cyttsp5_proximity"; + + cy,inp_dev_name = "cyttsp5_proximity"; + cy,abs = <0x19 0 1 0 0>; + }; + }; + }; + +}; + +&tlmm { + pmx_ts_int_active { + ts_int_active: ts_int_active { + mux { + pins = "gpio65"; + function = "gpio"; + }; + + config { + pins = "gpio65"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + + pmx_ts_int_suspend { + ts_int_suspend: ts_int_suspend { + mux { + pins = "gpio65"; + function = "gpio"; + }; + + config { + pins = "gpio65"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; + + pmx_ts_reset_active { + ts_reset_active: ts_reset_active { + mux { + pins = "gpio64"; + function = "gpio"; + }; + + config { + pins = "gpio64"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + + pmx_ts_reset_suspend { + ts_reset_suspend: ts_reset_suspend { + mux { + pins = "gpio64"; + function = "gpio"; + }; + + config { + pins = "gpio64"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; + + pmx_ts_release { + ts_release: ts_release { + mux { + pins = "gpio65", "gpio64"; + function = "gpio"; + }; + + config { + pins = "gpio65", "gpio64"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi new file mode 100644 index 000000000000..247d312216a7 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2019, 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-edo-rm67162-qvga-cmd.dtsi" + +&soc { + dsi_pm660_panel_pwr_supply: dsi_pm660_panel_pwr_supply { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <2800000>; + qcom,supply-max-voltage = <2800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,panel-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + }; +}; + +&cdc_pdm_lines_act { + mux { + pins = "gpio68", "gpio73", "gpio74"; + function = "cdc_pdm0"; + }; + + config { + pins = "gpio68", "gpio73", "gpio74"; + drive-strength = <8>; + }; +}; + +&cdc_pdm_lines_sus { + mux { + pins = "gpio68", "gpio73", "gpio74"; + function = "cdc_pdm0"; + }; + + config { + pins = "gpio68", "gpio73", "gpio74"; + drive-strength = <2>; + bias-disable; + }; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_edo_rm67162_qvga_cmd>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-te-gpio = <&tlmm 24 0>; + qcom,platform-reset-gpio = <&tlmm 60 0>; + qcom,platform-enable-gpio = <&tlmm 69 0>; +}; + +&dsi_edo_rm67162_qvga_cmd { + /delete-property/ qcom,mdss-dsi-panel-timings; + qcom,mdss-dsi-panel-timings-phy-12nm = [06 05 01 0A 00 03 01 0F]; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,panel-supply-entries = <&dsi_pm660_panel_pwr_supply>; + qcom,esd-check-enabled; + qcom,mdss-dsi-panel-status-check-mode = "te_signal_check"; + qcom,partial-update-enabled; + qcom,panel-roi-alignment = <2 2 4 2 320 2>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro.dts new file mode 100644 index 000000000000..a869792acd85 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro.dts @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019, 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 "sdm429-spyro.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDM429 QRD Spyro"; + compatible = "qcom,sdm429-qrd", "qcom,sdm429", "qcom,qrd"; + qcom,board-id = <0xb 6>; + qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi new file mode 100644 index 000000000000..80f89d908639 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2019, 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 "sdm429.dtsi" +#include "sdm429w-pm660.dtsi" diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index 450691b42381..caab464ccf5b 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -339,14 +339,6 @@ /delete-node/ qcom,pmi632@3; }; -&dsi_hx8399c_truly_vid { - /delete-property/ qcom,mdss-dsi-pwm-gpio; -}; - -&dsi_hx8399c_hd_vid { - /delete-property/ qcom,mdss-dsi-pwm-gpio; -}; - &tlmm { /delete-node/ smb_int_default; }; From 73c443b96a2146e780e11ada562457443144e09d Mon Sep 17 00:00:00 2001 From: Neng Chen Date: Tue, 23 Jul 2019 18:05:51 +0800 Subject: [PATCH 148/281] ARM: dts: msm: add power S5 supply control for external LDO The front camera use external LDO to control DVDD. So that need to set the power as specification. Change-Id: I29eb837a0ab9de88757cd53c6d56e14194b7c67a Signed-off-by: Neng Chen --- .../boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi index 29d253eacccc..f732a9e858c3 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi @@ -339,12 +339,11 @@ qcom,mount-angle = <270>; cam_vdig-supply = <&pm660_l3>; cam_vio-supply = <&pm660_l14>; - cam_vaf-supply = <&pm660_l19>; - qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", - "cam_vaf"; - qcom,cam-vreg-min-voltage = <1200000 1800000 2800000 2850000>; - qcom,cam-vreg-max-voltage = <1200000 1800000 2800000 3200000>; - qcom,cam-vreg-op-mode = <200000 0 80000 100000>; + cam_vana-supply = <&pm660_s5>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 1420000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 1420000>; + qcom,cam-vreg-op-mode = <200000 80000 80000>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk1_default &cam_sensor_front_default>; From 0dfcc0e090a4ab2bc75c0ba0b5cabbecff0481b3 Mon Sep 17 00:00:00 2001 From: shaoxing Date: Tue, 9 Jul 2019 20:26:20 +0800 Subject: [PATCH 149/281] ARM: dts: msm: Add device tree compile for SDM429W spyro WDP Add device tree compile for SDM429W spyro WDP devices. Change-Id: I63c2a5d00faf9c67bb84aa1ff62d5edcba859454 Signed-off-by: Shaoxing --- arch/arm64/boot/dts/qcom/Makefile | 7 +++- arch/arm64/boot/dts/qcom/sdm429-spyro-dvt.dts | 2 +- .../dts/qcom/sdm429-spyro-qrd-dvt-overlay.dts | 2 +- .../dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts | 37 +++++++++++++++++++ arch/arm64/boot/dts/qcom/sdm429-spyro-wdp.dts | 24 ++++++++++++ 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts create mode 100644 arch/arm64/boot/dts/qcom/sdm429-spyro-wdp.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 641ad02e4780..51578892cda8 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -394,7 +394,8 @@ dtbo-$(CONFIG_ARCH_SDM429) += sdm429-mtp-overlay.dtbo \ sdm429-cdp-overlay.dtbo \ sdm429-qrd-overlay.dtbo \ sdm429-spyro-qrd-evt-overlay.dtbo \ - sdm429-spyro-qrd-dvt-overlay.dtbo + sdm429-spyro-qrd-dvt-overlay.dtbo \ + sdm429-spyro-qrd-wdp-overlay.dtbo msm8940-mtp-overlay.dtbo-base := msm8940-pmi8950.dtb \ msm8940-pmi8937.dtb \ @@ -515,6 +516,7 @@ sdm429-qrd-overlay.dtbo-base := sdm429.dtb \ msm8937-interposer-sdm429.dtb sdm429-spyro-qrd-evt-overlay.dtbo-base := sdm429-spyro.dtb sdm429-spyro-qrd-dvt-overlay.dtbo-base := sdm429-spyro-dvt.dtb +sdm429-spyro-qrd-wdp-overlay.dtbo-base := sdm429-spyro-wdp.dtb else dtb-$(CONFIG_ARCH_MSM8953) += msm8953-cdp.dtb \ msm8953-mtp.dtb \ @@ -647,7 +649,8 @@ dtb-$(CONFIG_ARCH_SDM429) += sdm429-mtp.dtb \ sda429-mtp.dtb \ sda429-cdp.dtb \ sdm429-spyro.dtb \ - sdm429-spyro-dvt.dtb + sdm429-spyro-dvt.dtb \ + sdm429-spyro-wdp.dtb endif diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-dvt.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-dvt.dts index f9a62f04de68..385ae4ffc43c 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-dvt.dts +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-dvt.dts @@ -19,6 +19,6 @@ model = "Qualcomm Technologies, Inc. SDM429 QRD DVT Spyro"; compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd"; qcom,msm-id = <416 0x0>; - qcom,board-id = <0x01000b 6>; + qcom,board-id = <0x00010b 6>; qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; }; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-dvt-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-dvt-overlay.dts index 4ddf6d19834e..98b42eec785d 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-dvt-overlay.dts +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-dvt-overlay.dts @@ -20,7 +20,7 @@ model = "Qualcomm Technologies, Inc. SDM429 QRD Spyro DVT Overlay"; compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd"; qcom,msm-id = <416 0x0>; - qcom,board-id = <0x01000b 6>; + qcom,board-id = <0x00010b 6>; qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; }; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts new file mode 100644 index 000000000000..bb30d8609536 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019, 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/; +/plugin/; + +#include "sdm429-spyro-qrd-evt.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDM429 QRD Spyro WDP Overlay"; + compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd"; + qcom,msm-id = <416 0x0>; + qcom,board-id = <0x01000b 6>; + qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; +}; + +&usb_otg { + HSUSB_3p3-supply = <&L16A>; +}; + +&msm_dig_codec { + cdc-vdd-digital-supply = <&pm660_l11>; +}; + +&ext_smart_pa { + dvdd-supply = <&pm660_l11>; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-wdp.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-wdp.dts new file mode 100644 index 000000000000..dd12d18efa78 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-wdp.dts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019, 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 "sdm429-spyro.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDM429 QRD Spyro WDP"; + compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd"; + qcom,msm-id = <416 0x0>; + qcom,board-id = <0x01000b 6>; + qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; +}; From c1b341d7cc8211d07ea21c3d3b3054762690a9ce Mon Sep 17 00:00:00 2001 From: xiaolin Date: Wed, 17 Jul 2019 10:23:58 +0800 Subject: [PATCH 150/281] ARM: dts: Change active status of detection pin Change active status from high to low of Sd card detection pin for SDM429W spyro WDP. Change-Id: I0324064850522c9234ebe1ed21e9cab81de792f7 Signed-off-by: xiaolin --- arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts index bb30d8609536..f70c45834fed 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts @@ -35,3 +35,7 @@ &ext_smart_pa { dvdd-supply = <&pm660_l11>; }; + +&sdhc_2 { + cd-gpios = <&tlmm 67 0x1>; +}; From ab8ee379f5f3a16383c937e7c8927d373b53d550 Mon Sep 17 00:00:00 2001 From: Ashok Vuyyuru Date: Wed, 24 Jul 2019 12:05:09 +0530 Subject: [PATCH 151/281] msm: ipa3: Fix to recycle the skb before adding to recycle list Because of not recycling the skb causing the skb panic in dma mapping failed scenarios. Add changes to recycle the skb before adding to recycle list. Change-Id: I3e91ed9f921baedd79d7aa42c1162a620b83c1c7 Signed-off-by: Ashok Vuyyuru --- drivers/platform/msm/ipa/ipa_v3/ipa_dp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 62d10bf62025..c9c6281a13cd 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -1936,6 +1936,9 @@ static void ipa3_replenish_rx_cache_recycle(struct ipa3_sys_context *sys) dma_unmap_single(ipa3_ctx->pdev, rx_pkt->data.dma_addr, sys->rx_buff_sz, DMA_FROM_DEVICE); fail_dma_mapping: + /* Recycle skb before adding to recycle list if dma mapping failed */ + rx_pkt->data.dma_addr = 0; + ipa3_skb_recycle(rx_pkt->data.skb); spin_lock_bh(&sys->spinlock); list_add_tail(&rx_pkt->link, &sys->rcycl_list); INIT_LIST_HEAD(&rx_pkt->link); From 625ceffe3ba866d558ddccdb52edf6db1f90bade Mon Sep 17 00:00:00 2001 From: Srinivasarao P Date: Fri, 19 Jul 2019 17:49:43 +0530 Subject: [PATCH 152/281] defconfig: msm: Enable CONFIG_DM_BOW for SDM845 Enable DM-BOW for Android userdata check point feature. Change-Id: I5c87e963b8080155243c6adc8eedca1740d54df3 Signed-off-by: Srinivasarao P --- arch/arm64/configs/sdm845-perf_defconfig | 1 + arch/arm64/configs/sdm845_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index 4529bfb899c0..0180464bdf50 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -273,6 +273,7 @@ CONFIG_DM_REQ_CRYPT=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index c06356427028..f988600a1b89 100755 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -281,6 +281,7 @@ CONFIG_DM_REQ_CRYPT=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y From d59f27c6f6fe12c2431f36fab3e72686887bfe64 Mon Sep 17 00:00:00 2001 From: Sumalatha Malothu Date: Mon, 22 Jul 2019 13:47:49 +0530 Subject: [PATCH 153/281] msm:camera:isp: Fix array index bound checks Added check for max array index Change-Id: I4f8a4b559c83c04577cd58376526668d29b6b723 Signed-off-by: Sumalatha Malothu --- .../media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c index b5a6f44f20fa..c237ad23b753 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, 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 @@ -1215,7 +1215,7 @@ static void msm_isp_update_rdi_output_count( for (i = 0; i < stream_cfg_cmd->num_streams; i++) { if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) - > MAX_NUM_STREAM) + >= MAX_NUM_STREAM) return; stream_info = &axi_data->stream_info[ From 533dd2c86fb4ce2b97e24ced0bc4a75059a19fd8 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Thu, 27 Jun 2019 15:23:18 +0800 Subject: [PATCH 154/281] media: platform: Altek AL6100 driver release This change adds the Altek mini isp driver for sdm845 robotics. Altek mini isp driver is to process the depth data from dual IR camera sensor. This will be used on sdm845 robotics. Change-Id: I5db93dab54595b7b5673a89a6eb6ea88b54ee14d Signed-off-by: Shawn Lin Git-commit: 317fa9d7e52298253e69de1ba290c833848cb953 Git-repo: https://github.com/altek-al6100/845MTP.git [ziyujiang@codeaurora.org: modify Makefile and add Kconfig] [ziyujiang@codeaurora.org: fix critical issues] Signed-off-by: Ziyu Jian --- .../devicetree/bindings/altek/al6100.txt | 65 + arch/arm64/configs/sdm845-perf_defconfig | 1 + arch/arm64/configs/sdm845_defconfig | 1 + drivers/media/platform/Kconfig | 1 + drivers/media/platform/Makefile | 2 + drivers/media/platform/altek/Kconfig | 8 + drivers/media/platform/altek/Makefile | 16 + .../media/platform/altek/basic_setting_cmd.c | 182 ++ drivers/media/platform/altek/bulk_data_cmd.c | 2176 +++++++++++++++ .../media/platform/altek/camera_profile_cmd.c | 716 +++++ drivers/media/platform/altek/include/error.h | 79 + .../altek/include/error/altek_state_err.h | 39 + .../include/error/ispctrl_if_master_err.h | 57 + .../altek/include/error/miniisp_err.h | 38 + .../media/platform/altek/include/error_pj.h | 45 + .../platform/altek/include/isp_camera_cmd.h | 698 +++++ .../altek/include/ispctrl_if_master.h | 194 ++ .../altek/include/ispctrl_if_master_local.h | 668 +++++ .../media/platform/altek/include/miniisp.h | 348 +++ .../altek/include/miniisp_chip_base_define.h | 1035 +++++++ .../platform/altek/include/miniisp_ctrl.h | 441 +++ .../altek/include/miniisp_ctrl_intf.h | 46 + .../altek/include/miniisp_customer_define.h | 114 + .../platform/altek/include/miniisp_debug_if.h | 68 + .../media/platform/altek/include/moduleid.h | 71 + .../platform/altek/include/moduleid_pj.h | 39 + drivers/media/platform/altek/include/mtype.h | 38 + .../media/platform/altek/ispctrl_if_master.c | 1113 ++++++++ .../platform/altek/miniisp_chip_base_define.c | 756 ++++++ drivers/media/platform/altek/miniisp_ctrl.c | 1901 +++++++++++++ .../media/platform/altek/miniisp_ctrl_intf.c | 129 + .../platform/altek/miniisp_customer_define.c | 399 +++ .../media/platform/altek/miniisp_debug_if.c | 647 +++++ .../media/platform/altek/miniisp_intf_i2c.c | 487 ++++ .../media/platform/altek/miniisp_intf_spi.c | 727 +++++ drivers/media/platform/altek/miniisp_isp.c | 2038 ++++++++++++++ drivers/media/platform/altek/miniisp_top.c | 1934 ++++++++++++++ .../media/platform/altek/miniisp_utility.c | 2376 +++++++++++++++++ drivers/media/platform/altek/operation_cmd.c | 214 ++ drivers/media/platform/altek/sys_manage_cmd.c | 281 ++ include/uapi/Kbuild | 1 + include/uapi/miniISP/Kbuild | 3 + include/uapi/miniISP/miniISP_ioctl.h | 164 ++ 43 files changed, 20356 insertions(+) create mode 100644 Documentation/devicetree/bindings/altek/al6100.txt create mode 100644 drivers/media/platform/altek/Kconfig create mode 100755 drivers/media/platform/altek/Makefile create mode 100755 drivers/media/platform/altek/basic_setting_cmd.c create mode 100644 drivers/media/platform/altek/bulk_data_cmd.c create mode 100755 drivers/media/platform/altek/camera_profile_cmd.c create mode 100755 drivers/media/platform/altek/include/error.h create mode 100755 drivers/media/platform/altek/include/error/altek_state_err.h create mode 100755 drivers/media/platform/altek/include/error/ispctrl_if_master_err.h create mode 100755 drivers/media/platform/altek/include/error/miniisp_err.h create mode 100755 drivers/media/platform/altek/include/error_pj.h create mode 100755 drivers/media/platform/altek/include/isp_camera_cmd.h create mode 100755 drivers/media/platform/altek/include/ispctrl_if_master.h create mode 100755 drivers/media/platform/altek/include/ispctrl_if_master_local.h create mode 100755 drivers/media/platform/altek/include/miniisp.h create mode 100755 drivers/media/platform/altek/include/miniisp_chip_base_define.h create mode 100755 drivers/media/platform/altek/include/miniisp_ctrl.h create mode 100755 drivers/media/platform/altek/include/miniisp_ctrl_intf.h create mode 100755 drivers/media/platform/altek/include/miniisp_customer_define.h create mode 100755 drivers/media/platform/altek/include/miniisp_debug_if.h create mode 100755 drivers/media/platform/altek/include/moduleid.h create mode 100755 drivers/media/platform/altek/include/moduleid_pj.h create mode 100755 drivers/media/platform/altek/include/mtype.h create mode 100644 drivers/media/platform/altek/ispctrl_if_master.c create mode 100755 drivers/media/platform/altek/miniisp_chip_base_define.c create mode 100755 drivers/media/platform/altek/miniisp_ctrl.c create mode 100755 drivers/media/platform/altek/miniisp_ctrl_intf.c create mode 100755 drivers/media/platform/altek/miniisp_customer_define.c create mode 100755 drivers/media/platform/altek/miniisp_debug_if.c create mode 100755 drivers/media/platform/altek/miniisp_intf_i2c.c create mode 100755 drivers/media/platform/altek/miniisp_intf_spi.c create mode 100644 drivers/media/platform/altek/miniisp_isp.c create mode 100644 drivers/media/platform/altek/miniisp_top.c create mode 100644 drivers/media/platform/altek/miniisp_utility.c create mode 100755 drivers/media/platform/altek/operation_cmd.c create mode 100755 drivers/media/platform/altek/sys_manage_cmd.c create mode 100644 include/uapi/miniISP/Kbuild create mode 100644 include/uapi/miniISP/miniISP_ioctl.h diff --git a/Documentation/devicetree/bindings/altek/al6100.txt b/Documentation/devicetree/bindings/altek/al6100.txt new file mode 100644 index 000000000000..01f6b295cb0d --- /dev/null +++ b/Documentation/devicetree/bindings/altek/al6100.txt @@ -0,0 +1,65 @@ +Altek al6100 depth chip driver(spi/I2c) + +Description: + +The al6100 is a mini isp chip which is to process +the dual IR raw images from IR camera sensor to be +depth data. It has own firmware. It can connect to +two IR camera sensors via internal mipi port(Rx0/Rx1). +The input of this chip is the IR raw image from +the two IR camera sensors. The Tx0/Tx1 on chip can +connect to AP side and output depth data and IR images +to AP. + +Required properties: + - compatible: Should be "altek,isp"(with spi)/ + "altek,i2c_slave"(with i2c)/"altek,i2c_top"(with i2c) + for al6100 depth chip driver + - irq-gpios: a gpio for spi/I2c interrupt + +Optional properties: + - vcc1-gpios: If present, specifies a gpio for power on + al6100 depth chip + - wp-gpios: If present, specifies a gpio for control + eeprom write protected pin + - reset-gpios: If present, specifies a gpio for reset + al6100 depth chip + +Example: + (spi) + &spi_8 { + mini_isp@0 { + compatible = "altek,isp"; + reg = <0>; + spi-max-frequency = <50000000>; + spi-cpol; + spi-cpha; + vcc-supply = <&pm8953_s3>; + reset-gpios = <&tlmm 33 0x00>; + irq-gpios = <&tlmm 35 0x00>; + vcc1-gpios = <&tlmm 38 0x00>; + wp-gpios = <&tlmm 52 0x00>; + vcc2-gpios = <&tlmm 63 0x00>; + status = "ok"; + }; + }; + + (I2c) + i2c_slave@11 { + compatible = "altek,i2c_slave"; + reg = <0x4b>; /* for Pure Bypass */ + reg = <0x11>; + status = "disabled"; /* use SPI instead */ + }; + + i2c_top@77 { + compatible = "altek,i2c_top"; + reg = <0x77>; + vcc-supply = <&pm8953_s3>; + reset-gpios = <&tlmm 33 0x00>; + irq-gpios = <&tlmm 35 0x00>; + vcc1-gpios = <&tlmm 38 0x00>; + wp-gpios = <&tlmm 52 0x00>; + vcc2-gpios = <&tlmm 63 0x00>; + status = "disabled"; /* use SPI instead */ + }; diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index 4529bfb899c0..4fcc546a2dbd 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -388,6 +388,7 @@ CONFIG_DVB_MPQ=m CONFIG_DVB_MPQ_DEMUX=m CONFIG_DVB_MPQ_TSPP1=y CONFIG_TSPP=m +CONFIG_VIDEO_ALTEK_ISP=y CONFIG_QCOM_KGSL=y CONFIG_DRM=y CONFIG_DRM_SDE_EVTLOG_DEBUG=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index c06356427028..c4293b1e5b86 100755 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -393,6 +393,7 @@ CONFIG_DVB_MPQ=m CONFIG_DVB_MPQ_DEMUX=m CONFIG_DVB_MPQ_TSPP1=y CONFIG_TSPP=m +CONFIG_VIDEO_ALTEK_ISP=y CONFIG_QCOM_KGSL=y CONFIG_DRM=y CONFIG_DRM_SDE_EVTLOG_DEBUG=y diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 493035b8eff4..92ee790dc544 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -379,3 +379,4 @@ source "drivers/media/platform/sti/c8sectpfe/Kconfig" endif #DVB_PLATFORM_DRIVERS source "drivers/media/platform/msm/Kconfig" +source "drivers/media/platform/altek/Kconfig" diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 0929cd1daeab..cb648c01a541 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -67,4 +67,6 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VPU) += mtk-vpu/ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec/ +obj-$(CONFIG_VIDEO_ALTEK_ISP) += altek/ + obj-y += msm/ diff --git a/drivers/media/platform/altek/Kconfig b/drivers/media/platform/altek/Kconfig new file mode 100644 index 000000000000..3c013d08bfc5 --- /dev/null +++ b/drivers/media/platform/altek/Kconfig @@ -0,0 +1,8 @@ +config VIDEO_ALTEK_ISP + tristate "Altek mini isp support" + depends on I2C && SPI + ---help--- + This is a camera driver for Altek mini isp which is to process + depth data from dual IR camera sensors. + Say Y here to enable Altek mini isp support. + diff --git a/drivers/media/platform/altek/Makefile b/drivers/media/platform/altek/Makefile new file mode 100755 index 000000000000..e31405c33b15 --- /dev/null +++ b/drivers/media/platform/altek/Makefile @@ -0,0 +1,16 @@ +# Makefile for Altek mini isp driver + +ccflags-y += -DNEW_ABS + +# add obj to linux kernel +altek_isp-objs := \ + basic_setting_cmd.o bulk_data_cmd.o \ + camera_profile_cmd.o miniisp_intf_i2c.o \ + miniisp_intf_spi.o miniisp_isp.o \ + ispctrl_if_master.o miniisp_customer_define.o \ + miniisp_top.o miniisp_ctrl.o \ + operation_cmd.o sys_manage_cmd.o \ + miniisp_utility.o miniisp_debug_if.o \ + miniisp_chip_base_define.o miniisp_ctrl_intf.o + +obj-$(CONFIG_VIDEO_ALTEK_ISP) += altek_isp.o diff --git a/drivers/media/platform/altek/basic_setting_cmd.c b/drivers/media/platform/altek/basic_setting_cmd.c new file mode 100755 index 000000000000..9c18ec88aad0 --- /dev/null +++ b/drivers/media/platform/altek/basic_setting_cmd.c @@ -0,0 +1,182 @@ +/* + * File: basic_setting_cmd.c + * Description: Mini ISP sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/10/14; Aaron Chuang; Initial version + * 2013/12/05; Bruce Chung; 2nd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +/******Include File******/ +#include "include/isp_camera_cmd.h" +#include "include/ispctrl_if_master.h" +#include "include/error/ispctrl_if_master_err.h" +#include "include/miniisp.h" +#include "include/ispctrl_if_master_local.h" + +/******Private Constant Definition******/ +#define MINI_ISP_LOG_TAG "[[miniisp]Basic_setting_cmd]" + +/******Private Type Declaration******/ + +/******Private Function Prototype******/ + +/******Private Global Variable******/ + +/******Public Global Variable******/ + +/******Public Function******/ + +/* + *\brief Set Depth 3A Info + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_depth_3a_info(void *devdata, + u16 opcode, u8 *param) +{ + /*Error Code */ + errcode err = ERR_SUCCESS; + u32 para_size = sizeof(struct isp_cmd_depth_3a_info); + + /*Send command to slave */ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set Depth auto interleave mode + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode +mast_basic_setting_cmd_set_depth_auto_interleave_mode( + void *devdata, u16 opcode, u8 *param) +{ + /*Error Code */ + errcode err = ERR_SUCCESS; + u32 para_size = sizeof(struct isp_cmd_depth_auto_interleave_param); + struct isp_cmd_depth_auto_interleave_param *depth_auto_interleave_param; + + depth_auto_interleave_param = + (struct isp_cmd_depth_auto_interleave_param *)param; + + misp_info("%s - enter", __func__); + misp_info("[onoff]: %d, [skip_frame]: %d, ", + depth_auto_interleave_param->depth_interleave_mode_on_off, + depth_auto_interleave_param->skip_frame_num_after_illuminator_pulse); + + misp_info("[projector_Lv]: %d, [flood_Lv]: %d", + depth_auto_interleave_param->projector_power_level, + depth_auto_interleave_param->illuminator_power_level); + + /*Send command to slave */ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set projector interleave mode with depth type + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode +mast_basic_setting_cmd_set_interleave_mode_depth_type( + void *devdata, u16 opcode, u8 *param) +{ + /*Error Code */ + errcode err = ERR_SUCCESS; + u32 para_size = sizeof(struct isp_cmd_interleave_mode_depth_type); + + /*Send command to slave */ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set depth polish level + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_depth_polish_level( + void *devdata, u16 opcode, u8 *param) +{ + /*Error Code */ + errcode err = ERR_SUCCESS; + u32 para_size = sizeof(struct isp_cmd_depth_polish_level); + + /*Send command to slave */ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set exposure param + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_exposure_param( + void *devdata, u16 opcode, u8 *param) +{ + /*Error Code */ + errcode err = ERR_SUCCESS; + u32 para_size = sizeof(struct isp_cmd_exposure_param); + + /*Send command to slave */ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set depth stream size + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_depth_stream_size( + void *devdata, u16 opcode, u8 *param) +{ + /*Error Code */ + errcode err = ERR_SUCCESS; + u32 para_size = sizeof(struct isp_cmd_depth_stream_size); + + /*Send command to slave */ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} +/******End Of File******/ diff --git a/drivers/media/platform/altek/bulk_data_cmd.c b/drivers/media/platform/altek/bulk_data_cmd.c new file mode 100644 index 000000000000..d70fca41bbe9 --- /dev/null +++ b/drivers/media/platform/altek/bulk_data_cmd.c @@ -0,0 +1,2176 @@ +/* + * File: bulk_data_cmd.c + * Description: Mini ISP sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/10/14; Bruce Chung; Initial version + * 2013/12/05; Bruce Chung; 2nd version + * 2016/05/05; Louis Wang; Linux Coding Style + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/******Include File******/ +#include +#include +#include +#include +#include "include/isp_camera_cmd.h" +#include "include/ispctrl_if_master.h" +#include "include/error/ispctrl_if_master_err.h" +#include "include/miniisp.h" +#include "include/ispctrl_if_master_local.h" +#include "include/miniisp_customer_define.h" +/******Private Constant Definition******/ +#define LOGSIZE (4*1024) +#define RAWBLOCKSIZE SPI_TX_BULK_SIZE_BOOT +#define MINI_ISP_LOG_TAG "[[miniisp]bulk_data_cmd]" +#define MID_PJ_EXEBIN_BUF (1024*1024) +#define MAX_BUFFER_SIZE (10 * 1024 * 1024) + +/*Private Type Declaration*/ +#if (!ENABLE_LINUX_FW_LOADER) +/*Basic code buffer address*/ +static u8 *basic_code_buf_addr; +#endif +/*Calibration data buffer address*/ +static u8 *calibration_data_buf_addr; + +u16 fw_version_before_point; +u16 fw_version_after_point; +char fw_build_by[9]; +char fw_project_name[17]; +u32 sc_build_date; +/******Private Function Prototype******/ +static u16 +calculate_check_sum(const u8 *input_buffer_addr, u32 input_buffer_size); + +/******Private Global Variable******/ + + +/******Public Global Variable*******/ + +/******Public Function******/ + +#if ENABLE_LINUX_FW_LOADER +const u8 *fw_data; +/** + *\brief Write Boot Code + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], boot code file pointer + *\return Error code + */ +errcode mast_bulk_data_cmd_write_boot_code(void *devdata, + u8 *param) +{ + errcode err = ERR_SUCCESS; + u32 total_size; + u32 curpos; + const struct firmware *fw = NULL; + struct device *mini_isp_device; + u32 ProductId_val = 0; + u16 miniboot_version_before_point = 0; + u16 miniboot_version_after_point = 0; + u8 ProductId[4]; + u8 miniboot_ver_major[2]; + u8 miniboot_ver_minor[2]; + char miniboot_build_by[9]; + char *fw_name = NULL; + + /* load boot fw file */ + mini_isp_device = mini_isp_getdev(); + if (mini_isp_device != NULL) { + fw_name = strrchr((BOOT_FILE_LOCATION ? + BOOT_FILE_LOCATION : ""), '/'); + + /* skip char '/' */ + if (fw_name != NULL) + fw_name = fw_name + 1; + + misp_info("%s, fw name: %s", __func__, fw_name); + err = request_firmware(&fw, + fw_name, mini_isp_device); + if (err) { + misp_info("%s, L: %d, err: %d", + __func__, __LINE__, err); + goto mast_bulk_data_cmd_write_boot_code_end; + } + } + + if (fw == NULL) { + misp_info("%s, fw is NULL.", __func__); + return -EINVAL; + } + + total_size = fw->size; + fw_data = fw->data; + + /*Transfer boot code*/ + /* boot code & main code can only be sent by SPI */ + err = ispctrl_if_mast_send_bulk(devdata, + fw_data, total_size, RAWBLOCKSIZE, true); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_boot_code_end; + + misp_info("%s send boot code success", __func__); + + /* Get miniboot version */ + curpos = total_size - 16; + memcpy(ProductId, &fw_data[curpos], 4); + curpos += 4; + memcpy(miniboot_ver_major, &fw_data[curpos], 2); + curpos += 2; + memcpy(miniboot_ver_minor, &fw_data[curpos], 2); + curpos += 2; + memcpy(miniboot_build_by, &fw_data[curpos], 8); + + if (err == -1) { + misp_info("%s - Read file failed.", __func__); + } else { + err = 0; + ProductId_val = (ProductId[3]<<24) + (ProductId[2]<<16) + + (ProductId[1] << 8) + ProductId[0]; + miniboot_version_before_point = miniboot_ver_major[1]*256 + + miniboot_ver_major[0]; + miniboot_version_after_point = miniboot_ver_minor[1]*256 + + miniboot_ver_minor[0]; + miniboot_build_by[8] = '\0'; + misp_info("%s - miniboot version: %d.%d.%d, build by %s", + __func__, ProductId_val, miniboot_version_before_point, + miniboot_version_after_point, miniboot_build_by); + } + +mast_bulk_data_cmd_write_boot_code_end: + if (fw != NULL) + release_firmware(fw); + + return err; +} + +/** + *\brief Write Boot Code (Short SPI Len) + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], boot code file pointer + *\return Error code + */ +errcode +mast_bulk_data_cmd_write_boot_code_shortlen(void *devdata, + u8 *param) +{ + errcode err = ERR_SUCCESS; + u32 total_size; + u32 block_size; + u32 curpos; + const struct firmware *fw = NULL; + struct device *mini_isp_device; + u32 ProductId_val = 0; + u16 miniboot_version_before_point = 0; + u16 miniboot_version_after_point = 0; + u8 ProductId[4]; + u8 miniboot_ver_major[2]; + u8 miniboot_ver_minor[2]; + char miniboot_build_by[9]; + char *fw_name = NULL; + + /* load boot fw file */ + mini_isp_device = mini_isp_getdev(); + if (mini_isp_device != NULL) { + fw_name = strrchr((BOOT_FILE_LOCATION ? + BOOT_FILE_LOCATION : ""), '/'); + + /* skip char '/' */ + if (fw_name != NULL) + fw_name = fw_name + 1; + + misp_info("%s, fw name: %s", __func__, fw_name); + err = request_firmware(&fw, + fw_name, mini_isp_device); + if (err) { + misp_info("%s, err: %d", __func__, err); + goto mast_bulk_data_cmd_write_boot_code_end; + } + } + + if (fw == NULL) { + misp_info("%s, fw is NULL.", __func__); + return -EINVAL; + } + + block_size = SPI_BLOCK_LEN; + total_size = fw->size; + fw_data = fw->data; + /*misp_info("%s filesize : %d", __func__, total_size);*/ + /*misp_info("block_size %d", RAWBLOCKSIZE);*/ + + /*Transfer boot code*/ + /* boot code & main code can only be sent by SPI */ + err = ispctrl_if_mast_send_bulk(devdata, + fw_data, total_size, block_size, true); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_boot_code_end; + + misp_info("%s send boot code success", __func__); + + /* Get miniboot version */ + curpos = total_size - 16; + memcpy(ProductId, &fw_data[curpos], 4); + curpos += 4; + memcpy(miniboot_ver_major, &fw_data[curpos], 2); + curpos += 2; + memcpy(miniboot_ver_minor, &fw_data[curpos], 2); + curpos += 2; + memcpy(miniboot_build_by, &fw_data[curpos], 8); + + if (err == -1) { + misp_info("%s - Read file failed.", __func__); + } else { + err = 0; + ProductId_val = (ProductId[3]<<24) + (ProductId[2]<<16) + + (ProductId[1] << 8) + ProductId[0]; + miniboot_version_before_point = miniboot_ver_major[1]*256 + + miniboot_ver_major[0]; + miniboot_version_after_point = miniboot_ver_minor[1]*256 + + miniboot_ver_minor[0]; + miniboot_build_by[8] = '\0'; + misp_info("%s - miniboot version: %d.%d.%d, build by %s", + __func__, ProductId_val, miniboot_version_before_point, + miniboot_version_after_point, miniboot_build_by); + } + /* Get miniboot version */ + +mast_bulk_data_cmd_write_boot_code_end: + if (fw != NULL) + release_firmware(fw); + + return err; +} + +/** + *\brief Write Basic Code + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], basic code file pointer + *\return Error code + */ +errcode mast_bulk_data_cmd_write_basic_code(void *devdata, + u8 *param) +{ + errcode err = ERR_SUCCESS; + u8 fw_version[4]; + u32 para_size = ISPCMD_EXEBIN_INFOBYTES; + u32 *total_size = (u32 *)¶m[ISPCMD_EXEBIN_ADDRBYTES]; + u32 file_total_size; + u32 block_size; + u32 currpos; + const struct firmware *fw = NULL; + struct device *mini_isp_device; + char *fw_name = NULL; + + block_size = ((struct misp_data *)devdata)->bulk_cmd_blocksize; + + /* load boot fw file */ + mini_isp_device = mini_isp_getdev(); + if (mini_isp_device != NULL) { + fw_name = strrchr((BASIC_FILE_LOCATION ? + BASIC_FILE_LOCATION : ""), '/'); + + /* skip char '/' */ + if (fw_name != NULL) + fw_name = fw_name + 1; + + misp_info("%s, fw name: %s", __func__, fw_name); + err = request_firmware(&fw, + fw_name, mini_isp_device); + if (err) { + misp_info("%s, L: %d, err: %d", + __func__, __LINE__, err); + goto mast_bulk_data_cmd_write_basic_code_end; + } + } + + if (fw == NULL) { + misp_info("%s, fw is NULL.", __func__); + return -EINVAL; + } + + file_total_size = fw->size; + fw_data = fw->data; + + /*read the header info (first 16 bytes in the basic code)*/ + memcpy(param, fw_data, ISPCMD_EXEBIN_INFOBYTES); + + /*To copy checksum value to correct header point*/ + memcpy((u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES + ISPCMD_EXEBIN_BLOCKSIZEBYTES), + (u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES), sizeof(u32)); + /*Assign block size to correct header point*/ + memcpy((u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES), &block_size, sizeof(u32)); + /* + * misp_info("%s param[0][1][2][3]: %02x %02x %02x %02x", + * __func__, param[0], param[1], param[2], param[3]); + * misp_info("%s param[4][5][6][7]: %02x %02x %02x %02x", + * __func__, param[4], param[5], param[6], param[7]); + * misp_info("%s param[8][9][10][11]: %02x %02x %02x %02x", + * __func__, param[8], param[9], param[10], param[11]); + * misp_info("%s param[12][13][14][15]: %02x %02x %02x %02x", + * __func__, param[12], param[13], param[14], param[15]); + */ + + misp_info("block size: %d", block_size); + misp_info("Total fw size: %zu", fw->size); + misp_info("fw size: %d", ((u32 *)param)[1]); + misp_info("0x%x, 0x%x, 0x%x, 0x%x", + ((u32 *)fw->data)[0], ((u32 *)fw->data)[1], + ((u32 *)fw->data)[2], ((u32 *)fw->data)[3]); + + /*Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_WRITE_BASICCODE, param, para_size); + if (err != ERR_SUCCESS) { + misp_info("%s, L: %d, err: %d", __func__, __LINE__, err); + goto mast_bulk_data_cmd_write_basic_code_end; + } + + /*misp_info("%s send leaking packet success", __func__);*/ + + /*misp_info("block_size %d", BLOCKSIZE);*/ + misp_info("%s send basic code start", __func__); + /*Transfer basic code*/ + err = ispctrl_if_mast_send_bulk(devdata, + fw_data + ISPCMD_EXEBIN_INFOBYTES, + *total_size, block_size, false); + + if (err != ERR_SUCCESS) { + misp_info("%s, L: %d, err: %d", __func__, __LINE__, err); + goto mast_bulk_data_cmd_write_basic_code_end; + } + + /*wait for the interrupt*/ + err = mini_isp_wait_for_event(MINI_ISP_RCV_BULKDATA); + + if (err != ERR_SUCCESS) { + misp_info("%s, L: %d, err: %d", __func__, __LINE__, err); + goto mast_bulk_data_cmd_write_basic_code_end; + } + + misp_info("%s - send basic code success", __func__); + + currpos = file_total_size - 32; + memcpy(fw_project_name, &fw_data[currpos], 16); + currpos = file_total_size - 12; + memcpy(fw_version, &fw_data[currpos], 4); + currpos += 4; + memcpy(fw_build_by, &fw_data[currpos], 8); + + err = 0; + fw_version_before_point = fw_version[1]*256 + fw_version[0]; + fw_version_after_point = fw_version[3]*256 + fw_version[2]; + fw_build_by[8] = '\0'; + fw_project_name[16] = '\0'; + misp_info("%s project: %s, fw version: %05d.%05d, build by %s", + __func__, fw_project_name, fw_version_before_point, + fw_version_after_point, fw_build_by); + +mast_bulk_data_cmd_write_basic_code_end: + if (fw != NULL) + release_firmware(fw); + return err; +} + +/** + *\brief Write Basic Code (Short SPI Len) + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], basic code file pointer + *\return Error code + */ +errcode mast_bulk_data_cmd_write_basic_code_shortlen( + void *devdata, u8 *param) +{ + errcode err = ERR_SUCCESS; + u8 fw_version[4]; + /* u32 para_size = ISPCMD_EXEBIN_INFOBYTES; */ + u32 *total_size = (u32 *)¶m[ISPCMD_EXEBIN_ADDRBYTES]; + u32 file_total_size; + u32 block_size; + off_t currpos; + const struct firmware *fw = NULL; + struct device *mini_isp_device; + char *fw_name = NULL; + + /* load boot fw file */ + mini_isp_device = mini_isp_getdev(); + if (mini_isp_device != NULL) { + fw_name = strrchr((BASIC_FILE_LOCATION ? + BASIC_FILE_LOCATION : ""), '/'); + + /* skip char '/' */ + if (fw_name != NULL) + fw_name = fw_name + 1; + + misp_info("%s, fw name: %s", __func__, fw_name); + err = request_firmware(&fw, + fw_name, mini_isp_device); + if (err) { + misp_info("%s, err: %d", __func__, err); + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + } + } + + if (fw == NULL) { + misp_info("%s, fw is NULL.", __func__); + return -EINVAL; + } + + block_size = SPI_BLOCK_LEN; + + /*get the file size*/ + file_total_size = fw->size; + fw_data = fw->data; + /*misp_info("%s filesize : %u", __func__, file_total_size);*/ + + + /*read the header info (first 16 bytes in the basic code)*/ + memcpy(param, fw_data, ISPCMD_EXEBIN_INFOBYTES); + + /*To copy checksum value to correct header point*/ + memcpy((u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES + ISPCMD_EXEBIN_BLOCKSIZEBYTES), + (u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES), sizeof(u32)); + /*Assign block size to correct header point*/ + memcpy((u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES), &block_size, sizeof(u32)); + + + misp_info("%s param[0][1][2][3]: %02x %02x %02x %02x", + __func__, param[0], param[1], param[2], param[3]); + misp_info("%s param[4][5][6][7]: %02x %02x %02x %02x", + __func__, param[4], param[5], param[6], param[7]); + misp_info("%s param[8][9][10][11]: %02x %02x %02x %02x", + __func__, param[8], param[9], param[10], param[11]); + misp_info("%s param[12][13][14][15]: %02x %02x %02x %02x", + __func__, param[12], param[13], param[14], param[15]); + + + + /* misp_info("%s Main Code Address >>>> param[0]: %04x", + * __func__, *(u32 *)¶m[0]); + * misp_info("%s Main Code Size >>>> param[4]: %04x", + * __func__, *(u32 *)¶m[4]); + * misp_info("%s Main Code Checksum >>>> param[12]: %04x", + * __func__, *(u32 *)¶m[12]); + */ + + /*Send command to slave*/ + /* Step 1: Main Code Address */ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_WRITE_BASICCODE_CODEADDR, + ¶m[0], ISPCMD_EXEBIN_ADDRBYTES); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + + msleep(20); /*mdelay(1);*/ + + /* Step 2: Main Code Size */ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_WRITE_BASICCODE_CODESIZE, + ¶m[4], ISPCMD_EXEBIN_TOTALSIZEBYTES); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + + msleep(20); /*mdelay(1);*/ + + /* Step 3: Main Code Checksum */ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_WRITE_BASICCODE_CODESUM, + ¶m[12], ISPCMD_EXEBIN_CKSUMBYTES); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + + + /*misp_info("%s send leaking packet success", __func__);*/ + + /*misp_info("block_size %d", BLOCKSIZE);*/ + misp_info("%s send basic code start", __func__); + /*Transfer basic code*/ + err = ispctrl_if_mast_send_bulk(devdata, + fw_data + ISPCMD_EXEBIN_INFOBYTES, + *total_size, block_size, false); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + + misp_info("%s - send basic code success", __func__); + + + /* mdelay(1); */ + + /* wait for the interrupt */ + err = mini_isp_wait_for_event(MINI_ISP_RCV_BULKDATA); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + + currpos = file_total_size - 32; + memcpy(fw_project_name, &fw_data[currpos], 16); + currpos = file_total_size - 12; + memcpy(fw_version, &fw_data[currpos], 4); + currpos += 4; + memcpy(fw_build_by, &fw_data[currpos], 8); + + err = 0; + fw_version_before_point = fw_version[1]*256 + fw_version[0]; + fw_version_after_point = fw_version[3]*256 + fw_version[2]; + fw_build_by[8] = '\0'; + fw_project_name[16] = '\0'; + misp_info("%s project: %s, fw version: %05d.%05d, build by %s", + __func__, fw_project_name, fw_version_before_point, + fw_version_after_point, fw_build_by); + +mast_bulk_data_cmd_write_basic_code_shortlen_end: + if (fw != NULL) + release_firmware(fw); + return err; +} + +/** + *\brief Write Calibration Data + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], calibration data file pointer + *\return Error code + */ +errcode +mast_bulk_data_cmd_write_calibration_data(void *devdata, + u8 *param) +{ + #define IS_FROM_AP_BUF (infomode == 0 || infomode == 1 || \ + infomode == 7 || infomode == 9) + errcode err = ERR_SUCCESS; + u8 infomode; + u16 opcode; + u16 ckecksum; + u32 para_size = 11; + u32 filesize = 0; + u32 block_size; + const char *file_name; + const struct firmware *fw = NULL; + struct device *mini_isp_device; + + infomode = param[8]; + block_size = ((struct misp_data *)devdata)->bulk_cmd_blocksize; + + /* Trasfered files have been opened in kernel + * when mini_isp_drv_load_fw() + */ + + /* load boot fw file */ + if (infomode == 2) + file_name = strrchr( + (SCENARIO_TABLE_FILE_LOCATION ? + SCENARIO_TABLE_FILE_LOCATION : ""), '/'); + else if (infomode == 3) + file_name = strrchr( + (HDR_QMERGE_DATA_FILE_LOCATION ? + HDR_QMERGE_DATA_FILE_LOCATION : ""), '/'); + else if (infomode == 4) + file_name = strrchr( + (IRP0_QMERGE_DATA_FILE_LOCATION ? + IRP0_QMERGE_DATA_FILE_LOCATION : ""), '/'); + + else if (infomode == 5) + file_name = strrchr( + (IRP1_QMERGE_DATA_FILE_LOCATION ? + IRP1_QMERGE_DATA_FILE_LOCATION : ""), '/'); + + else if (infomode == 6) + file_name = strrchr( + (PP_MAP_FILE_LOCATION ? + PP_MAP_FILE_LOCATION : ""), '/'); + + else if (infomode == 7) + file_name = NULL; + else if (infomode == 8) + file_name = strrchr( + (DPETH_QMERGE_DATA_FILE_LOCATION ? + DPETH_QMERGE_DATA_FILE_LOCATION : ""), '/'); + + else + file_name = NULL; + + /* skip char '/' */ + if (file_name != NULL) + file_name = file_name + 1; + + /* AP provide data buffer */ + if (IS_FROM_AP_BUF) { + misp_info("%s, buf_len: %d", __func__, *(u32 *)¶m[0]); + memcpy(&filesize, param, sizeof(u32)); + if (filesize > T_MEMSIZE) { + err = ~ERR_SUCCESS; + misp_info("%s, filesize:%d out of bound.", __func__, filesize); + return err; + } + calibration_data_buf_addr = kzalloc(filesize, GFP_KERNEL); + if (!calibration_data_buf_addr) { + err = ~ERR_SUCCESS; + misp_info("%s, L: %d, err: %d", + __func__, __LINE__, err); + goto cmd_write_calibration_data_end; + } + + memcpy(calibration_data_buf_addr, + param + T_SPI_CMD_LENGTH, filesize); + + /* + * calculate the checksum of calibration data. + */ + ckecksum = calculate_check_sum(calibration_data_buf_addr, filesize); + + fw_data = (const u8 *) calibration_data_buf_addr; + } else { + /* load bin file flow*/ + misp_info("%s, fw name: %s", __func__, file_name); + mini_isp_device = mini_isp_getdev(); + if (mini_isp_device != NULL && file_name != NULL) { + err = request_firmware(&fw, + file_name, mini_isp_device); + + if (err) { + misp_info("%s, L: %d, err: %d", + __func__, __LINE__, err); + goto cmd_write_calibration_data_end; + } + } + + if (fw == NULL) { + misp_info("%s, fw:%s is NULL.", __func__, file_name); + return -EINVAL; + } + + filesize = fw->size; + fw_data = fw->data; + + if (infomode == 2) { + sc_build_date = + fw_data[16+3]*256*256*256 + + fw_data[16+2]*256*256 + + fw_data[16+1]*256 + + fw_data[16+0]; + misp_info("%s - SC table build date %d.", __func__, + sc_build_date); + } + + ckecksum = calculate_check_sum(fw_data, filesize); + } + + /*Assign Info ID to correct header point*/ + memcpy((u8 *)(param + 8), &infomode, sizeof(u8)); + /*To copy Total Size to correct header point*/ + memcpy((u8 *)param, &filesize, sizeof(u32)); + /*Assign block size to correct header point*/ + memcpy((u8 *)(param + 4), &block_size, sizeof(u32)); + /*Assign check sum to correct header point*/ + memcpy((u8 *)(param + 9), &ckecksum, sizeof(u16)); + + if (SPI_SHORT_LEN_MODE && SPI_SHORT_LEN_MODE_WRITE_ENABLE) { + opcode = ISPCMD_BULK_WRITE_CALIBRATION_NO_BLOCK; + /* Total size(4byte) + data id(1byte) + checksum(2byte)*/ + para_size = 7; + /* left shift 4byte */ + memcpy((u8 *)(param + 4), (u8 *)(param + 8), + sizeof(u32) + sizeof(u16)); + block_size = SPI_BLOCK_LEN; + } else + opcode = ISPCMD_BULK_WRITE_CALIBRATION_DATA; + + /*Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, + opcode, param, para_size); + + if (err != ERR_SUCCESS) { + misp_info("%s L:%d err: %d", __func__, __LINE__, err); + goto cmd_write_calibration_data_end; + } + + /*misp_info("%s send leaking packet success", __func__);*/ + /*misp_info("block_size %d", BLOCKSIZE);*/ + + err = mini_isp_wait_for_event(MINI_ISP_RCV_CMD_READY); + if (err) { + misp_info("%s L:%d err: %d", __func__, __LINE__, err); + goto cmd_write_calibration_data_end; + } + + err = ispctrl_if_mast_send_bulk(devdata, + fw_data, filesize, block_size, false); + + if (err != ERR_SUCCESS) { + misp_info("%s L:%d err: %d", __func__, __LINE__, err); + goto cmd_write_calibration_data_end; + } + + err = mini_isp_wait_for_event(MINI_ISP_RCV_BULKDATA); + if (err) { + misp_info("%s L:%d err: %d", __func__, __LINE__, err); + goto cmd_write_calibration_data_end; + } + + if (infomode == 0) + misp_info("%s write IQ calibration data success", __func__); + else if (infomode == 1) + misp_info("%s write depth packet data success", __func__); + else if (infomode == 2) + misp_info("%s write scenario table success", __func__); + else if (infomode == 3) + misp_info("%s write HDR Qmerge data success", __func__); + else if (infomode == 4) + misp_info("%s write IRP0 Qmerge data success", __func__); + else if (infomode == 5) + misp_info("%s write IRP1 Qmerge data success", __func__); + else if (infomode == 6) + misp_info("%s write PP map success", __func__); + else if (infomode == 7) + misp_info("%s write blending table success", __func__); + else if (infomode == 8) + misp_info("%s write Depth Qmerge data success", __func__); + +cmd_write_calibration_data_end: + if (IS_FROM_AP_BUF && calibration_data_buf_addr != NULL) + kfree(calibration_data_buf_addr); + else if (fw != NULL) + release_firmware(fw); + + return err; + +} + +#else +/** + *\brief Write Boot Code + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], boot code file pointer + *\return Error code + */ +errcode mast_bulk_data_cmd_write_boot_code(void *devdata, + u8 *param, struct file *filp) +{ + errcode err = ERR_SUCCESS; + u32 total_size; + off_t currpos; + mm_segment_t oldfs; + u32 ProductId_val = 0; + u16 miniboot_version_before_point = 0; + u16 miniboot_version_after_point = 0; + u8 ProductId[4]; + u8 miniboot_ver_major[2]; + u8 miniboot_ver_minor[2]; + char miniboot_build_by[9]; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + if (filp == NULL) { + misp_err("%s - file didn't exist.", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_boot_code_end; + } + + /*get the file size*/ + currpos = vfs_llseek(filp, 0L, SEEK_END); + if (currpos == -1) { + misp_err("%s llseek failed", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_boot_code_end; + } + total_size = (u32)currpos; + /*misp_info("%s filesize : %d", __func__, total_size);*/ + vfs_llseek(filp, 0L, SEEK_SET); + + /*misp_info("block_size %d", RAWBLOCKSIZE);*/ + + /*Transfer boot code*/ + /* boot code & main code can only be sent by SPI */ + err = ispctrl_if_mast_send_bulk(devdata, + basic_code_buf_addr, filp, total_size, RAWBLOCKSIZE, true); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_boot_code_end; + + misp_info("%s send boot code success", __func__); + + /* Get miniboot version */ + set_fs(KERNEL_DS); + currpos = vfs_llseek(filp, total_size - 16, SEEK_SET); + err = vfs_read(filp, ProductId, 4, &filp->f_pos); + err = vfs_read(filp, miniboot_ver_major, 2, &filp->f_pos); + err = vfs_read(filp, miniboot_ver_minor, 2, &filp->f_pos); + err = vfs_read(filp, miniboot_build_by, 8, &filp->f_pos); + set_fs(oldfs); + if (err == -1) { + misp_info("%s - Read file failed.", __func__); + } else { + err = 0; + ProductId_val = (ProductId[3]<<24) + (ProductId[2]<<16) + + (ProductId[1] << 8) + ProductId[0]; + miniboot_version_before_point = miniboot_ver_major[1]*256 + + miniboot_ver_major[0]; + miniboot_version_after_point = miniboot_ver_minor[1]*256 + + miniboot_ver_minor[0]; + miniboot_build_by[8] = '\0'; + misp_info("%s - miniboot version: %d.%d.%d, build by %s", + __func__, ProductId_val, miniboot_version_before_point, + miniboot_version_after_point, miniboot_build_by); + } + /* Get miniboot version */ + +mast_bulk_data_cmd_write_boot_code_end: + + return err; +} + + +/** + *\brief Write Boot Code (Short SPI Len) + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], boot code file pointer + *\return Error code + */ +errcode +mast_bulk_data_cmd_write_boot_code_shortlen(void *devdata, + u8 *param, struct file *filp) +{ + errcode err = ERR_SUCCESS; + u32 total_size; + u32 block_size; + off_t currpos; + mm_segment_t oldfs; + + u32 ProductId_val = 0; + u16 miniboot_version_before_point = 0; + u16 miniboot_version_after_point = 0; + u8 ProductId[4]; + u8 miniboot_ver_major[2]; + u8 miniboot_ver_minor[2]; + char miniboot_build_by[9]; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + + block_size = SPI_BLOCK_LEN; + + if (filp == NULL) { + misp_err("%s - file didn't exist.", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_boot_code_end; + } + + /*get the file size*/ + currpos = vfs_llseek(filp, 0L, SEEK_END); + if (currpos == -1) { + misp_err("%s llseek failed", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_boot_code_end; + } + total_size = (u32)currpos; + /*misp_info("%s filesize : %d", __func__, total_size);*/ + vfs_llseek(filp, 0L, SEEK_SET); + + /*misp_info("block_size %d", RAWBLOCKSIZE);*/ + + /*Transfer boot code*/ + /* boot code & main code can only be sent by SPI */ + err = ispctrl_if_mast_send_bulk(devdata, + basic_code_buf_addr, filp, total_size, block_size, true); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_boot_code_end; + + misp_info("%s send boot code success", __func__); + + + + /* Get miniboot version */ + set_fs(KERNEL_DS); + currpos = vfs_llseek(filp, total_size - 16, SEEK_SET); + err = vfs_read(filp, ProductId, 4, &filp->f_pos); + err = vfs_read(filp, miniboot_ver_major, 2, &filp->f_pos); + err = vfs_read(filp, miniboot_ver_minor, 2, &filp->f_pos); + err = vfs_read(filp, miniboot_build_by, 8, &filp->f_pos); + set_fs(oldfs); + + if (err == -1) { + misp_info("%s - Read file failed.", __func__); + } else { + err = 0; + ProductId_val = (ProductId[3]<<24) + (ProductId[2]<<16) + + (ProductId[1] << 8) + ProductId[0]; + miniboot_version_before_point = miniboot_ver_major[1]*256 + + miniboot_ver_major[0]; + miniboot_version_after_point = miniboot_ver_minor[1]*256 + + miniboot_ver_minor[0]; + miniboot_build_by[8] = '\0'; + misp_info("%s - miniboot version: %d.%d.%d, build by %s", + __func__, ProductId_val, miniboot_version_before_point, + miniboot_version_after_point, miniboot_build_by); + } + /* Get miniboot version */ + + +mast_bulk_data_cmd_write_boot_code_end: + + return err; +} + + + +/** + *\brief Write Basic Code + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], basic code file pointer + *\return Error code + */ +errcode mast_bulk_data_cmd_write_basic_code(void *devdata, + u8 *param, struct file *filp) +{ + errcode err = ERR_SUCCESS; + u8 fw_version[4]; + u32 para_size = ISPCMD_EXEBIN_INFOBYTES; + u32 *total_size = (u32 *)¶m[ISPCMD_EXEBIN_ADDRBYTES]; + u32 file_total_size; + u32 block_size; + off_t currpos; + loff_t offset; + mm_segment_t oldfs; + + if (filp == NULL) { + misp_err("%s - file didn't exist.", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_basic_code_end; + } + + block_size = ((struct misp_data *)devdata)->bulk_cmd_blocksize; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + + /*get the file size*/ + currpos = vfs_llseek(filp, 0L, SEEK_END); + if (currpos == -1) { + set_fs(oldfs); + misp_err("%s - llseek end failed", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_basic_code_end; + } + + file_total_size = (u32)currpos; + /*misp_info("%s filesize : %u", __func__, file_total_size);*/ + + currpos = vfs_llseek(filp, 0L, SEEK_SET); + if (currpos == -1) { + set_fs(oldfs); + misp_err("%s - llseek set failed", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_basic_code_end; + } + + + /*read the header info (first 16 bytes in the basic code)*/ + offset = filp->f_pos; + err = vfs_read(filp, param, ISPCMD_EXEBIN_INFOBYTES, &offset); + set_fs(oldfs); + if (err == -1) { + misp_err("%s - Read file failed.", __func__); + /*close the file*/ + filp_close(filp, NULL); + goto mast_bulk_data_cmd_write_basic_code_end; + } + filp->f_pos = offset; + + /*To copy checksum value to correct header point*/ + memcpy((u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES + ISPCMD_EXEBIN_BLOCKSIZEBYTES), + (u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES), sizeof(u32)); + /*Assign block size to correct header point*/ + memcpy((u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES), &block_size, sizeof(u32)); + + /*misp_info("%s param[0][1][2][3]: %02x %02x %02x %02x", + *__func__, param[0], param[1], param[2], param[3]); + *misp_info("%s param[4][5][6][7]: %02x %02x %02x %02x", + *__func__, param[4], param[5], param[6], param[7]); + *misp_info("%s param[8][9][10][11]: %02x %02x %02x %02x", + *__func__, param[8], param[9], param[10], param[11]); + *misp_info("%s param[12][13][14][15]: %02x %02x %02x %02x", + *__func__, param[12], param[13], param[14], param[15]); + */ + + /*Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_WRITE_BASICCODE, param, para_size); + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_end; + + /*misp_info("%s send leaking packet success", __func__);*/ + + /*misp_info("block_size %d", BLOCKSIZE);*/ + misp_info("%s send basic code start", __func__); + /*Transfer basic code*/ + err = ispctrl_if_mast_send_bulk(devdata, + basic_code_buf_addr, filp, *total_size, block_size, false); + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_end; + + misp_info("%s - send basic code success", __func__); + + /*wait for the interrupt*/ + err = mini_isp_wait_for_event(MINI_ISP_RCV_BULKDATA); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_end; + + set_fs(KERNEL_DS); + offset = filp->f_pos; + currpos = vfs_llseek(filp, file_total_size - 32, SEEK_SET); + err = vfs_read(filp, fw_project_name, 16, &filp->f_pos); + + currpos = vfs_llseek(filp, file_total_size - 12, SEEK_SET); + err = vfs_read(filp, fw_version, 4, &filp->f_pos); + err = vfs_read(filp, fw_build_by, 8, &filp->f_pos); + set_fs(oldfs); + + if (err == -1) { + misp_info("%s - Read file failed.", __func__); + } else { + err = 0; + fw_version_before_point = fw_version[1]*256 + fw_version[0]; + fw_version_after_point = fw_version[3]*256 + fw_version[2]; + fw_build_by[8] = '\0'; + fw_project_name[16] = '\0'; + misp_info("%s project: %s, fw version: %05d.%05d, build by %s", + __func__, fw_project_name, fw_version_before_point, + fw_version_after_point, fw_build_by); +} +mast_bulk_data_cmd_write_basic_code_end: + + return err; +} + +/** + *\brief Write Basic Code (Short SPI Len) + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], basic code file pointer + *\return Error code + */ +errcode mast_bulk_data_cmd_write_basic_code_shortlen( + void *devdata, u8 *param, struct file *filp) +{ + errcode err = ERR_SUCCESS; + u8 fw_version[4]; + /* u32 para_size = ISPCMD_EXEBIN_INFOBYTES; */ + u32 *total_size = (u32 *)¶m[ISPCMD_EXEBIN_ADDRBYTES]; + u32 file_total_size; + u32 block_size; + off_t currpos; + loff_t offset; + mm_segment_t oldfs; + + if (filp == NULL) { + misp_err("%s - file didn't exist.", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + } + + block_size = SPI_BLOCK_LEN; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + + /*get the file size*/ + currpos = vfs_llseek(filp, 0L, SEEK_END); + if (currpos == -1) { + set_fs(oldfs); + misp_err("%s - llseek end failed", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + } + + file_total_size = (u32)currpos; + /*misp_info("%s filesize : %u", __func__, file_total_size);*/ + + currpos = vfs_llseek(filp, 0L, SEEK_SET); + if (currpos == -1) { + set_fs(oldfs); + misp_err("%s - llseek set failed", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + } + + + /*read the header info (first 16 bytes in the basic code)*/ + offset = filp->f_pos; + err = vfs_read(filp, param, ISPCMD_EXEBIN_INFOBYTES, &offset); + set_fs(oldfs); + if (err == -1) { + misp_err("%s - Read file failed.", __func__); + /*close the file*/ + filp_close(filp, NULL); + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + } + filp->f_pos = offset; + + /*To copy checksum value to correct header point*/ + memcpy((u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES + ISPCMD_EXEBIN_BLOCKSIZEBYTES), + (u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES), sizeof(u32)); + /*Assign block size to correct header point*/ + memcpy((u8 *)(param + ISPCMD_EXEBIN_ADDRBYTES + + ISPCMD_EXEBIN_TOTALSIZEBYTES), &block_size, sizeof(u32)); + + + /*misp_info("%s param[0][1][2][3]: %02x %02x %02x %02x", + *__func__, param[0], param[1], param[2], param[3]); + *misp_info("%s param[4][5][6][7]: %02x %02x %02x %02x", + *__func__, param[4], param[5], param[6], param[7]); + *misp_info("%s param[8][9][10][11]: %02x %02x %02x %02x", + *__func__, param[8], param[9], param[10], param[11]); + *misp_info("%s param[12][13][14][15]: %02x %02x %02x %02x", + *__func__, param[12], param[13], param[14], param[15]); + */ + + + /* misp_info("%s Main Code Address >>>> param[0]: %04x", + * __func__, *(u32 *)¶m[0]); + * misp_info("%s Main Code Size >>>> param[4]: %04x", + * __func__, *(u32 *)¶m[4]); + * misp_info("%s Main Code Checksum >>>> param[12]: %04x", + * __func__, *(u32 *)¶m[12]); + */ + + /*Send command to slave*/ + /* Step 1: Main Code Address */ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_WRITE_BASICCODE_CODEADDR, + ¶m[0], ISPCMD_EXEBIN_ADDRBYTES); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + + msleep(20); /*mdelay(1);*/ + + /* Step 2: Main Code Size */ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_WRITE_BASICCODE_CODESIZE, + ¶m[4], ISPCMD_EXEBIN_TOTALSIZEBYTES); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + + msleep(20); /*mdelay(1);*/ + + /* Step 3: Main Code Checksum */ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_WRITE_BASICCODE_CODESUM, + ¶m[12], ISPCMD_EXEBIN_CKSUMBYTES); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + + + /*misp_info("%s send leaking packet success", __func__);*/ + + /*misp_info("block_size %d", BLOCKSIZE);*/ + misp_info("%s send basic code start", __func__); + /*Transfer basic code*/ + err = ispctrl_if_mast_send_bulk(devdata, + basic_code_buf_addr, filp, *total_size, block_size, false); + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + + misp_info("%s - send basic code success", __func__); + + + /* mdelay(1); */ + + /* wait for the interrupt */ + err = mini_isp_wait_for_event(MINI_ISP_RCV_BULKDATA); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_basic_code_shortlen_end; + + set_fs(KERNEL_DS); + offset = filp->f_pos; + currpos = vfs_llseek(filp, file_total_size - 12, SEEK_SET); + err = vfs_read(filp, fw_version, 4, &filp->f_pos); + err = vfs_read(filp, fw_build_by, 8, &filp->f_pos); + set_fs(oldfs); + + if (err == -1) { + misp_info("%s - Read file failed.", __func__); + } else { + err = 0; + fw_version_before_point = fw_version[1]*256 + fw_version[0]; + fw_version_after_point = fw_version[3]*256 + fw_version[2]; + fw_build_by[8] = '\0'; + misp_info("%s - fw version: %05d.%05d, build by %s", + __func__, fw_version_before_point, + fw_version_after_point, fw_build_by); +} +mast_bulk_data_cmd_write_basic_code_shortlen_end: + + return err; +} + +/** + *\brief Write Calibration Data + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], calibration data file pointer + *\return Error code + */ +errcode +mast_bulk_data_cmd_write_calibration_data(void *devdata, + u8 *param, struct file *filp) +{ + errcode err = ERR_SUCCESS; + u8 infomode; + u16 opcode; + u16 ckecksum; + u32 para_size = 11; + u32 filesize; + u32 block_size; + off_t currpos; + loff_t offset; + mm_segment_t oldfs; + + infomode = param[8]; + block_size = ((struct misp_data *)devdata)->bulk_cmd_blocksize; + + /* Trasfered files have been opened in kernel + * when mini_isp_drv_load_fw() + */ + if (((infomode >= 2) && (infomode < 7)) || (infomode == 8)) { + if (filp == NULL) { + misp_err("%s - file didn't exist.", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_calibration_data_end; + } + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + /*get the file size*/ + currpos = vfs_llseek(filp, 0L, SEEK_END); + if (currpos == -1) { + set_fs(oldfs); + misp_err("%s llseek end failed", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_calibration_data_end; + } + + filesize = (u32)currpos; + /*misp_info("%s filesize : %u", __func__, filesize);*/ + + currpos = vfs_llseek(filp, 0L, SEEK_SET); + if (currpos == -1) { + set_fs(oldfs); + misp_err("%s llseek set failed", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_calibration_data_end; + } + + /*Request memory*/ + calibration_data_buf_addr = kzalloc(filesize, GFP_KERNEL); + if (!calibration_data_buf_addr) { + err = ~ERR_SUCCESS; + kfree(calibration_data_buf_addr); + goto mast_bulk_data_cmd_write_calibration_data_fail; + } + + /* if the file is SC table, print the SC table built day */ + if (infomode == 2) { + vfs_llseek(filp, 16, SEEK_SET); + vfs_read(filp, calibration_data_buf_addr, 4, + &filp->f_pos); + sc_build_date = + calibration_data_buf_addr[3]*256*256*256 + + calibration_data_buf_addr[2]*256*256 + + calibration_data_buf_addr[1]*256 + + calibration_data_buf_addr[0]; + misp_info("%s - SC table build date %d.", __func__, + sc_build_date); + vfs_llseek(filp, 0L, SEEK_SET); + } + + /*read the header info (first 16 bytes in the data)*/ + offset = filp->f_pos; + err = vfs_read(filp, calibration_data_buf_addr, filesize, + &offset); + set_fs(oldfs); + if (err == -1) { + misp_err("%s Read file failed.", __func__); + /*close the file*/ + filp_close(filp, NULL); + kfree(calibration_data_buf_addr); + goto mast_bulk_data_cmd_write_calibration_data_end; + } + filp->f_pos = offset; + vfs_llseek(filp, 0L, SEEK_SET); + + ckecksum = calculate_check_sum((u8 *) calibration_data_buf_addr, + filesize); + + /*Assign Info ID to correct header point*/ + memcpy((u8 *)(param + 8), &infomode, sizeof(u8)); + /*To copy Total Size to correct header point*/ + memcpy((u8 *)param, &filesize, sizeof(u32)); + /*Assign block size to correct header point*/ + memcpy((u8 *)(param + 4), &block_size, sizeof(u32)); + /*Assign check sum to correct header point*/ + memcpy((u8 *)(param + 9), &ckecksum, sizeof(u16)); + /* + * misp_info("%s [0][1][2][3]:%02x %02x %02x %02x", + * __func__, param[0], param[1], param[2], param[3]); + * misp_info("%s [4][5][6][7]:%02x %02x %02x %02x", + * __func__, param[4], param[5], param[6], param[7]); + * misp_info("%s [8][9][10]:%02x %02x %02x", + * __func__, param[8], param[9], param[10]); + */ + + /* Trasfered buffer has opened in user space and passed to kernel.*/ + } else { + memcpy(&filesize, param, sizeof(u32)); + calibration_data_buf_addr = kzalloc(filesize, GFP_KERNEL); + + if (!calibration_data_buf_addr) { + err = ~ERR_SUCCESS; + kfree(calibration_data_buf_addr); + goto mast_bulk_data_cmd_write_calibration_data_fail; + } + memcpy(calibration_data_buf_addr, + param + T_SPI_CMD_LENGTH, filesize); + } + + if (SPI_SHORT_LEN_MODE && SPI_SHORT_LEN_MODE_WRITE_ENABLE) { + opcode = ISPCMD_BULK_WRITE_CALIBRATION_NO_BLOCK; + /* Total size(4byte) + data id(1byte) + checksum(2byte)*/ + para_size = 7; + /* left shift 4byte */ + memcpy((u8 *)(param + 4), (u8 *)(param + 8), + sizeof(u32) + sizeof(u16)); + block_size = SPI_BLOCK_LEN; + } else + opcode = ISPCMD_BULK_WRITE_CALIBRATION_DATA; + + /*Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, + opcode, param, para_size); + + if (err != ERR_SUCCESS) { + kfree(calibration_data_buf_addr); + goto mast_bulk_data_cmd_write_calibration_data_end; + } + + /*misp_info("%s send leaking packet success", __func__);*/ + /*misp_info("block_size %d", BLOCKSIZE);*/ + + err = mini_isp_wait_for_event(MINI_ISP_RCV_CMD_READY); + if (err) + goto mast_bulk_data_cmd_write_calibration_data_fail; + + err = ispctrl_if_mast_send_bulk(devdata, + calibration_data_buf_addr, filp, filesize, block_size, + false); + + kfree(calibration_data_buf_addr); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_calibration_data_end; + + err = mini_isp_wait_for_event(MINI_ISP_RCV_BULKDATA); + if (err) + goto mast_bulk_data_cmd_write_calibration_data_fail; + + if (infomode == 0) + misp_info("%s write IQ calibration data success", __func__); + else if (infomode == 1) + misp_info("%s write depth packet data success", __func__); + else if (infomode == 2) + misp_info("%s write scenario table success", __func__); + else if (infomode == 3) + misp_info("%s write HDR Qmerge data success", __func__); + else if (infomode == 4) + misp_info("%s write IRP0 Qmerge data success", __func__); + else if (infomode == 5) + misp_info("%s write IRP1 Qmerge data success", __func__); + else if (infomode == 6) + misp_info("%s write PP map success", __func__); + else if (infomode == 7) + misp_info("%s write blending table success", __func__); + else if (infomode == 8) + misp_info("%s write Depth Qmerge data success", __func__); + + goto mast_bulk_data_cmd_write_calibration_data_end; + +mast_bulk_data_cmd_write_calibration_data_fail: + misp_err("%s mast_bulk_data_cmd_write_calibration_data_fail", __func__); + +mast_bulk_data_cmd_write_calibration_data_end: + return err; + +} + +#endif + +/* + *\brief Read Calibration Data + *\param devdata [In], misp_data + *\param param [In], CMD param + *\return Error code + */ +errcode mast_bulk_data_cmd_read_calibration_data(void *devdata, + u8 *param) +{ + /*Error Code*/ + errcode err = ERR_SUCCESS; + u8 *allocated_memmory = NULL; + u32 read_size = 0; + u8 filename[80]; + /* + *Parameter size + *4bytes for start addr, 4 bytes for total size, 4 bytes for block size, + *4 bytes for memory dump mode + */ + u32 para_size = sizeof(struct memmory_dump_hdr_info); + /*Total size*/ + u32 total_size; + struct memmory_dump_hdr_info *memory_dump_hdr_config; + struct file *f; + mm_segment_t fs; + + read_size = MID_PJ_EXEBIN_BUF; + + /*Request memory*/ + allocated_memmory = kzalloc(read_size, GFP_KERNEL); + if (!allocated_memmory) { + err = ~ERR_SUCCESS; + misp_err("%s Allocate memory failed.", __func__); + goto allocate_memory_fail; + } + + + memory_dump_hdr_config = (struct memmory_dump_hdr_info *)param; + + /*Assign total size*/ + total_size = memory_dump_hdr_config->total_size; + if (total_size > read_size) { + err = ERR_MASTERCMDSIZE_MISMATCH; + kfree(allocated_memmory); + misp_err("%s total_size error.", __func__); + goto mast_bulk_data_cmd_read_memory_data_end; + } + + /*Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_READ_CALIBRATION_DATA, param, para_size); + if (err != ERR_SUCCESS) { + kfree(allocated_memmory); + misp_err("%s send command fail, 0x%x.", __func__, err); + goto mast_bulk_data_cmd_read_memory_data_end; + } + /*Get memory data from slave*/ + err = ispctrl_if_mast_recv_memory_data_from_slave(devdata, + allocated_memmory, + &total_size, + memory_dump_hdr_config->block_size, + true); + if (err != ERR_SUCCESS) { + kfree(allocated_memmory); + misp_err("%s get bulk fail, 0x%x.", __func__, err); + goto mast_bulk_data_cmd_read_memory_data_end; + } + + misp_info("%s - Read memory finished.", __func__); + /*write out allocated_memmory to file here*/ + /*** add your codes here ***/ + snprintf(filename, 80, "%s/READ_OTP_DATA.bin", + MINIISP_INFO_DUMPLOCATION); +#if ENABLE_FILP_OPEN_API + /* use file open */ +#else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + goto file_open_fail; +#endif + /*Get current segment descriptor*/ + fs = get_fs(); + /*Set segment descriptor associated*/ + set_fs(get_ds()); + + if (IS_ERR(f)) { + err = PTR_ERR(f); + misp_err("%s open file failed. err: %d", __func__, err); + set_fs(fs); + goto file_open_fail; + } + + /*write the file*/ + vfs_write(f, (char *)allocated_memmory, total_size, + &f->f_pos); + + /*Restore segment descriptor*/ + set_fs(fs); + filp_close(f, NULL); + /*** end of the codes ***/ +file_open_fail: + kfree(allocated_memmory); +allocate_memory_fail: +mast_bulk_data_cmd_read_memory_data_end: + + return err; + + +} + +/* + *\brief Read Memory Data + *\param devdata [In], misp_data + *\param param [In], CMD param + *\return Error code + */ +errcode mast_bulk_data_cmd_read_memory_data(void *devdata, + u8 *param) +{ + /*Error Code*/ + errcode err = ERR_SUCCESS; + u8 *allocated_memmory = NULL; + u32 read_size = 0; + u8 filename[80]; + /* + *Parameter size + *4bytes for start addr, 4 bytes for total size, 4 bytes for block size, + *4 bytes for memory dump mode + */ + u32 para_size = sizeof(struct memmory_dump_hdr_info); + /*Total size*/ + u32 total_size; + struct memmory_dump_hdr_info *memory_dump_hdr_config; + struct file *f; + mm_segment_t fs; + + read_size = MID_PJ_EXEBIN_BUF; + + /*Request memory*/ + allocated_memmory = kzalloc(read_size, GFP_KERNEL); + if (!allocated_memmory) { + err = ~ERR_SUCCESS; + misp_err("%s Allocate memory failed.", __func__); + goto allocate_memory_fail; + } + + + memory_dump_hdr_config = (struct memmory_dump_hdr_info *)param; + + /*Assign total size*/ + total_size = memory_dump_hdr_config->total_size; + if (total_size > read_size) { + kfree(allocated_memmory); + err = ERR_MASTERCMDSIZE_MISMATCH; + misp_err("%s total_size error.", __func__); + goto mast_bulk_data_cmd_read_memory_data_end; + } + + /*Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_READ_MEMORY, param, para_size); + if (err != ERR_SUCCESS) { + kfree(allocated_memmory); + misp_err("%s send command fail, 0x%x.", __func__, err); + goto mast_bulk_data_cmd_read_memory_data_end; + } + /*Get memory data from slave*/ + err = ispctrl_if_mast_recv_memory_data_from_slave(devdata, + allocated_memmory, + &total_size, + memory_dump_hdr_config->block_size, + true); + if (err != ERR_SUCCESS) { + kfree(allocated_memmory); + misp_err("%s get bulk fail, 0x%x.", __func__, err); + goto mast_bulk_data_cmd_read_memory_data_end; + } + + misp_info("%s - Read memory finished.", __func__); + /*write out allocated_memmory to file here*/ + /*** add your codes here ***/ + snprintf(filename, 80, "%s/miniISP_memory.log", + MINIISP_INFO_DUMPLOCATION); +#if ENABLE_FILP_OPEN_API + /* use file open */ +#else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + goto file_open_fail; +#endif + /*Get current segment descriptor*/ + fs = get_fs(); + /*Set segment descriptor associated*/ + set_fs(get_ds()); + + if (IS_ERR(f)) { + err = PTR_ERR(f); + misp_err("%s open file failed. err: %d", __func__, err); + set_fs(fs); + goto file_open_fail; + } + + /*write the file*/ + vfs_write(f, (char *)allocated_memmory, total_size, + &f->f_pos); + + /*Restore segment descriptor*/ + set_fs(fs); + filp_close(f, NULL); + /*** end of the codes ***/ +file_open_fail: + kfree(allocated_memmory); +allocate_memory_fail: +mast_bulk_data_cmd_read_memory_data_end: + + return err; +} + +/* + *\brief Read common log data + *\param devdata [In], misp_data + *\param param [In], CMD param + *\return Error code + */ +errcode bulk_data_cmd_read_common_log(void *devdata, u8 *param) +{ + /*Error Code*/ + errcode err = ERR_SUCCESS; + u8 *allocated_memmory = NULL; + u32 read_size = LOGSIZE; + struct file *f = NULL; + mm_segment_t fs; + u8 filename[80]; + + /*Parameter size : 4 bytes for total size, 4 bytes for block size*/ + u32 para_size = sizeof(struct common_log_hdr_info); + /*Total size*/ + u32 total_size; + struct common_log_hdr_info *common_log_hdr_cfg; + + + /*Request memory*/ + allocated_memmory = kzalloc(read_size, GFP_KERNEL); + if (!allocated_memmory) { + err = ~ERR_SUCCESS; + goto allocate_memory_fail; + } + + + common_log_hdr_cfg = (struct common_log_hdr_info *)param; + + /*Assign total size*/ + total_size = common_log_hdr_cfg->total_size; + if (total_size > read_size) { + err = ERR_MASTERCMDSIZE_MISMATCH; + kfree(allocated_memmory); + goto bulk_data_cmd_read_common_log_end; + } + + /*Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_READ_COMLOG, param, para_size); + if (err != ERR_SUCCESS) { + kfree(allocated_memmory); + misp_info("%s err - 0x%x.", __func__, err); + goto bulk_data_cmd_read_common_log_end; + } + misp_info("%s - Start to read log.", __func__); + + /* + *Get memory data from slave,don't wait INT + *and use polling interval to wait + */ + err = ispctrl_if_mast_recv_memory_data_from_slave(devdata, + allocated_memmory, + &total_size, + common_log_hdr_cfg->block_size, + true); + if (err != ERR_SUCCESS) { + kfree(allocated_memmory); + goto bulk_data_cmd_read_common_log_end; + } + misp_info("%s - Read log finished.", __func__); + snprintf(filename, 80, "%s/miniISP_Common_Log.log", + MINIISP_INFO_DUMPLOCATION); +#if ENABLE_FILP_OPEN_API + /* use file open */ +#else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + kfree(allocated_memmory); + goto bulk_data_cmd_read_common_log_end; +#endif + /*Get current segment descriptor*/ + fs = get_fs(); + + /*Set segment descriptor associated*/ + set_fs(get_ds()); + + if (IS_ERR(f)) { + err = PTR_ERR(f); + misp_err("%s open file failed. err: %d", __func__, err); + goto file_open_fail; + } + /*write the file*/ + vfs_write(f, (char *)allocated_memmory, strlen(allocated_memmory), + &f->f_pos); + +file_open_fail: + /*Restore segment descriptor*/ + set_fs(fs); + filp_close(f, NULL); + + kfree(allocated_memmory); + goto bulk_data_cmd_read_common_log_end; +allocate_memory_fail: + + misp_err("%s Allocate memory failed.", __func__); +bulk_data_cmd_read_common_log_end: + return err; +} + + +/* + *\brief Get depth Rect A, B, Invrect + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_bulk_data_cmd_write_depth_rectab_invrect( + void *devdata, u16 opcode, u8 *param) +{ + /*Error Code */ + errcode err = ERR_SUCCESS; + u8 *allocated_memmory = 0; + u32 para_size = 0; + u32 rect_set_num = 0; + u32 send_total_bulk_size = 0; + u8 send_cmd[T_SPI_CMD_LENGTH]; + struct isp_cmd_depth_rectab_invrect_info *depth_rect_info; + + depth_rect_info = (struct isp_cmd_depth_rectab_invrect_info *)param; + if (depth_rect_info->trans_mode == 0) + rect_set_num = 3; + else + rect_set_num = 1; + + send_total_bulk_size = + rect_set_num*sizeof(struct depth_rectab_invrect_param); + + /* Fill command buffer for send */ + memcpy(&send_cmd[0], &(depth_rect_info->trans_mode), + sizeof(depth_rect_info->trans_mode)); + para_size = sizeof(depth_rect_info->trans_mode); + + memcpy(&send_cmd[para_size], &(depth_rect_info->block_size), + sizeof(depth_rect_info->block_size)); + para_size += sizeof(depth_rect_info->block_size); + + /*Request memory*/ + allocated_memmory = kzalloc(send_total_bulk_size, GFP_KERNEL); + if (!allocated_memmory) { + err = ~ERR_SUCCESS; + goto allocate_memory_fail; + } + + /*Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, + ISPCMD_BULK_WRITE_DEPTH_RECTAB_INVRECT, + (u8 *)&send_cmd[0], para_size); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_depth_rectab_invrect_end; + + err = mini_isp_wait_for_event(MINI_ISP_RCV_CMD_READY); + if (err) + goto mast_bulk_data_cmd_write_depth_rectab_invrect_end; + +#if ENABLE_LINUX_FW_LOADER + /* Send bulk data to slave*/ + err = ispctrl_if_mast_send_bulk( + devdata, + (u8 *)&depth_rect_info->rect_param[0], + send_total_bulk_size, + depth_rect_info->block_size, false); +#else + /* Send bulk data to slave*/ + err = ispctrl_if_mast_send_bulk( + devdata, + (u8 *)&depth_rect_info->rect_param[0], + NULL, send_total_bulk_size, + depth_rect_info->block_size, false); +#endif + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_depth_rectab_invrect_end; + + err = mini_isp_wait_for_event(MINI_ISP_RCV_BULKDATA); + if (err) + goto mast_bulk_data_cmd_write_depth_rectab_invrect_end; + +mast_bulk_data_cmd_write_depth_rectab_invrect_end: + kfree(allocated_memmory); + allocated_memmory = NULL; + +allocate_memory_fail: + misp_err("%s Allocate memory failed.", __func__); + + return err; +} + +#if ENABLE_LINUX_FW_LOADER +/** + *\brief Write Spinor Data + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], the data file pointer + *\return Error code + */ +errcode mast_bulk_data_cmd_write_spinor_data(void *devdata, + u8 *param) +{ + errcode err = ERR_SUCCESS; + u8 infomode; + u16 opcode; + u16 ckecksum; + u32 para_size = 11; + u32 filesize; + u32 block_size; + const char *file_name; + const struct firmware *fw = NULL; + struct device *mini_isp_device; + const u8 *fw_data; + + infomode = param[8]; + block_size = ((struct misp_data *)devdata)->bulk_cmd_blocksize; + + if (infomode == 0) + file_name = strrchr( + BOOT_FILE_LOCATION ? + BOOT_FILE_LOCATION : "", '/'); + else if (infomode == 1) + file_name = strrchr( + BASIC_FILE_LOCATION ? + BASIC_FILE_LOCATION : "", '/'); + else { + misp_err("%s not support infomode: %x", __func__, infomode); + goto mast_bulk_data_cmd_write_spinor_data_end; + } + + mini_isp_device = mini_isp_getdev(); + if (mini_isp_device != NULL && file_name != NULL) { + /* skip char '/' */ + if (file_name != NULL) + file_name = file_name + 1; + + misp_info("%s, fw name: %s", __func__, file_name); + err = request_firmware(&fw, + file_name, mini_isp_device); + + if (err) { + misp_info("%s, L: %d, err: %d", + __func__, __LINE__, err); + goto mast_bulk_data_cmd_write_spinor_data_end; + } + } + + if (fw == NULL) { + misp_info("%s, fw:%s is NULL.", __func__, file_name); + return -EINVAL; + } + + /*get the file size*/ + filesize = fw->size; + fw_data = fw->data; + + ckecksum = calculate_check_sum(fw_data, filesize); + misp_info("ckecksum %d", ckecksum); + /*Assign Info ID to correct header point*/ + memcpy((u8 *)(param + 8), &infomode, sizeof(u8)); + /*To copy Total Size to correct header point*/ + memcpy((u8 *)param, &filesize, sizeof(u32)); + /*Assign block size to correct header point*/ + memcpy((u8 *)(param + 4), &block_size, sizeof(u32)); + /*Assign check sum to correct header point*/ + memcpy((u8 *)(param + 9), &ckecksum, sizeof(u16)); + + opcode = ISPCMD_BULK_WRITE_SPINOR_DATA; + + /*Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, + opcode, param, para_size); + if (err != ERR_SUCCESS) { + misp_info("%s, L: %d, err: %d", __func__, __LINE__, err); + goto mast_bulk_data_cmd_write_spinor_data_end; + } + + /*misp_info("%s send leaking packet success", __func__);*/ + + /*misp_info("block_size %d", BLOCKSIZE);*/ + + err = mini_isp_wait_for_event(MINI_ISP_RCV_CMD_READY); + if (err) { + misp_info("%s, L: %d, err: %d", __func__, __LINE__, err); + goto mast_bulk_data_cmd_write_spinor_data_end; + } + + err = ispctrl_if_mast_send_bulk(devdata, + fw_data, filesize, block_size, false); + + if (err != ERR_SUCCESS) { + misp_info("%s, L: %d, err: %d", __func__, __LINE__, err); + goto mast_bulk_data_cmd_write_spinor_data_end; + } + + err = mini_isp_wait_for_event(MINI_ISP_RCV_BULKDATA); + + if (err) { + misp_info("%s, L: %d, err: %d", __func__, __LINE__, err); + goto mast_bulk_data_cmd_write_spinor_data_end; + } + + if (infomode == 0) + misp_info("%s write spinor boot data success", __func__); + else if (infomode == 1) + misp_info("%s write spinor main data success", __func__); + +mast_bulk_data_cmd_write_spinor_data_end: + if (fw != NULL) + release_firmware(fw); + + return err; + +} + +#else +/** + *\brief Write Spinor Data + *\param devdata [In], misp_data + *\param param [In], CMD param + *\param filp [In], the data file pointer + *\return Error code + */ +errcode mast_bulk_data_cmd_write_spinor_data(void *devdata, + u8 *param, struct file *filp) +{ + errcode err = ERR_SUCCESS; + u8 infomode; + u16 opcode; + u16 ckecksum; + u32 para_size = 11; + u32 filesize; + u32 block_size; + off_t currpos; + loff_t offset; + mm_segment_t oldfs; + + infomode = param[8]; + block_size = ((struct misp_data *)devdata)->bulk_cmd_blocksize; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + +#if ENABLE_FILP_OPEN_API + /* use file open */ +#else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + set_fs(oldfs); + goto mast_bulk_data_cmd_write_spinor_data_end; +#endif + if (IS_ERR(filp)) { + err = PTR_ERR(filp); + misp_err("%s open file failed. err: %x", __func__, err); + goto mast_bulk_data_cmd_write_spinor_data_end; + } else { + misp_info("%s open file success!", __func__); + } + + /*get the file size*/ + currpos = vfs_llseek(filp, 0L, SEEK_END); + if (currpos == -1) { + set_fs(oldfs); + misp_err("%s llseek end failed", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_spinor_data_end; + } + + filesize = (u32)currpos; + /*misp_info("%s filp: %p, filesize : %u, blocksize : %u" + * , __func__, filp, filesize, block_size); + */ + + currpos = vfs_llseek(filp, 0L, SEEK_SET); + if (currpos == -1) { + set_fs(oldfs); + misp_err("%s llseek set failed", __func__); + err = ~ERR_SUCCESS; + goto mast_bulk_data_cmd_write_spinor_data_end; + } + + /*Request memory*/ + calibration_data_buf_addr = vmalloc(filesize); + if (!calibration_data_buf_addr) { + err = ~ERR_SUCCESS; + vfree(calibration_data_buf_addr); + goto mast_bulk_data_cmd_write_spinor_data_fail; + } + + offset = filp->f_pos; + err = vfs_read(filp, calibration_data_buf_addr, filesize, &offset); + filp->f_pos = offset; + + set_fs(oldfs); + if (err == -1) { + misp_err("%s Read file failed.", __func__); + /*close the file*/ + filp_close(filp, NULL); + vfree(calibration_data_buf_addr); + goto mast_bulk_data_cmd_write_spinor_data_end; + } + vfs_llseek(filp, 0L, SEEK_SET); + + ckecksum = calculate_check_sum((u8 *) calibration_data_buf_addr, + filesize); + misp_info("ckecksum %d", ckecksum); + /*Assign Info ID to correct header point*/ + memcpy((u8 *)(param + 8), &infomode, sizeof(u8)); + /*To copy Total Size to correct header point*/ + memcpy((u8 *)param, &filesize, sizeof(u32)); + /*Assign block size to correct header point*/ + memcpy((u8 *)(param + 4), &block_size, sizeof(u32)); + /*Assign check sum to correct header point*/ + memcpy((u8 *)(param + 9), &ckecksum, sizeof(u16)); + + opcode = ISPCMD_BULK_WRITE_SPINOR_DATA; + + /*Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, + opcode, param, para_size); + if (err != ERR_SUCCESS) { + vfree(calibration_data_buf_addr); + goto mast_bulk_data_cmd_write_spinor_data_end; + } + + /*misp_info("%s send leaking packet success", __func__);*/ + + /*misp_info("block_size %d", BLOCKSIZE);*/ + + err = mini_isp_wait_for_event(MINI_ISP_RCV_CMD_READY); + if (err) + goto mast_bulk_data_cmd_write_spinor_data_fail; + + err = ispctrl_if_mast_send_bulk(devdata, + calibration_data_buf_addr, filp, filesize, block_size, + false); + + if (err != ERR_SUCCESS) + goto mast_bulk_data_cmd_write_spinor_data_end; + + err = mini_isp_wait_for_event(MINI_ISP_RCV_BULKDATA); + + vfree(calibration_data_buf_addr); + + if (err) + goto mast_bulk_data_cmd_write_spinor_data_fail; + + if (infomode == 0) + misp_info("%s write spinor boot data success", __func__); + else if (infomode == 1) + misp_info("%s write spinor main data success", __func__); + + goto mast_bulk_data_cmd_write_spinor_data_end; + +mast_bulk_data_cmd_write_spinor_data_fail: + misp_err("%s mast_bulk_data_cmd_write_spinor_data_fail", __func__); + +mast_bulk_data_cmd_write_spinor_data_end: + + /*close the file*/ + filp_close(filp, NULL); + + return err; + +} +#endif + +/******Private Function******/ +static +u16 calculate_check_sum(const u8 *input_buffer_addr, u32 input_buffer_size) +{ + u32 i; + u32 sum = 0; + u16 sumvalue; + + if (input_buffer_size > MAX_BUFFER_SIZE) { + misp_err("%s input buffer size:%d out of bound.", + __func__, input_buffer_size); + return 0; + } + + /*calculating unit is 2 bytes */ + for (i = 0; i < input_buffer_size; i++) { + if (0 == (i%2)) + sum += input_buffer_addr[i]; + else + sum += (input_buffer_addr[i] << 8); + } + + /*Do 2's complement */ + sumvalue = (u16)(65536 - (sum & 0x0000FFFF)); + + return sumvalue; +} + +/******End Of File******/ diff --git a/drivers/media/platform/altek/camera_profile_cmd.c b/drivers/media/platform/altek/camera_profile_cmd.c new file mode 100755 index 000000000000..a1ab39f46ef3 --- /dev/null +++ b/drivers/media/platform/altek/camera_profile_cmd.c @@ -0,0 +1,716 @@ +/* + * File: camera_profile_cmd.c + * Description: Mini ISP sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/10/14; Bruce Chung; Initial version + * 2013/12/05; Bruce Chung; 2nd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/******Include File******/ + +#include + +#include "include/mtype.h" +#include "include/error.h" +#include "include/miniisp.h" +#include "include/isp_camera_cmd.h" +#include "include/ispctrl_if_master.h" +#include "include/ispctrl_if_master_local.h" + +/******Private Constant Definition******/ +#define MINI_ISP_LOG_TAG "[[miniisp]camera_profile_cmd]" + +/******Private Type Declaration******/ + +/******Private Function Prototype******/ + +/******Private Global Variable******/ + +static struct isp_cmd_get_sensor_mode mast_sensors_info; + +/******Public Function******/ + +/* + *\brief Camera profile parameters init + *\return None + */ +void isp_mast_camera_profile_para_init(void) +{ + /*Reset Camera profile parameters*/ + memset(&mast_sensors_info, 0x0, + sizeof(struct isp_cmd_get_sensor_mode)); +} + +/* + *\brief Set Sensor Mode + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_sensor_mode( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_set_sensor_mode *set_sensor_mode_param; + + set_sensor_mode_param = (struct isp_cmd_set_sensor_mode *)param; + misp_info("%s - enter", __func__); + misp_info("[on/off]: %d, [id]:%d, [txskew]: %d", + set_sensor_mode_param->sensor_on_off, + set_sensor_mode_param->scenario_id, + set_sensor_mode_param->mipi_tx_skew); + + misp_info("[w_tbl_idx]: %d, [merge_enable]:%d", + set_sensor_mode_param->ae_weighting_table_index, + set_sensor_mode_param->merge_mode_enable); + + para_size = sizeof(struct isp_cmd_set_sensor_mode); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + + + if ((((struct isp_cmd_set_sensor_mode *)param)->sensor_on_off) + && (err == ERR_SUCCESS)) + err = mini_isp_wait_for_event(MINI_ISP_RCV_SETSENSORMODE); + + return err; +} + +/* + *\brief Get Sensor Mode + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_get_sensor_mode( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + + misp_info("%s - enter", __func__); + + para_size = sizeof(struct isp_cmd_get_sensor_mode); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, NULL, 0); + if (err != ERR_SUCCESS) + goto mast_camera_profile_cmd_get_sensor_mode_end; + + /* Get data from slave*/ + err = ispctrl_mast_recv_response_from_slave(devdata, + (u8 *)&mast_sensors_info, para_size, true); + if (err != ERR_SUCCESS) + goto mast_camera_profile_cmd_get_sensor_mode_end; + + /* copy to usr defined target addr*/ + memcpy(param, &mast_sensors_info, para_size); + +mast_camera_profile_cmd_get_sensor_mode_end: + return err; +} + +/* + *\brief Set Output Format + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_output_format( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_set_output_format *set_output_format_param; + + set_output_format_param = (struct isp_cmd_set_output_format *)param; + + misp_info("%s - enter", __func__); + misp_info("[DP_size]: 0x%x, [DP_Type_LV]: 0x%x, [InvRect_bypass]: 0x%x", + set_output_format_param->depth_size, + set_output_format_param->reserve[0], + set_output_format_param->reserve[1]); + + para_size = sizeof(struct isp_cmd_set_output_format); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, param, + para_size); + return err; +} + +/* + *\brief Set CP Mode + *\return Error code + */ +errcode mast_camera_profile_cmd_set_cp_mode( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + + misp_info("%s - enter", __func__); + + para_size = 0; + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + if (err != ERR_SUCCESS) + goto mast_camera_profile_cmd_set_cp_mode_end; + + err = mini_isp_wait_for_event(MINI_ISP_RCV_CPCHANGE); + +mast_camera_profile_cmd_set_cp_mode_end: + return err; +} + +/* + *\brief Set AE statistics + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_ae_statistics( + void *devdata, u16 opcode, u8 *param) +{ + /*Error Code */ + errcode err = ERR_SUCCESS; + u32 para_size = sizeof(struct isp_cmd_ae_statistics); + + misp_info("%s - enter", __func__); + /*Send command to slave */ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Preview stream on off + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_preview_stream_on_off( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_preview_stream_on_off *preview_stream_on_off_param; + + preview_stream_on_off_param = + (struct isp_cmd_preview_stream_on_off *)param; + + misp_info("%s - enter", __func__); + misp_info("[tx0]: %d, [tx1]: %d", + preview_stream_on_off_param->tx0_stream_on_off, + preview_stream_on_off_param->tx1_stream_on_off); + + para_size = sizeof(struct isp_cmd_preview_stream_on_off); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief dual PD Y calculation weightings + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode +mast_camera_profile_cmd_dual_pd_y_cauculation_weightings( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + + misp_info("%s - enter", __func__); + para_size = sizeof(struct isp_cmd_dual_pd_y_calculation_weightings); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief LED power control + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_led_power_control( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_led_power_control *led_power_control_param; + + led_power_control_param = (struct isp_cmd_led_power_control *)param; + misp_info("%s - enter", __func__); + misp_info("[led_onoff]: %d, [led_lv]: %d, [led_id]: %d", + led_power_control_param->led_on_off, + led_power_control_param->led_power_level, + led_power_control_param->control_projector_id); + + misp_info("[delay_after_sof]: %d, [pulse_time]: %d", + led_power_control_param->delay_after_sof, + led_power_control_param->pulse_time); + + misp_info("[control_mode]: %d, [reserved]: %d, [rolling_shutter]: %d", + led_power_control_param->control_mode, + led_power_control_param->reserved, + led_power_control_param->rolling_shutter); + + para_size = sizeof(struct isp_cmd_led_power_control); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Active AE + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_active_ae( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_active_ae *active_ae_param; + + active_ae_param = (struct isp_cmd_active_ae *) param; + misp_info("%s - enter", __func__); + misp_info("[active ae]: %d, [f_number]: %d", + active_ae_param->active_ae, active_ae_param->f_number_x1000); + + para_size = sizeof(struct isp_cmd_active_ae); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Control AE on/off + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_isp_ae_control_on_off( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_isp_ae_control_on_off *ae_control_on_off_param; + + ae_control_on_off_param = (struct isp_cmd_isp_ae_control_on_off *)param; + misp_info("%s - enter", __func__); + misp_info("[ae control]: %d", + ae_control_on_off_param->isp_ae_control_mode_on_off); + + para_size = sizeof(struct isp_cmd_isp_ae_control_on_off); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set Frame Rate Limits + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_frame_rate_limits( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + + misp_info("%s - enter", __func__); + para_size = sizeof(struct isp_cmd_frame_rate_limits); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set period drop frame + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_period_drop_frame( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_period_drop_frame *period_drop_frame_param; + + period_drop_frame_param = (struct isp_cmd_period_drop_frame *)param; + misp_info("%s - enter", __func__); + misp_info("[period_drop_type]: %d", + period_drop_frame_param->period_drop_type); + + para_size = sizeof(struct isp_cmd_period_drop_frame); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set Max exposure + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_max_exposure( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + + misp_info("%s - enter", __func__); + para_size = sizeof(struct isp_cmd_exposure_param); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set target mean + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_target_mean( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + + misp_info("%s - enter", __func__); + para_size = sizeof(struct isp_cmd_target_mean); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Frame sync control + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_frame_sync_control( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_frame_sync_control *frame_sync_control_param; + + frame_sync_control_param = (struct isp_cmd_frame_sync_control *)param; + misp_info("%s - enter", __func__); + misp_info("[deviceId]: %d, [delay_frame]: %d, [active_frame]: %d,", + frame_sync_control_param->control_deviceID, + frame_sync_control_param->delay_framephase, + frame_sync_control_param->active_framephase); + + misp_info("[deactive_frame]: %d, [active_timeLv]: %d", + frame_sync_control_param->deactive_framephase, + frame_sync_control_param->active_timelevel); + + para_size = sizeof(struct isp_cmd_frame_sync_control); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set shot mode + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_shot_mode( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_set_shot_mode *set_shot_mode_param; + + set_shot_mode_param = (struct isp_cmd_set_shot_mode *)param; + misp_info("%s - enter", __func__); + misp_info("[shot_mode]: %d, [frame_rate]: %d", + set_shot_mode_param->shot_mode, + set_shot_mode_param->frame_rate); + para_size = sizeof(struct isp_cmd_set_shot_mode); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Lighting control + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_lighting_ctrl( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size, i; + struct isp_cmd_lighting_ctrl *lighting_ctrl_param; + + lighting_ctrl_param = (struct isp_cmd_lighting_ctrl *)param; + misp_info("%s - enter", __func__); + misp_info("[cycle_len]: %d", lighting_ctrl_param->cycle_len); + for (i = 0; i < lighting_ctrl_param->cycle_len; i++) { + misp_info("cycle[%d]: 0x%x, 0x%x, %d", i, + lighting_ctrl_param->cycle[i].source, + lighting_ctrl_param->cycle[i].TxDrop, + lighting_ctrl_param->cycle[i].co_frame_rate); + } + para_size = sizeof(struct isp_cmd_lighting_ctrl); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set Min exposure + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_min_exposure( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + + misp_info("%s - enter", __func__); + para_size = sizeof(struct isp_cmd_exposure_param); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set Max exposure slope + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_max_exposure_slope( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + + misp_info("%s - enter", __func__); + para_size = sizeof(struct isp_cmd_max_exposure_slope); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set Depth Compensation + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_depth_compensation( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_depth_compensation_param *depth_compensation_param; + + depth_compensation_param = + (struct isp_cmd_depth_compensation_param *)param; + + misp_info("%s - enter", __func__); + misp_info("[en_updated]: 0x%x, [short_dist]: %d, [compensation]: %d", + depth_compensation_param->en_updated, + depth_compensation_param->short_distance_value, + depth_compensation_param->compensation); + + para_size = sizeof(struct isp_cmd_depth_compensation_param); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/* + *\brief Set cycle trigger depth process + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_cycle_trigger_depth( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + struct isp_cmd_cycle_trigger_depth_process + *cycle_trigger_depth_process_param; + + cycle_trigger_depth_process_param = + (struct isp_cmd_cycle_trigger_depth_process *)param; + + misp_info("%s - enter", __func__); + misp_info("[Cycle_len]: %d, [DP_trigBitField]: 0x%x", + cycle_trigger_depth_process_param->cycleLen, + cycle_trigger_depth_process_param->depth_triggerBitField); + + misp_info("[DPOut_trigBitField]: 0x%x", + cycle_trigger_depth_process_param->depthoutput_triggerBitField); + + para_size = sizeof(struct isp_cmd_cycle_trigger_depth_process); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} +/* + *\brief Set led active delay time + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_led_active_delay( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + + misp_info("%s - enter", __func__); + misp_info("[delay]: %d", *(u32 *)param); + para_size = sizeof(u32); + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} +/* + *\brief Set isp control led level + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_isp_control_led_level( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size; + + misp_info("%s - enter", __func__); + misp_info("[isp control led level]: %d", *(u8 *)param); + para_size = sizeof(u8); + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} +/************************** End Of File *******************************/ diff --git a/drivers/media/platform/altek/include/error.h b/drivers/media/platform/altek/include/error.h new file mode 100755 index 000000000000..c47f5e898f75 --- /dev/null +++ b/drivers/media/platform/altek/include/error.h @@ -0,0 +1,79 @@ +/* + * File: error.h + * Description: Error code base of modules + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/* + *@defgroup ErrorCode Error Code Definition + */ + +/** + *@file error.h + *@brief TBirdOS 2.0 module error code definition. + *Error code definition: + *Bits 31~20: Module id + *Bits 19~12: Reserved + *Bits 11~0: Error code defined in each module + *@author Gene Hung + *@version 2005/08/22; Gene; Add Doxygen remark + *@see ModuleID + *@ingroup ErrorCode Error Code Definition + */ + +/** + *@defgroup SysCtrlErr System Control Module Error Code + *@ingroup ErrorCode + */ + +/** + *@defgroup SysMgrErr System Manager Module Error Code + *@ingroup ErrorCode + */ + +#ifndef _ERROR_H_ +#define _ERROR_H_ + +#ifndef _MODULEID_H_ +#include "moduleid.h" +#endif +/** + *@ingroup ErrorCode + *@{ + */ +#define ERR_MODULEID_SHIFTBITS 20 +#define ERR_MODULEID(ErrorCode) ((ErrorCode) >> ERR_MODULEID_SHIFTBITS) +#define ERR_BASE(ModuleId) ((ModuleId) << ERR_MODULEID_SHIFTBITS) + +/* No error*/ +#define ERR_SUCCESS 0 + +/* The following constants define the module ID and the error code base*/ + +#define ERR_BASE_PROJECT ERR_BASE(MODULEID_PROJECT) + +/** + *@} + */ +#endif /*_ERROR_H_*/ + diff --git a/drivers/media/platform/altek/include/error/altek_state_err.h b/drivers/media/platform/altek/include/error/altek_state_err.h new file mode 100755 index 000000000000..7b433386a134 --- /dev/null +++ b/drivers/media/platform/altek/include/error/altek_state_err.h @@ -0,0 +1,39 @@ +/* + * File: altek_state_err.h + * Description: miniISPISP error definition + * + * Copyright 2019-2030 Altek Semiconductor Corporation + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _ALTEK_STATE_ERR_H_ +#define _ALTEK_STATE_ERR_H_ + +/******Include File******/ + +#include "../error_pj.h" + +/******Public Define******/ + +#define ERR_MINIISP_STATE_REDUNDANT_SEQUENCE \ + (ERR_BASE_PJ_MINIISP_STATE + 0x000) +#define ERR_MINIISP_STATE_ERROR_SEQUENCE \ + (ERR_BASE_PJ_MINIISP_STATE + 0x001) + +#endif diff --git a/drivers/media/platform/altek/include/error/ispctrl_if_master_err.h b/drivers/media/platform/altek/include/error/ispctrl_if_master_err.h new file mode 100755 index 000000000000..1f322a0da5d2 --- /dev/null +++ b/drivers/media/platform/altek/include/error/ispctrl_if_master_err.h @@ -0,0 +1,57 @@ +/** + * File: ispctrl_if_master_err.h + * Description: ISP Ctrl IF Master error definition + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/10/14; Aaron Chuang; Initial version + * 2013/12/05; Bruce Chung; 2nd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _ISPCTRLIFMASTER_ERR_H_ +#define _ISPCTRLIFMASTER_ERR_H_ + +/******Include File******/ + + +#include "../error_pj.h" + + +/******Public Define******/ +/* command Size mismatch*/ +#define ERR_MASTERCMDSIZE_MISMATCH (ERR_BASE_PJ_ISPCTRLIF_MASTER + 0x000) +/* null buffer*/ +#define ERR_MASTERCMDBUF_NULL (ERR_BASE_PJ_ISPCTRLIF_MASTER + 0x001) +/* command options unsupport*/ +#define ERR_MASTERCMDOPTION_UNSUPPORT (ERR_BASE_PJ_ISPCTRLIF_MASTER + 0x002) +/* open file error*/ +#define ERR_MASTERCMDCKSM_INVALID (ERR_BASE_PJ_ISPCTRLIF_MASTER + 0x003) +/* open file error*/ +#define ERR_MASTEROPENFILE_FAILED (ERR_BASE_PJ_ISPCTRLIF_MASTER + 0x004) +/* open file error*/ +#define ERR_MASTEROPENFILE_FILENAME_INVALID (ERR_BASE_PJ_ISPCTRLIF_MASTER+\ + 0x005) +/* event timeout*/ +#define ERR_MASTER_EVENT_TIMEOUT (ERR_BASE_PJ_ISPCTRLIF_MASTER + 0x006) + +/* opcode not supported*/ +#define ERR_MASTER_OPCODE_UNSUPPORT (ERR_BASE_PJ_ISPCTRLIF_MASTER + 0x007) + +#endif diff --git a/drivers/media/platform/altek/include/error/miniisp_err.h b/drivers/media/platform/altek/include/error/miniisp_err.h new file mode 100755 index 000000000000..f1fb5aef8f44 --- /dev/null +++ b/drivers/media/platform/altek/include/error/miniisp_err.h @@ -0,0 +1,38 @@ +/* + * File: miniisp_err.h + * Description: miniISPISP error definition + * + * Copyright 2019-2030 Altek Semiconductor Corporation + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _MINIISP_ERR_H_ +#define _MINIISP_ERR_H_ + +/******Include File******/ + +#include "../error_pj.h" + +/******Public Define******/ + +#define ERR_MINIISP_BUFFERSIZE_OVERFLOW (ERR_BASE_PJ_MINIISP + 0x000) +#define ERR_MINIISP_REQUESTFIRMWARE_FAILED (ERR_BASE_PJ_MINIISP + 0x001) +#define ERR_MINIISP_GETDATA_TIMEOUT (ERR_BASE_PJ_MINIISP + 0x002) + +#endif diff --git a/drivers/media/platform/altek/include/error_pj.h b/drivers/media/platform/altek/include/error_pj.h new file mode 100755 index 000000000000..c51781fc9d34 --- /dev/null +++ b/drivers/media/platform/altek/include/error_pj.h @@ -0,0 +1,45 @@ +/* + * File: error_pj.h + * Description: Error code base of modules + * + * Copyright 2019-2030 Altek Semiconductor Corporation + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +#ifndef _ERROR_PJ_H_ +#define _ERROR_PJ_H_ + +#include "error.h" +#include "moduleid_pj.h" + +/** + *@ingroup ErrorCode + *@{ + */ + +/* The following constants define the module ID and the error code base*/ +#define ERR_BASE_PJ_MINIISP_STATE ERR_BASE(MODULEID_PJ_MINIISP_STATE) +#define ERR_BASE_PJ_ISPCTRLIF_SLAVE ERR_BASE(MODULEID_PJ_ISPCTRLIF_SLAVE) +#define ERR_BASE_PJ_ISPCTRLIF_MASTER ERR_BASE(MODULEID_PJ_ISPCTRLIF_MASTER) +#define ERR_BASE_PJ_MINIISP ERR_BASE(MODULEID_PJ_MINIISP) + + + +#endif diff --git a/drivers/media/platform/altek/include/isp_camera_cmd.h b/drivers/media/platform/altek/include/isp_camera_cmd.h new file mode 100755 index 000000000000..b5de794dff70 --- /dev/null +++ b/drivers/media/platform/altek/include/isp_camera_cmd.h @@ -0,0 +1,698 @@ +/* + * File: isp_camera_cmd.h + * Description: The structure and API definition ISP camera command + * It is a header file that define structure and API for ISP camera command + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * History + * 2013/09/18; Aaron Chuang; Initial version + * 2013/12/05; Bruce Chung; 2nd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _ISPCAMERA_CMD_H_ +#define _ISPCAMERA_CMD_H_ + +/* + *@addtogroup ISPCameraCmd + *@{ + */ + +/******Include File******/ + + +#include "mtype.h" + + +/******Public Constant Definition******/ + +#define T_MEMSIZE (936*1024) +#define T_SPI_CMD_LENGTH 64 + +#define ISPCMD_DUMMYBYTES 4 +#define FWVER_INFOSIZE_MAX 34 + +#define ISPCMD_LENFLDBYTES 2 +#define ISPCMD_OPCODEBYTES 2 +#define ReportRegCount 27 +#define ISPCMD_CKSUMBYTES 2 + +/*length field size = 2, opcode field size = 2 */ +#define ISPCMD_CMDSIZE ((ISPCMD_LENFLDBYTES) + (ISPCMD_OPCODEBYTES)) + +/*length field size = 2, opcode field size = 2, dummy bytes = 4*/ +#define ISPCMD_CMDSIZEWDUMMY (ISPCMD_LENFLDBYTES+\ + ISPCMD_OPCODEBYTES+\ + ISPCMD_DUMMYBYTES) + +#define ISPCMD_FILENAME_SIZE 15 + +#define ISPCMD_EXEBIN_ADDRBYTES 4 +#define ISPCMD_EXEBIN_TOTALSIZEBYTES 4 +#define ISPCMD_EXEBIN_BLOCKSIZEBYTES 4 +#define ISPCMD_EXEBIN_CKSUMBYTES 4 +#define ISPCMD_EXEBIN_INFOBYTES (ISPCMD_EXEBIN_ADDRBYTES+\ + ISPCMD_EXEBIN_TOTALSIZEBYTES+\ + ISPCMD_EXEBIN_BLOCKSIZEBYTES+\ + ISPCMD_EXEBIN_CKSUMBYTES) + +/* Definition for Error code array number*/ +#define MAX_RECERRORCODE_NUM 10 + +/*log buffer size*/ +#define LEVEL_LOG_BUFFER_SIZE (1024*4) + + + +/*calibration profile*/ +#define ISPCMD_CAMERA_SET_SENSORMODE 0x300A +#define ISPCMD_CAMERA_GET_SENSORMODE 0x300B +#define ISPCMD_CAMERA_SET_OUTPUTFORMAT 0x300D +#define ISPCMD_CAMERA_SET_CP_MODE 0x300E +#define ISPCMD_CAMERA_SET_AE_STATISTICS 0x300F +#define ISPCMD_CAMERA_PREVIEWSTREAMONOFF 0x3010 +#define ISPCMD_CAMERA_DUALPDYCALCULATIONWEIGHT 0x3011 +#define ISPCMD_LED_POWERCONTROL 0x3012 +#define ISPCMD_CAMERA_ACTIVE_AE 0x3013 +#define ISPCMD_ISP_AECONTROLONOFF 0x3014 +#define ISPCMD_CAMERA_SET_FRAMERATELIMITS 0x3015 +#define ISPCMD_CAMERA_SET_PERIODDROPFRAME 0x3016 +#define ISPCMD_CAMERA_SET_MAX_EXPOSURE 0x3017 +#define ISPCMD_CAMERA_SET_AE_TARGET_MEAN 0x3018 +#define ISPCMD_CAMERA_FRAME_SYNC_CONTROL 0x3019 +#define ISPCMD_CAMERA_SET_SHOT_MODE 0x301A +#define ISPCMD_CAMERA_LIGHTING_CTRL 0x301B +#define ISPCMD_CAMERA_DEPTH_COMPENSATION 0x301C +#define ISPCMD_CAMERA_TRIGGER_DEPTH_PROCESS_CTRL 0x301D +#define ISPCMD_CAMERA_SET_MIN_EXPOSURE 0x301E +#define ISPCMD_CAMERA_SET_MAX_EXPOSURE_SLOPE 0x301F +#define ISPCMD_CAMERA_SET_LED_ACTIVE_DELAY 0x3020 +#define ISPCMD_CAMERA_ISPLEDLEVELCONTROLONOFF 0x3021 + +/* Bulk Data*/ +#define ISPCMD_BULK_WRITE_BASICCODE 0x2002 +#define ISPCMD_BULK_WRITE_BASICCODE_CODEADDR 0x2003 +#define ISPCMD_BULK_WRITE_BASICCODE_CODESIZE 0x2004 +#define ISPCMD_BULK_WRITE_BASICCODE_CODESUM 0x2005 +#define ISPCMD_BULK_READ_CALIBRATION_DATA 0x2007 +#define ISPCMD_BULK_WRITE_BOOTCODE 0x2008 +#define ISPCMD_BULK_WRITE_BOOTCODE_SHORT_LEN 0x2009 +#define ISPCMD_BULK_READ_MEMORY 0x2101 +#define ISPCMD_BULK_READ_COMLOG 0x2102 +#define ISPCMD_BULK_WRITE_CALIBRATION_DATA 0x210B +#define ISPCMD_BULK_WRITE_DEPTH_RECTAB_INVRECT 0x210C +#define ISPCMD_BULK_WRITE_CALIBRATION_NO_BLOCK 0x210D +#define ISPCMD_BULK_WRITE_SPINOR_DATA 0x210E + +/*basic setting*/ +#define ISPCMD_BASIC_SET_DEPTH_3A_INFO 0x10B9 +#define ISPCMD_BASIC_SET_DEPTH_AUTO_INTERLEAVE_MODE 0x10BC +#define ISPCMD_BASIC_SET_INTERLEAVE_MODE_DEPTH_TYPE 0x10BD +#define ISPCMD_BASIC_SET_DEPTH_POLISH_LEVEL 0x10BE +#define ISPCMD_BASIC_SET_EXPOSURE_PARAM 0x10BF +#define ISPCMD_BASIC_SET_DEPTH_STREAM_SIZE 0x10C0 +/*system cmd*/ +#define ISPCMD_SYSTEM_GET_STATUSOFLASTEXECUTEDCOMMAND 0x0015 +#define ISPCMD_SYSTEM_GET_ERRORCODE 0x0016 +#define ISPCMD_SYSTEM_SET_ISPREGISTER 0x0100 +#define ISPCMD_SYSTEM_GET_ISPREGISTER 0x0101 +/*#define ISPCMD_SYSTEM_SET_DEBUGCMD 0x0104*/ +#define ISPCMD_SYSTEM_SET_COMLOGLEVEL 0x0109 +#define ISPCMD_SYSTEM_GET_CHIPTESTREPORT 0x010A +#define ISPCMD_SYSTEM_GET_CHIP_THERMAL 0x0115 + +/*operarion code*/ +#define ISPCMD_MINIISPOPEN 0x4000 + +/* constants for memory dump mode*/ +#define T_MEMDUMP_CPURUN 0 +#define T_MEMDUMP_CPUHALT 1 + +#define EEPROM_BUFFER_ADDRESS 0x00000000 +#define EEPROM_BUFFER_SIZE 0x4000 +/******Public Type Declaration******/ +/*mode id*/ +/*define for ISP decide mode*/ +enum mini_isp_mode { + MINI_ISP_MODE_NORMAL = 0x0000, + MINI_ISP_MODE_E2A = 0x0001, + MINI_ISP_MODE_A2E = 0x0002, + MINI_ISP_MODE_LEAVE_BYPASS = 0x0003, + MINI_ISP_MODE_GET_CHIP_ID = 0x0004, + MINI_ISP_MODE_SET_CP_MODE = 0x0005, + MINI_ISP_MODE_LEAVE_CP_MODE = 0x0006, + MINI_ISP_MODE_CHIP_INIT = 0x0007, + MINI_ISP_MODE_BYPASS = 0x1000, + MINI_ISP_MODE_QUARTER_BYPASS = 0x1001, +}; + +#pragma pack(push, 1) +#pragma pack(1) +struct transferdata { + u16 opcode; + void *data; +}; + +/*camera profile cmd use structure*/ +/** + *@struct isp_cmd_set_sensor_mode(opcode:300A) + *@brief ISP master cmd for set sensor mode + *\param sensor_on_off [In],sensor on/off + *\param scenario_id[In], Scenario ID + *\param mipi_tx_skew_enable[In], mipi tx skew on(1)/off(0) + *\param ae_weighting_table_index[In] + *\param merge_mode_enable[In] + *\ bit[0:3] : + *\ set 0 for normal mode + *\ set 1 for merge mode, only for image samller than 640X480 case + *\ set 2 for depth test pattern mode + *\ bit[4] : + *\ set 0 for turn on sensor by AP. + *\ set 1 for turn on sensor by AL6100. + *\ bit[5] : + *\ set 0 for disable time stamp function. + *\ set 1 for enable time stamp function. + *\ Time stamp data will be put after ir raw data. + *\ Besides, the original metadata will be cancelled. + */ +#pragma pack(1) +struct isp_cmd_set_sensor_mode { + u8 sensor_on_off; + u8 scenario_id; + u8 mipi_tx_skew; + u8 ae_weighting_table_index; + u8 merge_mode_enable; + u8 reserve[2]; +}; + +/** + *@struct isp_cmd_get_sensor_mode(opcode:300B) + *@brief ISP master cmd for get sensor mode + */ +#pragma pack(1) +struct isp_cmd_get_sensor_mode { + bool on; /* On/off flag*/ + u8 scenario_id; /* scenario mode*/ + u8 reserve[4]; +}; + +/** + *@struct isp_cmd_set_output_format(opcode:300D) + *@brief ISP master cmd for set depth output format + + depth_size[In]depth_map_setting = resolution | opereation_mode + resolution + 0: Disable depth function (Depth engine is disable) + 1: 180p + 2: 360p + 3: 720p + 4: 480p + opereation_mode, + 0x00: DEPTH_BIT_DG_ONLY + 0x10: DEPTH_BIT_DP + 0x40: DEPTH_BIT_HIGH_DISTORTION_RATE + + reserve[0] [In]depth_process_type_and_qlevel = process_type | quality level + B[0:2] process_type: value 0x6 as reserve + B[3:6] quality level: 0 ~ 15 + + reserve[1] [In] + B[0:0] InvRect bypass: set 1 for enable InvRect bypass. set 0 disable. + return Error code + */ +#pragma pack(1) +struct isp_cmd_set_output_format { + u8 depth_size; + u8 reserve[2]; +}; + +/** + *@struct isp_cmd_ae_statistics(opcode:300F) + *@brief ae statistics + *\gr_channel_weight (0~65535) + *\gb_channel_weight (0~65535) + *\r_channel_weight (0~65535) + *\b_channel_weight (0~65535) + *\shift_bits (0 ~ 15, 0 means no shift) + */ +#pragma pack(1) +struct isp_cmd_ae_statistics { + u16 gr_channel_weight; + u16 gb_channel_weight; + u16 r_channel_weight; + u16 b_channel_weight; + u8 shift_bits; +}; + +/** + *@struct isp_cmd_preview_stream_on_off(opcode:3010) + *@briefISP master cmd for control tx stream on or off + */ +#pragma pack(1) +struct isp_cmd_preview_stream_on_off { + u8 tx0_stream_on_off; + u8 tx1_stream_on_off; + u8 reserve; +}; + +/** + *@struct isp_cmd_dual_pd_y_calculation_weightings(opcode:3011) + *@briefISP master cmd for control dual pd y calculation weightings + */ +#pragma pack(1) +struct isp_cmd_dual_pd_y_calculation_weightings { + u8 y_weight_gr_short; + u8 y_weight_gr_long; + u8 y_weight_r_short; + u8 y_weight_r_long; + u8 y_weight_b_short; + u8 y_weight_b_long; + u8 y_weight_gb_short; + u8 y_weight_gb_long; + u8 y_sum_right_shift; +}; + +/** + *@struct isp_cmd_led_power_control(opcode:3012) + *@briefISP master cmd for control led power + * u8 led_on_off: + * 0: off + * 1: always on + * 2: AP control pulse mode + * 3: AHCC control pulse mode + * u8 led_power_level: (0~255) + * u8 control_projector_id: + * 0: projector + * 1:illuminator + * u32 delay_after_sof, + * when led_on_off = 2, use this param to set delay time + * between SOF and start pulse time + * u32 pulse_time: + * when led_on_off = 2, use this param to set pulse time + * u8 control_mode: + * when led_on_off = 2, + * use this param to decide if pulse time + * met next SOF need triggler imediately or not + * u8 reserved: + * reserved; always set to 0 + * u8 rolling_shutter: + * when led_on_off = 3, use this param to let + * projector/illuminator konw hoe exposure deal + */ +#pragma pack(1) +struct isp_cmd_led_power_control { + u8 led_on_off; + u8 led_power_level; + u8 control_projector_id; + u32 delay_after_sof; + u32 pulse_time; + u8 control_mode; + u8 reserved; + u8 rolling_shutter; +}; + +/** + *@struct isp_cmd_active_ae(opcode:3013) + *@briefISP master cmd for avtive AE + */ +#pragma pack(1) +struct isp_cmd_active_ae { + u8 active_ae; + u16 f_number_x1000; +}; + +/** + *@struct isp_cmd_isp_ae_control_on_off(opcode:3014) + *@briefISP master cmd for isp AE control on off + */ +#pragma pack(1) +struct isp_cmd_isp_ae_control_on_off { + u8 isp_ae_control_mode_on_off; +}; + + +/** + *@struct isp_cmd_frame_rate_limits(opcode:3015) + *@brief set frame rate limits + */ +#pragma pack(1) +struct isp_cmd_frame_rate_limits { + u16 main_min_framerate_x100; + u16 main_max_framerate_x100; + u16 sub_min_framerate_x100; + u16 sub_max_framerate_x100; +}; + +/** + *@struct isp_cmd_period_drop_frame(opcode:3016) + *@brief set period drop frame + */ +#pragma pack(1) +struct isp_cmd_period_drop_frame { + u8 period_drop_type;/* 0: no drop, 1: drop active, 2; drop passive */ +}; + +/** + *@struct isp_cmd_target_mean(opcode:3018) + *@brief set target mean + */ +#pragma pack(1) +struct isp_cmd_target_mean { + u16 target_mean;/* 0~255 */ + u8 ucActiveDevice; +}; + +#pragma pack(1) +struct isp_cmd_frame_sync_control { + u8 control_deviceID; /* bit 0~3: Device ID */ + /* 0: OutDevice_0, 1: OutDevice_1. */ + /* Device name is based on project definition */ + /* bit 4~7: Reference signal source */ + /* 0: Dual sensor sync, 1: GPI */ + u8 delay_framephase; /* Unit: frame number */ + u8 active_framephase; /* Unit: frame number */ + u8 deactive_framephase; /* Unit: frame number */ + u8 active_timelevel; /* bit 0~3 : Active time level */ + /* 0: one frame; others : value*100(us), range (1~10) */ + /* bit 4~7: mode setting */ + /* 0: normal mode 1: always off mode 2: always on mode */ + u8 reserve[3]; +}; + + +/* +Param: shot_mode => value 0: Manual, value 1: Auto + N fps +Param: frame_rate => Please set frame rate when shot mode is Auto + N fps +*/ +#pragma pack(1) +struct isp_cmd_set_shot_mode { + u8 shot_mode; + u16 frame_rate; /* corresponding frame rate; Ex. 3002 = 30.02 fps */ + u8 reserve[1]; +}; + +/* +*/ +#pragma pack(1) +struct isp_cmd_lighting_ctrl { + u32 cycle_len; /* effective length in cycle[] */ + struct { + u8 source; + /* source of lighting (bit-map) */ + /* 0 means none */ + /* bit 0 represents an IR Project */ + /* bit 1 represents a Flood Illuminator */ + u8 TxDrop; + /* mipi tx drop control (bit-map) */ + /* 0 means mipi tx0 and mipi tx1 output */ + /* bit 0 represents mipi tx0 drop */ + /* bit 1 represents mipi tx1 drop */ + u16 co_frame_rate; + /* corresponding frame rate; Ex. 3002 = 30.02 fps */ + /* 0 means the same as sensor */ + } cycle[8]; +}; + +/*basic cmd use structure*/ + +/** + *@struct isp_cmd_depth_3a_info(opcode:10B9) + *@brief depth 3A information + */ +#pragma pack(1) +struct isp_cmd_depth_3a_info { + u16 hdr_ratio; + u32 main_cam_exp_time; + u16 main_cam_exp_gain; + u16 main_cam_amb_r_gain; + u16 main_cam_amb_g_gain; + u16 main_cam_amb_b_gain; + u16 main_cam_iso; + u16 main_cam_bv; + s16 main_cam_vcm_position; + u8 main_cam_vcm_status; + u32 sub_cam_exp_time; + u16 sub_cam_exp_gain; + u16 sub_cam_amb_r_gain; + u16 sub_cam_amb_g_gain; + u16 sub_cam_amb_b_gain; + u16 sub_cam_iso; + u16 sub_cam_bv; + s16 sub_cam_vcm_position; + u8 sub_cam_vcm_status; + u16 main_cam_isp_d_gain; + u16 sub_cam_isp_d_gain; + s16 hdr_long_exp_ev_x1000; + s16 hdr_short_exp_ev_x1000; + u16 ghost_prevent_low; + u16 ghost_prevent_high; + u8 depth_proc_mode; +}; + +/** + *@struct isp_cmd_depth_auto_interleave_param(opcode:10BC) + *@brief depth Interleave mode param + */ +#pragma pack(1) +struct isp_cmd_depth_auto_interleave_param { + u8 depth_interleave_mode_on_off;/*1: on, 0: off*/ + u8 skip_frame_num_after_illuminator_pulse; + u8 projector_power_level;/*0~255*/ + u8 illuminator_power_level;/*0~255*/ +}; + +/** + *@struct isp_cmd_interleave_mode_depth_type(opcode:10BD) + *@brief interleave mode projector with depth type + */ +#pragma pack(1) +struct isp_cmd_interleave_mode_depth_type { + u8 projector_interleave_mode_with_depth_type; + /*1: passive, 0: active, default active*/ +}; + +/** + *@struct isp_cmd_depth_polish_level(opcode:10BE) + *@brief set depth polish level + */ +#pragma pack(1) +struct isp_cmd_depth_polish_level { + u8 depth_polish_level;/*0~100*/ +}; + +/** + *@struct isp_cmd_exposure_param(opcode:10BF) + *@brief set exposure param + */ +#pragma pack(1) +struct isp_cmd_exposure_param { + u32 udExpTime;/*unit:us*/ + u16 uwISO; + u8 ucActiveDevice; +}; + +/** + *@struct isp_cmd_depth_stream_size(opcode:10C0) + *@brief set depth stream size + */ +#pragma pack(1) +struct isp_cmd_depth_stream_size { + u8 depth_stream_size;/*0 : normal, 1: Binning x2*/ +}; + +/*system cmd use structure*/ + +/* ISP operation mode*/ +enum ispctrl_operation_mode { + ISPCTRL_TEST_MODE, + ISPCTRL_STILLLV_MODE, + ISPCTRL_VIDEOLV_MODE, + ISPCTRL_CONCURRENT_MODE, + ISPCTRL_BYPASS_MODE, + ISPCTRL_POWERDOWN_MODE +}; + +/** + *@struct system_cmd_isp_mode(opcode:0010 and 0011) + *@brief depth 3A information + */ +#pragma pack(1) +struct system_cmd_isp_mode { + u8 isp_mode; /*ispctrl_operation_mode*/ +}; + +/** + *@struct system_cmd_status_of_last_command(opcode:0015) + *@brief last execution command status + */ +#pragma pack(1) +struct system_cmd_status_of_last_command { + u16 opcode; + u32 execution_status; +}; + +/** + *@struct system_cmd_isp_register(opcode:0100 and 0101) + *@brief use on set/get isp register + */ +#pragma pack(1) +struct system_cmd_isp_register { + u32 address; + u32 value; +}; + +/** + *@struct system_cmd_debug_mode(opcode:0104) + *@brief use on get irq status + */ +#pragma pack(1) +struct system_cmd_debug_mode { + u8 on; +}; + +/** + *@struct system_cmd_common_log_level(opcode:0109) + *@brief use on set common log level + */ +#pragma pack(1) +struct system_cmd_common_log_level { + u32 log_level; +}; + + + +/*bulk cmd use structure*/ + +/** + *@struct memmory_dump_hdr_info + *@brief use on isp memory read + */ +#pragma pack(1) +struct memmory_dump_hdr_info { + u32 start_addr; + u32 total_size; + u32 block_size; + u32 dump_mode; +}; + + +/** + *@struct common_log_hdr_info + *@brief Bulk data for memory dump header + */ +#pragma pack(1) +struct common_log_hdr_info { + u32 total_size; + u32 block_size; +}; + +struct depthflowmgrpv_dgmgr_recta_quality_param { + u32 recta_quality_rect_core_sel_param; + u32 recta_quality_rect_ldc_param[43]; + u32 recta_quality_rect_hgh_param[9]; + u32 recta_quality_rect_bilinear_param; +}; + +struct depthflowmgrpv_dgmgr_rectb_quality_param { + u32 rectb_quality_rect_core_sel_param; + u32 rectb_quality_rect_ldc_param[43]; + u32 rectb_quality_rect_hgh_param[9]; + u32 rectb_quality_rect_bilinear_param; +}; + +struct depthflowmgrpv_invrectmgr_quality_param { + u32 recta_quality_irect_core_sel_param; + u32 recta_quality_irect_ldc_param[43]; + u32 recta_quality_irect_hgh_param[9]; + u32 recta_quality_irect_bilinear_param; + u32 rectb_quality_irect_bilinear_param; +}; + +/** + *@struct depth_rectab_invrect_param(opcode:0x210C) + *@brief depth rect A, B, INV rect parameter structure + */ +#pragma pack(1) +struct depth_rectab_invrect_param { + struct depthflowmgrpv_dgmgr_recta_quality_param depth_recta_quality; + struct depthflowmgrpv_dgmgr_rectb_quality_param depth_rectb_quality; + struct depthflowmgrpv_invrectmgr_quality_param depth_invrect_quality; +}; + +/** + *@struct isp_cmd_depth_rectab_invrect_info(opcode:0x210C) + *@brief depth rect A, B, INV rect buffer address + */ +#pragma pack(1) +struct isp_cmd_depth_rectab_invrect_info { + struct depth_rectab_invrect_param rect_param[3]; + u8 trans_mode; + u32 block_size; +}; + +/** + *@struct isp_cmd_depth_compensation_param(opcode:0x301C) + *@brief depth compensation param + */ +#pragma pack(1) +struct isp_cmd_depth_compensation_param { + u8 en_updated; + u16 short_distance_value; + s8 compensation; + u8 reserve[4]; +}; + +/** +@struct isp_cmd_cycle_trigger_depth_process +@brief cycle trigger depth process +*/ +#pragma pack(1) +struct isp_cmd_cycle_trigger_depth_process { + u8 cycleLen; + /* effective length in cycle[], Range: 1~16 frames one cycle*/ + u16 depth_triggerBitField; + /* bit 0 : 1st frame, bit 1 : 2nd frame, ... */ + u16 depthoutput_triggerBitField; + /* bit 0 : 1st frame, bit 1 : 2nd frame, ... */ + /* 0 : Not trigger, 1: Trigger */ + u8 Reserved[3]; +}; + +/** +@struct isp_cmd_max_exposure_slope +@brief set max exposure slope +*/ +#pragma pack(1) +struct isp_cmd_max_exposure_slope { + u32 max_exposure_slope; + u8 ucActiveDevice; + u8 Reserved[3]; +}; + +/******Public Function Prototype******/ + +#pragma pack(pop) +/******End of File******/ + +/** + *@} + */ + +#endif /* _ISPCAMERA_CMD_H_*/ diff --git a/drivers/media/platform/altek/include/ispctrl_if_master.h b/drivers/media/platform/altek/include/ispctrl_if_master.h new file mode 100755 index 000000000000..eba22d762d30 --- /dev/null +++ b/drivers/media/platform/altek/include/ispctrl_if_master.h @@ -0,0 +1,194 @@ +/* + * File: ispctrl_if_master.h + * Description: The structure and API definition ISP Ctrl IF Master + * It,s a header file that define structure and API for ISP Ctrl IF Master + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/09/18; Aaron Chuang; Initial version + * 2013/12/05; Bruce Chung; 2nd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +/** + * \file ispctrl_if_master.h + * \brief ISP Ctrl IF Master and API define + * \version 0.01 + * \author Aaron Chuang + * \date 2013/09/17 + * \see ispctrl_if_master.h + */ + +#ifndef _ISPCTRLIF_MASTER_H_ +#define _ISPCTRLIF_MASTER_H_ + +/** + *@addtogroup ispctrl_if_master + *@{ + */ + +/******Include File******/ +#include + +#include "mtype.h" +#include "moduleid_pj.h" +#include "miniisp.h" + +/******Public Constant Definition******/ + +enum firmware_type { + BOOT_CODE, + BASIC_CODE, + ADVANCED_CODE, + SCENARIO_CODE, + HDR_CODE, + IRP0_CODE, + IRP1_CODE, + PPMAP_CODE, + DEPTH_CODE, + FIRMWARE_MAX +}; + +extern int g_isMiniISP_sendboot; + + + +/******Public Type Declaration******/ + + +/******Public Function Prototype******/ + + +/** + *\brief Execute master command + *\param opcode [In], Op code + *\param param [In], CMD param buffer + *\return Error code + */ +extern errcode ispctrl_if_mast_execute_cmd(u16 opcode, u8 *param); + +/** + *\brief Send command to slave + *\param devdata [In], misp_data + *\param opcode [In], Op code + *\param param [In], CMD param buffer + *\param len [In], CMD param size + *\return Error code + */ +errcode ispctrl_mast_send_cmd_to_slave(void *devdata, + u16 opcode, + u8 *param, + u32 len); + +/** + *\brief Receive response from slave + *\param devdata [In], misp_data + *\param param [Out], Response buffer + *\param len [Out], Response size + *\return Error code + */ +errcode ispctrl_mast_recv_response_from_slave(void *devdata, + u8 *param, + u32 len, + bool wait_int); + +/** + *\brief Receive Memory data from slave + *\param devdata [In], misp_data + *\param response_buf [Out], Response buffer + *\param response_size [Out], Response size + *\param wait_int [In], waiting INT flag + *\return Error code + */ +errcode ispctrl_if_mast_recv_memory_data_from_slave( + void *devdata, + u8 *response_buf, + u32 *response_size, + u32 block_size, + bool wait_int); + +#if ENABLE_LINUX_FW_LOADER +/** \brief Master send bulk (large data) to slave + *\param devdata [In], misp_data + *\param buffer [In], Data buffer to be sent, address 8-byte alignment + *\param filp [In], file pointer, used to read the file and send the data + *\param total_size [In], file size + *\param block_size [In], transfer buffer block size + *\param is_raw [In], true: mini boot code false: other files + *\return Error code + */ +errcode ispctrl_if_mast_send_bulk(void *devdata, const u8 *buffer, + u32 total_size, + u32 block_size, bool is_raw); + +#else +/** \brief Master send bulk (large data) to slave + *\param devdata [In], misp_data + *\param buffer [In], Data buffer to be sent, address 8-byte alignment + *\param filp [In], file pointer, used to read the file and send the data + *\param total_size [In], file size + *\param block_size [In], transfer buffer block size + *\param is_raw [In], true: mini boot code false: other files + *\return Error code + */ +errcode ispctrl_if_mast_send_bulk(void *devdata, u8 *buffer, + struct file *filp, u32 total_size, + u32 block_size, bool is_raw); +#endif +/** \brief Master open the firmware + *\param filename [In], file name of the firmware + *\param firmwaretype [In], firmware type + *\return Error code + */ +errcode ispctrl_if_mast_request_firmware(u8 *filename, u8 a_firmwaretype); + +/** \brief Master get SPI status bytes + *\param n/a + *\return status bytes(2 bytes) + */ +u16 ispctrl_if_mast_read_spi_status(void); + +/** + *\brief Receive ISP register response from slave + *\param devdata [In] misp_data + *\param response_buf [Out], Response buffer + *\param response_size [Out], Response size + *\param total_count [In], Total reg count + *\return Error code + */ +errcode ispctrl_if_mast_recv_isp_register_response_from_slave( + void *devdata, + u8 *response_buf, + u32 *response_size, + u32 total_count); + +/** + *\brief Initial purpose + *\param None + *\return Error code + */ +void isp_mast_camera_profile_para_init(void); + +/****** End of File******/ + +/** + *@} + */ + +#endif /* _ISPCTRLIF_MASTER_H_*/ diff --git a/drivers/media/platform/altek/include/ispctrl_if_master_local.h b/drivers/media/platform/altek/include/ispctrl_if_master_local.h new file mode 100755 index 000000000000..a263114b29fb --- /dev/null +++ b/drivers/media/platform/altek/include/ispctrl_if_master_local.h @@ -0,0 +1,668 @@ +/* + * File: ispctrl_if_master_local.h + * Description: The structure and API definition ISP Ctrl IF Master Local + * It,s a header file that define structure and API for ISP Ctrl IF Master Local + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/10/14; Aaron Chuang; Initial version + * 2013/12/05; Bruce Chung; 2nd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +/** + * \file ispctrl_if_master_local.h + * \brief ISP Ctrl IF Master Local and API define + * \version 0.01 + * \author Aaron Chuang + * \date 2013/09/23 + * \see ispctrl_if_master_local.h + */ + +#ifndef _ISPCTRLIF_MASTER_LOCAL_H_ +#define _ISPCTRLIF_MASTER_LOCAL_H_ + +/** + *@addtogroup ispctrl_if_master_local + *@{ + */ + + +/******Include File******/ + +#include "mtype.h" +#include "miniisp.h" + + +/******Public Constant Definition******/ +#define ISP_REGISTER_PARA_SIZE 8 +#define ISP_REGISTER_VALUE 4 + + +/******Public Function Prototype******/ + +/*********************** System manage command ***********************/ +/** + *\brief Get status of last executed command + *\param devdata [In], misp device data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_get_status_of_last_exec_command( + void *devdata, + u16 opcode, u8 *param); + +/** + *\brief Get error code CMD + *\param devdata [In], misp device data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_get_error_code_command(void *devdata, + u16 opcode, + u8 *param); + +/** + *\brief Set ISP register + *\param devdata [In], misp device data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_set_isp_register(void *devdata, + u16 opcode, + u8 *param); + +/** + *\brief Get ISP register + *\param devdata [In], misp device data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_get_isp_register(void *devdata, + u16 opcode, + u8 *param); + +/** + *\brief Set common log level + *\param devdata [In], misp device data + *\param opcode [In], Operation code + *\param param [In], CMD param + + *\return Error code + */ +errcode mast_sys_manage_cmd_set_comomn_log_level(void *devdata, + u16 opcode, + u8 *param); + +/** + *\brief Get chip test report + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_get_chip_test_report(void *devdata, + u16 opcode, + u8 *param); + +/** + *\brief Get chip isp thermal + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_get_chip_thermal(void *devdata, + u16 opcode, + u8 *param); + + +/*********************** Camera profile command ***********************/ +/** + *\brief Set Sensor Mode + *\param devdata [In], misp device data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_sensor_mode(void *devdata, + u16 opcode, + u8 *param); + +/** + *\brief Get Sensor Mode + *\param devdata [In], misp device data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_get_sensor_mode(void *devdata, + u16 opcode, + u8 *param); + +/** + *\brief Set Output Format + *\param devdata [In], misp device data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_output_format(void *devdata, + u16 opcode, + u8 *param); + +/* + *\brief Set CP Mode + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_cp_mode(void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set AE statistics + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_ae_statistics(void *devdata, + u16 opcode, u8 *param); + +/** + *\brief Preview stream on + *\param devdata [In], misp device data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_preview_stream_on_off( + void *devdata, + u16 opcode, + u8 *param); + +/* + *\brief dual PD Y calculation weightings + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_dual_pd_y_cauculation_weightings( + void *devdata, + u16 opcode, u8 *param); + + +/* + *\brief led power control + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_led_power_control( + void *devdata, + u16 opcode, u8 *param); + + +/* + *\brief Active AE + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_active_ae( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief ISP AE control on off + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_isp_ae_control_on_off( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set Frame Rate Limits + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_frame_rate_limits( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set Period Drop Frame + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_period_drop_frame( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set max exposure + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_max_exposure( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set target mean + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_target_mean( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Frame sync control + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_frame_sync_control( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set shot mode + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_shot_mode( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Lighting control + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_lighting_ctrl( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set min exposure + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_min_exposure( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set Max exposure slope + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_max_exposure_slope( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set depth compensation + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_depth_compensation( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set cycle trigger depth process + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_cycle_trigger_depth( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Set led active delay time + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_set_led_active_delay( + void *devdata, + u16 opcode, u8 *param); + + +/* + *\brief Set isp control led level + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_camera_profile_cmd_isp_control_led_level( + void *devdata, + u16 opcode, u8 *param); + +/* + *\brief Get isp thermal + *\param None + *\return Error code + */ +errcode mast_camera_profile_cmd_get_chip_thermal( + void *devdata, + u16 opcode, u8 *param); + + +/* Bulk data command*/ +#if ENABLE_LINUX_FW_LOADER +/** + *\brief Write Boot Code + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], boot file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_boot_code(void *devdata, + u8 *param); + + +/** + *\brief Write Boot Code (Short SPI CMD) + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], boot file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_boot_code_shortlen( + void *devdata, u8 *param); + +/** + *\brief Write Basic Code + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], basic file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_basic_code(void *devdata, + u8 *param); + +/** + *\brief Write Basic Code + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], basic file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_basic_code_shortlen(void *devdata, + u8 *param); + +/** + *\brief Write Calibration Data + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], sc table file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_calibration_data(void *devdata, + u8 *param); + +#else +/** + *\brief Write Boot Code + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], boot file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_boot_code(void *devdata, + u8 *param, + struct file *filp); + + +/** + *\brief Write Boot Code (Short SPI CMD) + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], boot file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_boot_code_shortlen(void *devdata, + u8 *param, + struct file *filp); + +/** + *\brief Write Basic Code + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], basic file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_basic_code(void *devdata, + u8 *param, + struct file *filp); + +/** + *\brief Write Basic Code + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], basic file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_basic_code_shortlen(void *devdata, + u8 *param, + struct file *filp); + +/** + *\brief Write Calibration Data + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], sc table file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_calibration_data(void *devdata, + u8 *param, + struct file *filp); +#endif + +/** + *\brief Write Qmerge Data + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], sc table file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_qmerge_data(void *devdata, + u8 *param, + struct file *filp); + +/** + *\brief Read Calibration Data + *\param devdata [In], misp device data + *\param param [In], CMD param + *\return Error code + */ +errcode mast_bulk_data_cmd_read_calibration_data(void *devdata, + u8 *param); + +/** + *\brief Read Memory Data + *\param devdata [In], misp device data + *\param param [In], CMD param + *\return Error code + */ +errcode mast_bulk_data_cmd_read_memory_data(void *devdata, + u8 *param); + +/** + *\brief Read common log data + *\param devdata [In], misp device data + *\param param [In], CMD param + *\return Error code + */ +errcode bulk_data_cmd_read_common_log(void *devdata, + u8 *param); + +/* + *\brief Read depth Rect A, B, Invrect + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_bulk_data_cmd_write_depth_rectab_invrect( + void *devdata, u16 opcode, u8 *param); + +#if ENABLE_LINUX_FW_LOADER +/** + *\brief Write Spinor Data + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], source file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_spinor_data(void *devdata, + u8 *param); + +#else +/** + *\brief Write Spinor Data + *\param devdata [In], misp device data + *\param param [In], CMD param + *\param filp [In], source file + *\return Error code + */ +errcode mast_bulk_data_cmd_write_spinor_data(void *devdata, + u8 *param, struct file *filp); +#endif +/*********************** Basic setting command ************************/ +/** + *\brief Set Depth 3A Info + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_depth_3a_info(void *devdata, + u16 opcode, + u8 *param); + + +/* + *\brief Set Depth auto interleave mode + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_depth_auto_interleave_mode( + void *devdata, u16 opcode, u8 *param); + + +/* + *\brief Set projector interleave mode with depth type + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_interleave_mode_depth_type( + void *devdata, u16 opcode, u8 *param); + +/* + *\brief Set depth polish level + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_depth_polish_level( + void *devdata, u16 opcode, u8 *param); + +/* + *\brief Set exposure param + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_exposure_param( + void *devdata, u16 opcode, u8 *param); + +/* + *\brief Set depth stream size + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_basic_setting_cmd_set_depth_stream_size( + void *devdata, u16 opcode, u8 *param); +/*********************** operation command ***********************/ +/** + *\brief Mini ISP open + *\param devdata [In], misp device data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_operation_cmd_miniisp_open( + void *devdata, u16 opcode, char *FileNametbl[]); + + +/****************************** End of File *********************************/ + +/** + *@} + */ + +#endif /* _ISPCTRLIF_MASTER_LOCAL_H_*/ diff --git a/drivers/media/platform/altek/include/miniisp.h b/drivers/media/platform/altek/include/miniisp.h new file mode 100755 index 000000000000..8f8e66179292 --- /dev/null +++ b/drivers/media/platform/altek/include/miniisp.h @@ -0,0 +1,348 @@ +/* + * File: miniisp.h + * Description: Mini ISP sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/11/01; Bruce Chung; Initial version + * 2017/03/30; LouisWang; 2rd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _MINI_ISP_H_ +#define _MINI_ISP_H_ + +/******Include File******/ +#include +#include +#include +#include +#include +#include +#include + +#include "mtype.h" +/******Public Constant Definition******/ + +#define MINIISP_DRIVER_VERSION "v1.48.A4" + +/* SPI_E_AND_I2C_SLAVE_RELATED */ +#define CTRL_BYTE_REGRD (0x19) +#define CTRL_BYTE_REGWR (0x09) +#define CTRL_BYTE_MEMRD (0x15) +#define CTRL_BYTE_MEMWR (0x05) +/* SPI_E CMD */ +#define CTRL_BYTE_REGRD_W (0x81) +#define CTRL_BYTE_MEMRD_W (0x82) +#define CTRL_BYTE_GETDATA_W (0x83) + +#define EMODE_TXCMD_LEN (5) /*1byte ctrl byte + 4 bytes address*/ + +#define EN_SPIE_REG_DUMMY_BYTE 1 +#if EN_SPIE_REG_DUMMY_BYTE + #define SPIE_RX_REG_DUMMY_LEN (16) + #define SPIE_RX_MEM_DUMMY_LEN (70) +#else + #define SPIE_RX_DUMMY_LEN (32) +#endif + +/*SPI_A_MODE_RELATED*/ +#define CTRL_BYTE_A2E 0x20 +#define SPI_TX_BULK_SIZE (64 * 1024) +#define SPI_TX_BULK_SIZE_BOOT (8 * 1024) + +/*I2C_TOP_RELATED*/ +/*#define I2C_BULK_SIZE (4 * 1024) *//* AQ360 can work */ +#define I2C_TX_BULK_SIZE (1024) /*AL6100 can work*/ +#define I2C_RX_DUMMY_LEN (0) + +#define TX_BUF_SIZE 64 +#define RX_BUF_SIZE 64 + +#define MINIISP_I2C_SLAVE 0 +#define MINIISP_I2C_TOP 1 + +#define INTF_SPI_READY (1 << 0) +#define INTF_I2C_READY (1 << 1) +#define INTF_CCI_READY (1 << 2) + +#define DEBUG_ALERT 1 +#define DEBUG_TURNON 1 + +/* Enable for use Linux Firmware API "request_firmware" to load fw or bin file + * The file search path is be defined at below array + * drivers/base/firmware_class.c: const fw_path[] + * User need to add required search path into this array + */ +#define ENABLE_LINUX_FW_LOADER 1 + +/* Enable below function + * 1. mast_bulk_data_cmd_read_calibration_data + * 2. mast_bulk_data_cmd_read_memory_data + */ + +#define ENABLE_FILP_OPEN_API 0 + +#define ENABLE_FSM 0 + +/*#define ALTEK_TEST*/ + +#ifdef DEBUG_TURNON + + #ifdef DEBUG_ALERT + #define misp_info(fmt, ...) \ + pr_err(MINI_ISP_LOG_TAG ": " fmt "\n",\ + ##__VA_ARGS__) + + #define misp_warn(fmt, ...) \ + pr_warn(MINI_ISP_LOG_TAG ": " fmt "\n",\ + ##__VA_ARGS__) + + #define misp_err(fmt, ...) \ + pr_err(MINI_ISP_LOG_TAG ": " fmt "\n",\ + ##__VA_ARGS__) + #else + #define misp_info(fmt, ...) \ + pr_err(MINI_ISP_LOG_TAG ": " fmt "\n",\ + ##__VA_ARGS__) + + #define misp_warn(fmt, ...) \ + pr_debug(MINI_ISP_LOG_TAG ": " fmt "\n",\ + ##__VA_ARGS__) + + #define misp_err(fmt, ...) \ + pr_debug(MINI_ISP_LOG_TAG ": " fmt "\n",\ + ##__VA_ARGS__) + #endif + +#else + #define misp_info(fmt, ...) + #define misp_err(fmt, ...) + #define misp_warn(fmt, ...) + +#endif + +/*ALTEK SPI MODE*/ +/*define Altek SPI mode*/ +enum ALTEK_SPI_MODE { + ALTEK_SPI_MODE_E = 0, + ALTEK_SPI_MODE_A, +}; + +/* + *@typedef USPICTRL_MS_CB_ID + *@brief USPI control byte definition (for master control) + */ +enum { + /*!< Ctrl-Byte, original command */ + USPICTRL_MS_CB_ORG = (0x00<<6), + /*!< Ctrl-Byte, polling status */ + USPICTRL_MS_CB_STS = (0x01<<6), + /*!< Ctrl-Byte, get response */ + USPICTRL_MS_CB_RSP = (0x02<<6), + /*!< Ctrl-Byte, disable Ctrl-Byte mode */ + USPICTRL_MS_CB_DIS = (0x03<<6), +}; + +/*Event Bit define*/ +/*define ISP control Master event Bit*/ +enum MINI_ISP_EVENT { + MINI_ISP_RCV_WAITING = 0, /* 0x00000000*/ + MINI_ISP_RCV_CMD_READY = (1L << 0), /* 0x00000001*/ + MINI_ISP_RCV_BULKDATA = (1L << 1), /* 0x00000002*/ + MINI_ISP_RCV_CPCHANGE = (1L << 2), /* 0x00000004*/ + MINI_ISP_RCV_SETSENSORMODE = (1L << 3),/* 0x00000008*/ + MINI_ISP_RCV_ERROR = (1L << 4),/* 0x00000010*/ + MINI_ISP_RCV_ERROR2 = (1L << 5),/* 0x00000020*/ + MINI_ISP_RCV_STRMOFF = (1L << 6),/* 0x00000040*/ +}; + +/* Definition for IRQ status*/ +#define COMMAND_COMPLETE 0x0001/*cmd deal complete by altek chip*/ +#define BULK_DATA_COMPLETE 0x0002/*bulk data deal complete by altek chip*/ +#define CP_STATUS_CHANGE_DONE 0x0004/*code persistence mode change finish*/ +#define SET_SENSOR_MODE_READY 0x0008 +#define SYSTEM_ERROR_LEVEL1 0x0010/*(Get Report)*/ +#define SYSTEM_ERROR_LEVEL2 0x0020/*(Dump Register)*/ +#define STRMOFF_READY 0x0040/*default not use*/ + +enum MINI_ISP_STATE { + MINI_ISP_POWER_OFF = 0, + MINI_ISP_POWER_ON = 1, + MINI_ISP_STANDBY = 3, + MINI_ISP_SENSOR_MODE = 4, + MINI_ISP_CP_MODE = 5, +}; + +enum MINI_CALIB_ID { + CALIBRATION_ID_OTP = 0, + CALIBRATION_ID_DEPTH = 1, + CALIBRATION_ID_SCID = 2, + CALIBRATION_ID_HDR = 3, + CALIBRATION_ID_IRP0 = 4, + CALIBRATION_ID_IRP1 = 5, + CALIBRATION_ID_PPMAP = 6, + CALIBRATION_ID_BLENDINGTABLE = 7, + CALIBRATION_ID_QMERGE = 8, + CALIBRATION_ID_EEPROM = 9, + CALIBRATION_ID_ALTEK = 10, + CALIBRATION_ID_MAX, +}; +/******Public Type Declaration******/ +struct misp_intf_fn_t { + int (*send)(void *devdata, u32 len); + int (*recv)(void *devdata, u32 len, bool waitINT); + int (*read)(void *devdata, u8 *tx_buf, u32 tx_len, u8 *rx_buf, + u32 rx_len); + int (*write)(void *devdata, u8 *tx_buf, u8 *rx_buf, u32 len); +#if ENABLE_LINUX_FW_LOADER + int (*send_bulk)(void *devdata, u32 total_size, u32 block_size, + bool is_raw, const u8 *Sendbulkbuffer); +#else + int (*send_bulk)(void *devdata, struct file *filp, u32 total_size, + u32 block_size, bool is_raw, u8 *Sendbulkbuffer); +#endif +}; + +struct misp_data { + union { + struct spi_device *spi; + struct i2c_client *i2c; + /*struct msm_camera_i2c_client *cci;*/ + } __packed cfg; + + struct misp_intf_fn_t *intf_fn; + int bulk_cmd_blocksize; + u8 tx_buf[TX_BUF_SIZE]; + u8 rx_buf[RX_BUF_SIZE]; +}; + +struct misp_global_variable { + int vcc1_gpio; + int vcc2_gpio; + int vcc3_gpio; + int irq_gpio; + int wp_gpio; + int irq_num; + int reset_gpio; + int intf_status; + int before_booting; + int i2c_enable; + int altek_spi_mode; + int be_set_to_bypass; + int now_state; + int spi_low_speed_mode; + bool en_cmd_send; + struct clk *isp_clk; + struct mutex busy_lock; +}; + + +struct irp_and_depth_information { + u32 irp_image_address; + u32 irp_width; + u32 irp_height; + u8 irp_format;/*Y_only:0 YUV:1*/ + u32 depth_image_address; + u32 depth_width; + u32 depth_height; + u8 fov_mode; +} __packed; + +/******Public Function Prototype******/ +extern irqreturn_t mini_isp_irq(int irq, void *handle); + +/*miniisp_spi.c*/ +extern struct misp_data *get_mini_isp_data(void); +extern void set_mini_isp_data(struct misp_data *data, int intf_type); +extern struct misp_data *get_mini_isp_intf(int i2c_type); +extern struct misp_global_variable *get_mini_isp_global_variable(void); +extern int mini_isp_get_bulk(struct misp_data *devdata, u8 *response_buf, + u32 total_size, u32 block_size); +/*extern u16 mini_isp_get_status(void); //currently not use*/ + +/*miniisp_top.c*/ +extern void mini_isp_e_to_a(void); +extern void mini_isp_a_to_e(void); +extern void mini_isp_chip_init(void); +extern void mini_isp_cp_mode_suspend_flow(void); +extern void mini_isp_cp_mode_resume_flow(void); +extern void mini_isp_check_and_leave_bypass_mode(void); +extern int mini_isp_pure_bypass(u16 mini_isp_mode); +extern void mini_isp_pure_bypass_debug(u16 mini_isp_mode); +extern int mini_isp_get_chip_id(void); +extern u32 mini_isp_register_read_then_write_file(u32 start_reg_addr, + u32 end_reg_addr, char *dest_path, char *module_name); +extern u32 mini_isp_register_read(u32 reg_addr, u32 *reg_value); +extern errcode mini_isp_debug_dump(void); +extern errcode mini_isp_memory_read_then_write_file(u32 start_addr, u32 len, + char *dest_path, char *file_name); +extern u32 mini_isp_woi_memory_read_then_write_file( + u32 start_addr, u32 lineoffset, + u32 width, u32 height, char *dest_path, char *file_name); +extern u32 mini_isp_memory_read_shortlen(u32 start_addr, u32 *read_buffer); +extern u32 mini_isp_memory_read(u32 start_addr, u8 *read_buffer, u32 len); +extern int mini_isp_get_altek_status(void *devdata, u32 *altek_status); +extern int mini_isp_wait_for_event(u32 MINI_ISP_EVENT); +extern u32 mini_isp_get_currentevent(void); +extern void mini_isp_register_write(u32 reg_addr, u32 reg_new_value); +extern void mini_isp_memory_write(u32 memory_addr, u8 *write_buffer, + u32 write_len); + +/*miniisp_utility.c*/ +extern int mini_isp_debug_dump_img(void); +extern int mini_isp_debug_depth_rect_combo_dump(u8 is_ground_mode); +extern errcode mini_isp_debug_packdata_dump(void); +extern errcode mini_isp_debug_IQCalib_dump(void); +extern errcode mini_isp_debug_metadata_dump(void); +extern errcode mini_isp_utility_read_reg_e_mode_for_bypass_use(void); +extern errcode mini_isp_utility_read_reg_e_mode(void); + + +extern errcode mini_isp_debug_depth_info(void); +extern errcode mini_isp_debug_metadata_info(void); +extern errcode mini_isp_debug_sensor_info(bool a_IsLog2File); +extern errcode mini_isp_debug_led_info(bool a_IsLog2File); +extern int mini_isp_debug_mipi_rx_fps_start(bool a_IsLog2File); +extern void mini_isp_debug_mipi_rx_fps_stop(void); +extern errcode mini_isp_debug_GPIO_Status(bool a_IsLog2File); +extern errcode mini_isp_utility_get_irp_and_depth_information( + struct irp_and_depth_information *info); +extern u32 mini_isp_check_rx_dummy(u8 **recv_buffer, u32 rx_dummy_len); +extern errcode mini_isp_create_directory(char *dir_name); +extern u32 mini_isp_get_rx_dummy_byte(u8 spie_rx_mode); +extern void mini_isp_set_spie_dummy_byte(u32 dummy_lens); + +/*miniisp_customer_define.c*/ +extern void mini_isp_poweron(void); +extern void mini_isp_poweroff(void); +extern void mini_isp_eeprom_wpon(void); +extern void mini_isp_eeprom_wpoff(void); +extern int mini_isp_gpio_init(struct device *spi, + struct misp_data *drv_data, + struct misp_global_variable *drv_global_variable); +/* AL6100 debug tool */ +extern int mini_isp_setup_resource(struct device *dev, + struct misp_data *drv_data); +extern struct device *miniisp_chdev_create(struct class *mini_isp_class); +extern struct device *mini_isp_getdev(void); +extern struct misp_data *get_mini_isp_intf_spi(void); +extern struct misp_data *get_mini_isp_intf_i2c(int i2c_type); +#endif + diff --git a/drivers/media/platform/altek/include/miniisp_chip_base_define.h b/drivers/media/platform/altek/include/miniisp_chip_base_define.h new file mode 100755 index 000000000000..89c949e30a68 --- /dev/null +++ b/drivers/media/platform/altek/include/miniisp_chip_base_define.h @@ -0,0 +1,1035 @@ +/* + * File: miniisp_chip_base_define.c.h + * Description: Mini ISP ChipBase Define Code + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2017/10/18; Louis Wang; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _MINIISP_CHIP_BASE_DEFINE_H_ +#define _MINIISP_CHIP_BASE_DEFINE_H_ + +/******Include File******/ + + +/******Public Constant Definition******/ +#define CHIP_ID_ADDR 0xffef0020 +#define SPIE_DUMMY_BYTE_ADDR 0xFFF82000 + +#define INTERRUPT_STATUS_REGISTER_ADDR 0xffef00b4 +#define INTERRUPT_ENABLE_BIT_REGISTER_ADDR 0xffef00b0 + +#define clk_gen_dump_field \ +{\ +0xFFE80040, 0xFFE8004C,\ +0xFFE80060, 0xFFE80064,\ +0xFFE80080, 0xFFE80084,\ +0xFFE800A0, 0xFFE800A4,\ +0xFFE800C0, 0xFFE800C4,\ +0xFFE800E0, 0xFFE800E4,\ +0xFFE80100, 0xFFE80104,\ +0xFFE80120, 0xFFE80124,\ +0xFFE80140, 0xFFE80144,\ +0xFFE80160, 0xFFE80164,\ +0xFFE80180, 0xFFE80184,\ +0xFFE801A0, 0xFFE801A8,\ +0xFFE801C8, 0xFFE801C8,\ +0xFFE80200, 0xFFE80204,\ +0xFFE80240, 0xFFE80244,\ +0xFFE80280, 0xFFE80284,\ +0xFFE80340, 0xFFE80344,\ +0xFFE80380, 0xFFE80384,\ +0xFFE80400, 0xFFE80404,\ +0xFFE80440, 0xFFE80444,\ +0xFFE80460, 0xFFE80464,\ +0xFFE80484, 0xFFE80484,\ +0xFFE804A4, 0xFFE804A4,\ +0xFFE804C4, 0xFFE804C4,\ +0xFFE804E4, 0xFFE804E4,\ +0xFFE80500, 0xFFE80504,\ +0xFFE80540, 0xFFE80548,\ +0xFFE80580, 0xFFE80588,\ +0xFFE805C0, 0xFFE805C8,\ +0xFFE80620, 0xFFE80630,\ +0xFFE80680, 0xFFE80684,\ +0xFFE806E0, 0xFFE806E4,\ +0xFFE80720, 0xFFE80724,\ +0xFFE807C0, 0xFFE807C4,\ +0xFFE80804, 0xFFE80804,\ +0xFFE80814, 0xFFE80814,\ +0xFFE80824, 0xFFE80824,\ +0xFFE80840, 0xFFE80844,\ +0xFFE80884, 0xFFE80884,\ +0xFFE80900, 0xFFE80904,\ +0xFFE80944, 0xFFE80944,\ +0xFFE80B00, 0xFFE80B04,\ +0xFFE80C00, 0xFFE80C04,\ +0xFFE80C40, 0xFFE80C44,\ +0xFFE81000, 0xFFE81004,\ +0xFFE81080, 0xFFE81080,\ +0xFFE81100, 0xFFE81114,\ +0xFFE81120, 0xFFE81134,\ +0xFFE81140, 0xFFE81154,\ +0xFFE81200, 0xFFE8122C,\ +0xFFE8F000, 0xFFE8F000,\ +} + +#define mipi_tx_phy_if_0_dump_field \ +{\ +0xFFED1000, 0xFFED1048,\ +0xFFED1100, 0xFFED1104,\ +} + +#define mipi_tx_phy_if_1_dump_field \ +{\ +0xFFED6000, 0xFFED6048,\ +0xFFED6100, 0xFFED6104,\ +} + +#define gen_reg_dump_field \ +{\ +0xffef0000, 0xffef0008,\ +0xffef0020, 0xffef0044,\ +0xffef0054, 0xffef005C,\ +0xffef0070, 0xffef00a8,\ +0xffef00b0, 0xffef00b4,\ +0xffef00f0, 0xffef00f8,\ +0xffef0100, 0xffef0100,\ +0xffef0208, 0xffef0208,\ +0xffef0240, 0xffef0240,\ +0xffef0248, 0xffef0248,\ +0xffef0250, 0xffef0258,\ +0xffef0280, 0xffef0284,\ +0xffef0410, 0xffef0414,\ +0xffef0500, 0xffef0500,\ +0xffef0f00, 0xffef0f00,\ +} + +#define mipi_slvds_rx_phy_if_0_dump_field \ +{\ +0xfff91000, 0xfff91008,\ +0xfff91010, 0xfff91040,\ +0xfff9104c, 0xfff9104c,\ +0xfff91068, 0xfff91078,\ +0xfff91084, 0xfff91084,\ +0xfff9108c, 0xfff9108c,\ +0xfff91094, 0xfff910c8,\ +0xfff91100, 0xfff9114c,\ +} + +#define mipi_slvds_rx_phy_if_1_dump_field \ +{\ +0xfff94000, 0xfff94008,\ +0xfff94010, 0xfff94040,\ +0xfff9404c, 0xfff9404c,\ +0xfff94068, 0xfff94078,\ +0xfff94084, 0xfff94084,\ +0xfff9408c, 0xfff9408c,\ +0xfff94094, 0xfff940c8,\ +0xfff94100, 0xfff9414c,\ +} + +#define ppi_bridge_a_0_dump_field \ +{\ +0xfff97000, 0xfff97040,\ +0xfff970a0, 0xfff970ac,\ +0xfff970f0, 0xfff970fc,\ +0xfff97110, 0xfff9716c,\ +0xfff972a0, 0xfff972a4,\ +0xfff97300, 0xfff97314,\ +} + +#define ppi_bridge_a_1_dump_field \ +{\ +0xfff98000, 0xfff98040,\ +0xfff980a0, 0xfff980ac,\ +0xfff980f0, 0xfff980fc,\ +0xfff98110, 0xfff9816c,\ +0xfff982a0, 0xfff982a4,\ +0xfff98300, 0xfff98314,\ +} + +#define ppi_bridge_a_1_dump_field \ +{\ +0xfff98000, 0xfff98040,\ +0xfff980a0, 0xfff980ac,\ +0xfff980f0, 0xfff980fc,\ +0xfff98110, 0xfff9816c,\ +0xfff982a0, 0xfff982a4,\ +0xfff98300, 0xfff98314,\ +} + +#define tx_top_out_mux_a_0_dump_field \ +{\ +0xffecb000, 0xffecb004,\ +0xffecb010, 0xffecb014,\ +0xffecb020, 0xffecb050,\ +0xffecb100, 0xffecb13c,\ +0xffecb200, 0xffecb220,\ +0xffecb300, 0xffecb32c,\ +0xffecbf00, 0xffecbf00,\ +} + +#define tx_top_out_mux_a_1_dump_field \ +{\ +0xffecc000, 0xffecc004,\ +0xffecc010, 0xffecc014,\ +0xffecc020, 0xffecc050,\ +0xffecc100, 0xffecc13c,\ +0xffecc200, 0xffecc220,\ +0xffecc300, 0xffecc32c,\ +0xffeccf00, 0xffeccf00,\ +} + +#define tx_line_merge_21_a_0_dump_field \ +{\ +0xffec1000, 0xffec1010,\ +0xffec1020, 0xffec1024,\ +0xffec1030, 0xffec1034,\ +0xffec1040, 0xffec1044,\ +0xffec104c, 0xffec105c,\ +0xffec1070, 0xffec1074,\ +0xffec108c, 0xffec108c,\ +0xffec1100, 0xffec1124,\ +0xffec1140, 0xffec1144,\ +0xffec1150, 0xffec1174,\ +0xffec1180, 0xffec1184,\ +0xffec1300, 0xffec1300,\ +0xffec1310, 0xffec1320,\ +0xffec1330, 0xffec135c,\ +0xffec1400, 0xffec1404,\ +0xffec1410, 0xffec145c,\ +0xffec1470, 0xffec1484,\ +0xffec1490, 0xffec14b0,\ +0xffec1a00, 0xffec1a00,\ +0xffec1a10, 0xffec1a34,\ +0xffec1a40, 0xffec1a84,\ +0xffec1a90, 0xffec1aac,\ +0xffec1ac0, 0xffec1ac4,\ +0xffec1ad0, 0xffec1adc,\ +0xffec1b00, 0xffec1b08,\ +0xffec1b10, 0xffec1b14,\ +0xffec1b20, 0xffec1b54,\ +0xffec1b68, 0xffec1b98,\ +0xffec1f00, 0xffec1f00,\ +} + +#define tx_line_merge_21_b_0_dump_field \ +{\ +0xffec2000, 0xffec2010,\ +0xffec2020, 0xffec2024,\ +0xffec2030, 0xffec2034,\ +0xffec2040, 0xffec2044,\ +0xffec204c, 0xffec205c,\ +0xffec2070, 0xffec2074,\ +0xffec208c, 0xffec208c,\ +0xffec2100, 0xffec2124,\ +0xffec2140, 0xffec2144,\ +0xffec2150, 0xffec2174,\ +0xffec2180, 0xffec2184,\ +0xffec2300, 0xffec2300,\ +0xffec2310, 0xffec2320,\ +0xffec2330, 0xffec235c,\ +0xffec2400, 0xffec2404,\ +0xffec2410, 0xffec245c,\ +0xffec2470, 0xffec2484,\ +0xffec2490, 0xffec24b0,\ +0xffec2a00, 0xffec2a00,\ +0xffec2a10, 0xffec2a34,\ +0xffec2a40, 0xffec2a84,\ +0xffec2a90, 0xffec2aac,\ +0xffec2ac0, 0xffec2ac4,\ +0xffec2ad0, 0xffec2adc,\ +0xffec2b00, 0xffec2b08,\ +0xffec2b10, 0xffec2b14,\ +0xffec2b20, 0xffec2b54,\ +0xffec2b68, 0xffec2b98,\ +0xffec2f00, 0xffec2f00,\ +} + +#define tx_line_merge_21_c_0_dump_field \ +{\ +0xffec5000, 0xffec5010,\ +0xffec5020, 0xffec5024,\ +0xffec5030, 0xffec5034,\ +0xffec5040, 0xffec5044,\ +0xffec504c, 0xffec505c,\ +0xffec5070, 0xffec5074,\ +0xffec508c, 0xffec508c,\ +0xffec5100, 0xffec5124,\ +0xffec5140, 0xffec5144,\ +0xffec5150, 0xffec5174,\ +0xffec5180, 0xffec5184,\ +0xffec5300, 0xffec5300,\ +0xffec5310, 0xffec5320,\ +0xffec5330, 0xffec535c,\ +0xffec5400, 0xffec5404,\ +0xffec5410, 0xffec545c,\ +0xffec5470, 0xffec5484,\ +0xffec5490, 0xffec54b0,\ +0xffec5a00, 0xffec5a00,\ +0xffec5a10, 0xffec5a34,\ +0xffec5a40, 0xffec5a84,\ +0xffec5a90, 0xffec5aac,\ +0xffec5ac0, 0xffec5ac4,\ +0xffec5ad0, 0xffec5adc,\ +0xffec5b00, 0xffec5b08,\ +0xffec5b10, 0xffec5b14,\ +0xffec5b20, 0xffec5b54,\ +0xffec5b68, 0xffec5b98,\ +0xffec5f00, 0xffec5f00,\ +} + +#define tx_line_merge_21_d_0_dump_field \ +{\ +0xffec6000, 0xffec6010,\ +0xffec6020, 0xffec6024,\ +0xffec6030, 0xffec6034,\ +0xffec6040, 0xffec6044,\ +0xffec604c, 0xffec605c,\ +0xffec6070, 0xffec6074,\ +0xffec608c, 0xffec608c,\ +0xffec6100, 0xffec6124,\ +0xffec6140, 0xffec6144,\ +0xffec6150, 0xffec6174,\ +0xffec6180, 0xffec6184,\ +0xffec6300, 0xffec6300,\ +0xffec6310, 0xffec6320,\ +0xffec6330, 0xffec635c,\ +0xffec6400, 0xffec6404,\ +0xffec6410, 0xffec645c,\ +0xffec6470, 0xffec6484,\ +0xffec6490, 0xffec64b0,\ +0xffec6a00, 0xffec6a00,\ +0xffec6a10, 0xffec6a34,\ +0xffec6a40, 0xffec6a84,\ +0xffec6a90, 0xffec6aac,\ +0xffec6ac0, 0xffec6ac4,\ +0xffec6ad0, 0xffec6adc,\ +0xffec6b00, 0xffec6b08,\ +0xffec6b10, 0xffec6b14,\ +0xffec6b20, 0xffec6b54,\ +0xffec6b68, 0xffec6b98,\ +0xffec6f00, 0xffec6f00,\ +} + +#define mipi_csi2_tx_0_dump_field \ +{\ +0xFFED0000, 0xFFED0008,\ +0xFFED0044, 0xFFED0044,\ +0xFFED0058, 0xFFED0068,\ +0xFFED0090, 0xFFED00AC,\ +0xFFED00BC, 0xFFED00C8,\ +0xFFED00D4, 0xFFED00EC,\ +0xFFED0100, 0xFFED0138,\ +0xFFED0300, 0xFFED0358,\ +0xFFED038C, 0xFFED038C,\ +0xFFED0360, 0xFFED03B4,\ +0xFFED03BC, 0xFFED03D0,\ +0xFFED0FF0, 0xFFED0FF0,\ +} + +#define mipi_csi2_tx_1_dump_field \ +{\ +0xFFED5000, 0xFFED5008,\ +0xFFED5044, 0xFFED5044,\ +0xFFED5058, 0xFFED5068,\ +0xFFED5090, 0xFFED50AC,\ +0xFFED50BC, 0xFFED50C8,\ +0xFFED50D4, 0xFFED50EC,\ +0xFFED5100, 0xFFED5138,\ +0xFFED5300, 0xFFED5358,\ +0xFFED538C, 0xFFED538C,\ +0xFFED5360, 0xFFED53B4,\ +0xFFED53BC, 0xFFED53D0,\ +0xFFED5FF0, 0xFFED5FF0,\ +} + +#define gen_reg_depth_top_dump_field \ +{\ +0xfffa0000, 0xfffa0004,\ +0xfffa0050, 0xfffa0050,\ +0xfffa0100, 0xfffa0104,\ +0xfffa0128, 0xfffa0128,\ +0xfffa0200, 0xfffa0234,\ +0xfffa0f00, 0xfffa0f00,\ +} + +#define gen_reg_dpc_top_dump_field \ +{\ +0xfff00000, 0xfff00004,\ +0xfff00010, 0xfff00010,\ +0xfff00100, 0xfff00104,\ +0xfff00128, 0xfff00128,\ +0xfff00f00, 0xfff00f00,\ +} + +#define gen_reg_hdr_top_dump_field \ +{\ +0xfff50000, 0xfff50004,\ +0xfff50100, 0xfff50104,\ +0xfff50128, 0xfff50128,\ +0xfff50f00, 0xfff50f00,\ +} + +#define gen_reg_irp_top_dump_field \ +{\ +0xffec3000, 0xffec3004,\ +0xffec3010, 0xffec3018,\ +0xffec3100, 0xffec3104,\ +0xffec3128, 0xffec312c,\ +0xffec3f00, 0xffec3f00,\ +} + +#define gen_reg_standby_top_dump_field \ +{\ +0xffec4000, 0xffec4004,\ +0xffec4010, 0xffec4020,\ +0xffec4030, 0xffec4044,\ +0xffec4100, 0xffec4104,\ +0xffec4128, 0xffec4128,\ +0xffec4f00, 0xffec4f00,\ +} + +#define gen_reg_tx_top_dump_field \ +{\ +0xffec0000, 0xffec0008,\ +0xffec0010, 0xffec0018,\ +0xffec0310, 0xffec0318,\ +0xffec0f00, 0xffec0f00,\ +} + +#define id_det_a_0_dump_field \ +{\ +0xfff01000, 0xfff01038,\ +0xfff01050, 0xfff0110c,\ +0xfff01150, 0xfff01158,\ +0xfff0117c, 0xfff011c8,\ +0xfff011f4, 0xfff01208,\ +0xfff012a0, 0xfff012b0,\ +0xfff012dc, 0xfff012e4,\ +} + +#define id_det_a_1_dump_field \ +{\ +0xfff02000, 0xfff02038,\ +0xfff02050, 0xfff0210c,\ +0xfff02150, 0xfff02158,\ +0xfff0217c, 0xfff021c8,\ +0xfff021f4, 0xfff02208,\ +0xfff022a0, 0xfff022b0,\ +0xfff022dc, 0xfff022e4,\ +} + +#define bayer_binning_a_0_dump_field \ +{\ +0xfff54000, 0xfff54008,\ +0xfff5401c, 0xfff54068,\ +0xfff54070, 0xfff54094,\ +} + +#define bayer_binning_a_1_dump_field \ +{\ +0xfff55000, 0xfff55008,\ +0xfff5501c, 0xfff55068,\ +0xfff55070, 0xfff55094,\ +} + +#define bayer_scl_a_0_dump_field \ +{\ +0xfffa7000, 0xfffa70d0,\ +0xfffa7100, 0xfffa7108,\ +0xfffa7110, 0xfffa7118,\ +0xfffa7200, 0xfffa7200,\ +} + +#define bayer_scl_a_1_dump_field \ +{\ +0xfffa8000, 0xfffa80d0,\ +0xfffa8100, 0xfffa8108,\ +0xfffa8110, 0xfffa8118,\ +0xfffa8200, 0xfffa8200,\ +} + +#define rlb_a_0_dump_field \ +{\ +0xfff05000, 0xfff0500c,\ +0xfff05018, 0xfff0501c,\ +0xfff05028, 0xfff0502c,\ +0xfff05058, 0xfff05098,\ +0xfff050b0, 0xfff050b0,\ +0xfff050b8, 0xfff050c8,\ +0xfff050d4, 0xfff050e0,\ +0xfff050f0, 0xfff050f0,\ +0xfff05100, 0xfff05108,\ +0xfff05110, 0xfff05110,\ +0xfff05120, 0xfff05138,\ +} + +#define rlb_b_0_dump_field \ +{\ +0xfff06000, 0xfff0600c,\ +0xfff06018, 0xfff0601c,\ +0xfff06028, 0xfff0602c,\ +0xfff06058, 0xfff06098,\ +0xfff060b0, 0xfff060b0,\ +0xfff060b8, 0xfff060c8,\ +0xfff060d4, 0xfff060e0,\ +0xfff060f0, 0xfff060f0,\ +0xfff06100, 0xfff06108,\ +0xfff06110, 0xfff06110,\ +0xfff06120, 0xfff06138,\ +} + + +#define mipi_csi2_rx_0_dump_field \ +{\ +0xfff92000, 0xfff92004,\ +0xfff9200c, 0xfff9208c,\ +0xfff92100, 0xfff92148,\ +0xfff9215c, 0xfff9217c,\ +0xfff92188, 0xfff9218c,\ +0xfff92198, 0xfff921dc,\ +0xfff921f8, 0xfff922d4,\ +} + +#define mipi_csi2_rx_1_dump_field \ +{\ +0xfff95000, 0xfff95004,\ +0xfff9500c, 0xfff9508c,\ +0xfff95100, 0xfff95148,\ +0xfff9515c, 0xfff9517c,\ +0xfff95188, 0xfff9518c,\ +0xfff95198, 0xfff951dc,\ +0xfff951f8, 0xfff952d4,\ +} + +#define dg_ca_a_0_dump_field \ +{\ +0xfff8b000, 0xfff8b074,\ +} + +#define dg_mcc_a_0_dump_field \ +{\ +0xfff8a000, 0xfff8a024,\ +0xfff8a0b0, 0xfff8a170,\ +} + +#define dp_top_a_0_dump_field \ +{\ +0xfff88000, 0xfff88090,\ +0xfff88100, 0xfff88104,\ +0xfff88200, 0xfff88240,\ +0xfff88280, 0xfff88280,\ +0xfff88300, 0xfff88300,\ +} + +#define lvhwirp_top_a_0_dump_field \ +{\ +0xfff30000, 0xfff30018,\ +0xfff30100, 0xfff30110,\ +0xfff30200, 0xfff30238,\ +0xfff30400, 0xfff30418,\ +0xfff31000, 0xfff311ec,\ +0xfff31300, 0xfff31310,\ +0xfff32000, 0xfff32ffc,\ +0xfff33000, 0xfff33004,\ +0xfff33100, 0xfff33188,\ +0xfff33200, 0xfff34204,\ +0xfff34300, 0xfff35ddc,\ +0xfff36000, 0xfff37000,\ +} + +#define lvhwirp_top_b_0_dump_field \ +{\ +0xfff20000, 0xfff20018,\ +0xfff20100, 0xfff20110,\ +0xfff20200, 0xfff20238,\ +0xfff20400, 0xfff20418,\ +0xfff21000, 0xfff211ec,\ +0xfff21300, 0xfff21310,\ +0xfff22000, 0xfff22ffc,\ +0xfff23000, 0xfff23004,\ +0xfff23100, 0xfff23188,\ +0xfff23200, 0xfff24204,\ +0xfff24300, 0xfff25ddc,\ +0xfff26000, 0xfff27000,\ +} + +#define lvlumanr_a_0_dump_field \ +{\ +0xfffa1000, 0xfffa1018,\ +0xfffa1040, 0xfffa1098,\ +0xfffa10A4, 0xfffa10C8,\ +} + +#define lvlumanr_a_1_dump_field \ +{\ +0xfffa2000, 0xfffa2018,\ +0xfffa2040, 0xfffa2098,\ +0xfffa20A4, 0xfffa20C8,\ +} + +#define lvsharp_a_0_dump_field \ +{\ +0xfffa5000, 0xfffa5028,\ +0xfffa5034, 0xfffa5034,\ +0xfffa5044, 0xfffa5060,\ +0xfffa5070, 0xfffa5070,\ +0xfffa50fc, 0xfffa51b0,\ +0xfffa5208, 0xfffa521c,\ +0xfffa5250, 0xfffa5264,\ +0xfffa5270, 0xfffa5270,\ +0xfffa5300, 0xfffa5308,\ +} + +#define lvsharp_a_1_dump_field \ +{\ +0xfffa6000, 0xfffa6028,\ +0xfffa6034, 0xfffa6034,\ +0xfffa6044, 0xfffa6060,\ +0xfffa6070, 0xfffa6070,\ +0xfffa60fc, 0xfffa61b0,\ +0xfffa6208, 0xfffa621c,\ +0xfffa6250, 0xfffa6264,\ +0xfffa6270, 0xfffa6270,\ +0xfffa6300, 0xfffa6308,\ +} + +#define rectify_a_0_dump_field \ +{\ +0xFFF8C000, 0xFFF8C008,\ +0xFFF8C010, 0xFFF8C010,\ +0xFFF8C024, 0xFFF8C024,\ +0xFFF8C040, 0xFFF8C040,\ +0xFFF8C050, 0xFFF8C050,\ +0xFFF8C060, 0xFFF8C060,\ +0xFFF8C080, 0xFFF8C084,\ +0xFFF8C100, 0xFFF8C108,\ +0xFFF8C110, 0xFFF8C110,\ +0xFFF8C17C, 0xFFF8C1A8,\ +0xFFF8C380, 0xFFF8C3A0,\ +0xFFF8C400, 0xFFF8C408,\ +0xFFF8C480, 0xFFF8C480,\ +0xFFF8C50C, 0xFFF8C518,\ +0xFFF8C540, 0xFFF8C540,\ +0xFFF8C550, 0xFFF8C550,\ +0xFFF8C5F0, 0xFFF8C5F0,\ +0xFFF8C900, 0xFFF8C908,\ +0xFFF8C910, 0xFFF8C910,\ +0xFFF8C97C, 0xFFF8C9A8,\ +0xFFF8CB80, 0xFFF8CBA0,\ +0xFFF8CC00, 0xFFF8CC00,\ +0xFFF8CC08, 0xFFF8CC08,\ +0xFFF8CC80, 0xFFF8CC80,\ +0xFFF8CD0C, 0xFFF8CD18,\ +0xFFF8CD40, 0xFFF8CD40,\ +0xFFF8CD50, 0xFFF8CD50,\ +0xFFF8CDF0, 0xFFF8CDF0,\ +0xFFF8CE04, 0xFFF8CE38,\ +0xFFF8CE40, 0xFFF8CE48,\ +0xFFF8CF00, 0xFFF8CFFC,\ +} + +#define rectify_b_0_dump_field \ +{\ +0xFFF8D000, 0xFFF8D008,\ +0xFFF8D010, 0xFFF8D010,\ +0xFFF8D024, 0xFFF8D024,\ +0xFFF8D040, 0xFFF8D040,\ +0xFFF8D050, 0xFFF8D050,\ +0xFFF8D060, 0xFFF8D060,\ +0xFFF8D080, 0xFFF8D084,\ +0xFFF8D100, 0xFFF8D108,\ +0xFFF8D110, 0xFFF8D110,\ +0xFFF8D17C, 0xFFF8D1A8,\ +0xFFF8D380, 0xFFF8D3A0,\ +0xFFF8D400, 0xFFF8D408,\ +0xFFF8D480, 0xFFF8D480,\ +0xFFF8D50C, 0xFFF8D518,\ +0xFFF8D540, 0xFFF8D540,\ +0xFFF8D550, 0xFFF8D550,\ +0xFFF8D5F0, 0xFFF8D5F0,\ +0xFFF8D900, 0xFFF8D908,\ +0xFFF8D910, 0xFFF8D910,\ +0xFFF8D97C, 0xFFF8D9A8,\ +0xFFF8DB80, 0xFFF8DBA0,\ +0xFFF8DC00, 0xFFF8DC00,\ +0xFFF8DC08, 0xFFF8DC08,\ +0xFFF8DC80, 0xFFF8DC80,\ +0xFFF8DD0C, 0xFFF8DD18,\ +0xFFF8DD40, 0xFFF8DD40,\ +0xFFF8DD50, 0xFFF8DD50,\ +0xFFF8DDF0, 0xFFF8DDF0,\ +0xFFF8DE04, 0xFFF8DE38,\ +0xFFF8DE40, 0xFFF8DE48,\ +0xFFF8DF00, 0xFFF8DFFC,\ +} + +#define hdr_ae_a_0_dump_field \ +{\ + 0xFFF59000, 0xFFF59450,\ +} + +#define hdr_ae_a_1_dump_field \ +{\ + 0xFFF5A000, 0xFFF5A450,\ +} + +#define DEPTH_FLOWMGR_INFO_VER 0xc +/* V11 */ +typedef struct { + /* General info */ + u8 ValidFlag; + u8 Ver; + u8 ALDU_MainVer; + u8 ALDU_SubVer; + + struct { + u8 ValidDepthFlowDebugInfo; + u8 DepthFlowModeId; + u16 refImg1_Width; + u16 refImg1_Height; + u16 refImg2_Width; + u16 refImg2_Height; + u16 refImg3_Width; + u16 refImg3_Height; + u16 DepthImgKernelSizeRatio; + u16 DepthType; + u16 DepthGroundType; + u32 DephtProcTime; + u32 BlendingProcTime; + u32 DepthProcCnt; + u8 FeatureFlag; + u8 InvRECT_BypassLDC; + u8 PerformanceFlag; + u8 NormalKernalSizeMatch; + u8 GroundKernalSizeMatch; + u8 NormalKernelSizeIdx; + u8 GroundKernelSizeIdx; + } tDepthFlowDebugInfo; + + /* Packdata */ + struct { + u8 ValidDepthPacadataDebugInfo; + u8 ValidPackdata; + u8 ValidDisparityToDistanceTable; + u8 HighDistortionRate; + u8 PackdataNormalIdx; + u8 PackdataGroundIdx; + u8 PackdataRGBIdx; + u8 AbsoluteGlobalVal; + u8 HwCoefficient; + u16 HighDistortionIdx; + u8 PackdataSource; + u16 WOIMainXBase; + u16 WOIMainYBase; + u16 WOIMainXLength; + u16 WOIMainYLength; + u16 WOISubXBase; + u16 WOISubYBase; + u16 WOISubXLength; + u16 WOISubYLength; + s16 SubCamRectShift; + u32 PackdataAddr; + u32 PackdataChkSum; + u32 IntrinsicK_Main[9]; + u32 AlDUErrCode; + u8 reserve; + u8 ConvertMatch; + u8 ConvertCount; + u8 NormalRectQPReadPingPongIdx; + } tDepthPackdataDebugInfo; + + /* Detph utility */ + struct { + u8 ValidDepthUtiDebugInfo; + u8 ValidBlendingTable; + u16 DistanceVal[3]; + u8 BlendingTableSource; + u16 BlendingTableSize; + u16 BlendingStartLine; + u8 ValidQmerge; + u8 QmergeBinCameraID; + u8 DWUpdated; + } tDepthUtiDebugInfo; +} DEPTHFLOWMGR_DEBUG_INFO; + +enum { + RESOLUTION_16_9 = 0, + RESOLUTION_16_10 = 1, + RESOLUTION_4_3 = 2, + RESOLUTION_OTHER = 3 +}; + +typedef enum { + DEPTHPACKDATA_SRC_NULL, + DEPTHPACKDATA_SRC_CMD, /* receive packdata via command */ + DEPTHPACKDATA_SRC_OTP, /* receive packdata from OTP, EEPROM (ISP read via I2C) */ +} DEPTHPACKDATA_SRC; + +typedef enum { + DEPTHBLENDING_SRC_NULL, + DEPTHBLENDING_SRC_CMD, /* AP send blending table */ + DEPTHBLENDING_SRC_ISP, /* ISP calculate blending table */ +} DEPTHBLENDING_SRC; + +typedef struct { + u16 MetaDataVer; + u16 SCID; + u8 RxSwap; + u8 TxSwap; + u8 SensorType; + u8 HDRPPPipeIdx; + u16 LPPWidth; + u16 LPPHeight; + u16 RPPWidth; + u16 RPPHeight; +} CAPFLOWMGR_META_COMMON; + +/** +@struct CAPFLOWMGR_META_PIPE +@brief Pipe paramters +*/ +typedef struct { + u32 FrameIndex; + u16 SrcImgWidth; + u16 SrcImgHeight; + u32 ColorOrder; + u32 ExpTime; + s16 BV; + u16 ISO; + u16 AD_Gain; + u16 AWB_RGain; + u16 AWB_GGain; + u16 AWB_BGain; + + u16 BlackOffset_R; + u16 BlackOffset_G; + u16 BlackOffset_B; + u16 Crop_X; + u16 Crop_Y; + u16 Crop_Width; + u16 Crop_Height; + u16 ScalarWidth; + u16 ScalarHeight; + + s16 VCM_macro; + s16 VCM_infinity; + s16 VCM_CurStep; + u32 Depth_VCMStatus; +} CAPFLOWMGR_META_PIPE; /* For MetaData */ + +/** +@struct CAPFLOWMGR_META_DEPTH +@brief Depth paramters +*/ +typedef struct { + u32 DepthIndex; + u32 ReferenceFrameIndex; + u16 DepthWidth; + u16 DepthHeight; + u16 DepthType; + s16 awDepth_VCMStep[2]; + u8 aucMediaData[34]; +} CAPFLOWMGR_META_DEPTH; /* For MetaData */ + +/** +@struct CAPFLOWMGR_META_HDR +@brief Depth paramters +*/ +typedef struct { + u8 HDR_Type; + u8 HDR_OutputMode; + u8 ZZ_ColorOrder_R; + u8 ZZ_ColorOrder_Gr; + u8 ZZ_ColorOrder_B; + u8 ExpRatio; + u16 RDN_AdapParam; + u8 Block_Operation_Mode; + u8 PPInfo; + u16 uw0EV_gain; + s16 LongImage_0EV_Target; + s16 ShortImage_0EV_Target; + u16 GhostPrevent_low; + u16 GhostPrevent_high; + u16 HDR_AE_weighting_table_ID; + u16 HDR_Compress_tone_ID; +} CAPFLOWMGR_META_HDR; /* For MetaData */ + +typedef struct { + u16 SHDTableW; + u16 SHDTableH; + u16 SHDNoWOIOutWidth; + u16 SHDNoWOIOutHeight; + u16 SHD_WOI_X; + u16 SHD_WOI_Y; + u16 SHD_WOI_Width; + u16 SHD_WOI_Height; +} CAPFLOWMGR_SHADING_DEBUG_INFO; /* For Metadata, check if it will be used in SK1 */ + +/** +@struct CAPFLOWMGR_PROJECTOR_STATUS +@brief Depth paramters +*/ +typedef struct { + u8 TurnOn; + u8 Level; +} CAPFLOWMGR_PROJECTOR_STATUS; + +typedef struct { + u16 XBase; + u16 YBase; + u16 XLength; + u16 YLength; +} DEPTHPACKDATA_WOI_INFO; + +/** +@struct CAPFLOWMGR_PROJECTOR_STATUS +@brief Depth paramters +*/ +typedef struct { + u8 TurnOn; +} CAPFLOWMGR_GPIO_DEV; + +/** +@struct CAPFLOWMGR_META_SWDEBUG +@brief Depth paramters +*/ +typedef struct { + u8 aucModuleByPass[12]; /* 12 */ + u16 DepthInWidth; /* 2 */ + u16 DepthInHeight; /* 2 */ + CAPFLOWMGR_SHADING_DEBUG_INFO tPipeSHDInfo[2]; /* 32 */ + DEPTHPACKDATA_WOI_INFO tPipeDepthCaliWOI[2]; /* 16 */ + u64 SysTimeus; /* 8 */ + CAPFLOWMGR_PROJECTOR_STATUS tProjectorStatus[8]; /* 16 */ + CAPFLOWMGR_GPIO_DEV tGPIO_Device[2]; /* 2 */ + u8 Resv1[6]; + u64 IDD0_ISRTimeus; + u64 IDD1_ISRTimeus; + u8 aucResv2[16]; +} CAPFLOWMGR_META_SWDEBUG; /* For MetaData */ + +/** +@struct CAPFLOWMGR_DEPTH +@brief Depth paramters +*/ +typedef struct { + u16 OriginalWidth; + u16 OriginalHeight; + u16 WOIWidth; /* Sensor Crop */ + u16 WOIHeight; /* Sensor Crop */ + u16 WOI_X; /* Sensor Crop */ + u16 WOI_Y; /* Sensor Crop */ + u16 uw2ndWOIWidth; /* Internal Module Crop */ + u16 uw2ndWOIHeight; /* Internal Module Crop */ + u16 uw2ndWOI_X; /* Internal Module Crop */ + u16 uw2ndWOI_Y; /* Internal Module Crop */ + u16 OutputWidth; + u16 OutputHeight; + u16 Output_X; + u16 Output_Y; +} CAPFLOWMGR_DEPTH_WOI_INFO; + +typedef struct { + u32 Qmerge_Ver; + u32 audTool_Ver[3]; + u32 audTuning_Ver[3]; + u8 aucVerifyDebug[2]; + u16 uw2PD_Info; + u8 aucEngineEnable[8]; + s16 awCCM[2][9]; + u32 ExpRatio; + u32 audParaAddr[2][80]; + u8 aucResv[32]; +} CAPFLOWMGR_META_IQDEBUG; /* For Metadata, check if it will be used in SK1 */ + +/** +@struct CAPFLOWMGR_METADATA +@brief scenario paramters +*/ +typedef struct { + CAPFLOWMGR_META_COMMON tCommonInfo; + CAPFLOWMGR_META_PIPE tPipe0Info; + CAPFLOWMGR_META_PIPE tPipe1Info; + CAPFLOWMGR_META_DEPTH tDpethInfo; + CAPFLOWMGR_META_HDR tHDRInfo; + u8 aucMetaData_reserved_0[12]; + CAPFLOWMGR_META_SWDEBUG tSWDebugInfo; + CAPFLOWMGR_META_IQDEBUG tIQDebugInfo; + u8 aucMetaData_reserved_1[920]; + u32 audHDRAEHistogram_Short[260]; + u32 audHDRAEHistogram_Long[260]; +} CAPFLOWMGR_METADATA; + +typedef enum { + E_FEC_SENSOR_MODE_NORMAL, + E_FEC_SENSOR_MODE_MASTER, + E_FEC_SENSOR_MODE_SLAVE, + E_FEC_SENSOR_MODE_MAX +} E_FEC_SENSOR_MODE; + +typedef struct { + u16 VTS; /* line_length_pck */ + u16 HTS; /* frame_length_line */ + u16 ImageWidth; /* image width */ + u16 ImageHeight; /* image height */ + u32 FrameTime; /* frame time (us) */ + u32 FrameRate; /* frame rate (3003 = 30.03fps) */ + u32 ExpTime; /* expousre time (us) */ + u32 Gain; /* gain (150 = 1.5x) */ + E_FEC_SENSOR_MODE SensorMode; /* see E_FEC_SENSOR_MODE */ +} FEC_SENSOR_REAL_INFO; + +typedef enum { + E_LED_PROJECTOR = 0, + E_LED_FLOOD, +} E_LED_TYPE; + + +typedef struct{ + u8 Type; /* 0 for projector, 1 for flood */ + u16 Level; /* current sw level (0~255) */ + u16 Current; /* sw level mapping to current (mA) */ + u16 MaxCurrent; /* support maximum current (mA) */ + u16 ErrStatus; /* driver IC status (if support) */ + u16 Temperature; /* error occurs, and record temperature from thermal sensor */ + u32 errCode; /* errCode, see ProjectorCtrl_Err.h */ +} PROJECTOR_INFO; + +typedef struct { + char name[32]; + u32 addr; + char mapping[32]; +} GPIO; + + +/******Public Function Prototype******/ +extern void mini_isp_chip_base_define_module_reg_dump( + char *dest_path, char *module_name); + +extern errcode mini_isp_chip_base_dump_bypass_mode_register(char *dest_path); + +extern errcode mini_isp_chip_base_dump_normal_mode_register(char *dest_path); + +extern errcode mini_isp_chip_base_dump_irp_and_depth_based_register(void); +#endif diff --git a/drivers/media/platform/altek/include/miniisp_ctrl.h b/drivers/media/platform/altek/include/miniisp_ctrl.h new file mode 100755 index 000000000000..b2287dac0a23 --- /dev/null +++ b/drivers/media/platform/altek/include/miniisp_ctrl.h @@ -0,0 +1,441 @@ +/* + * File: miniisp_ctrl.h + * Description: The structure and API definition mini ISP Ctrl + * It is a header file that define structure and API for mini ISP Ctrl + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/10/14; Aaron Chuang; Initial version + * 2013/12/05; Bruce Chung; 2nd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _MINIISP_CTRL_H_ +#define _MINIISP_CTRL_H_ + +/** + *@addtogroup MiniISPCtrl + *@{ + */ + +/******Include File******/ + +#include "mtype.h" +#include "isp_camera_cmd.h" +#include "error.h" +#include "moduleid_pj.h" + +/******Global define******/ +#define DEPTH_NONE 0x0 /*No depth*/ +#define DEPTH_BIT_RES_180 0x1 /*180p*/ +#define DEPTH_BIT_RES_360 0x2 /*360p*/ +#define DEPTH_BIT_RES_720 0x3 /*720p*/ +#define DEPTH_BIT_RES_480 0x4 /*480p*/ + +#define DEPTH_BIT_DG_ONLY 0x00 +#define DEPTH_BIT_DP_SPARSE_1 0x10 +#define DEPTH_BIT_DP_SPARSE_2 0x20 +#define DEPTH_BIT_DP_SPARSE_3 0x30 +#define DEPTH_BIT_DP_DENSE 0x40 +#define DEPTH_BIT_MASK_TYPE 0x70 +#define DEPTH_BIT_RESV 0x80 + +/******Public Function Prototype******/ + +/** + *\brief Mini ISP open + *\param boot_code_file_name [In], Boot code filename + *\param basic_code_file_name [In], Basic code filename + *\param advanced_code_file_name [In], Advanced code filename + *\param scenario_table_file_name [In], Sc table filename + *\param hdr_qmerge_file_name [In], hdr qmerge filename + *\param irp0_qmerge_file_name [In], irp0 qmerge filename + *\param irp1_qmerge_file_name [In], irp1 qmerge filename + *\param pp_map_file_name [In], PP map filename + *\param depth_qmerge_file_name [In], depth qmerge filename + *\return Error code + *\image html BootSeq.jpg + */ +extern errcode mini_isp_drv_open(char *boot_code_file_name, + char *basic_code_file_name, + char *advanced_code_file_name, + char *scenario_table_file_name, + char *hdr_qmerge_file_name, + char *irp0_qmerge_file_name, + char *irp1_qmerge_file_name, + char *pp_map_file_name, + char *depth_qmerge_file_name + ); + +/** + *\brief Mini ISP write boot code + *\param n/a + *\return Error code + */ +extern errcode mini_isp_drv_write_boot_code(void); + +/** + *\brief Mini ISP write boot code (short SPI Len) + *\param n/a + *\return Error code + */ +extern errcode mini_isp_drv_write_boot_code_shortlen(void); + +/** + *\brief Mini ISP write basic code + *\param n/a + *\return Error code + */ +extern errcode mini_isp_drv_write_basic_code(void); + +/** + *\brief Mini ISP write basic code (short SPI Len) + *\param n/a + *\return Error code + */ +extern errcode mini_isp_drv_write_basic_code_shortlen(void); + +/** + *\brief Mini ISP write spinor code + *\param info_id [In], 0 : boot data + * 1 : main data + *\return Error code + */ +extern errcode mini_isp_drv_write_spinor_data(u8 info_id); + +/** + *\brief Mini ISP Write Calibration Data 0x210B + *\param info_id [In], 0 : IQ data + * 1 : packet data + * 2 : scenario table + * 3 : hdr + * 4 : irp0 + * 5 : irp1 + * 6 : PP map + * 7 : blending table + * 8 : depth qmerge + * 9 : OTP data + *\param buf_addr [In], otp/packet data buffer start address + *\param buf_len [In], otp/packet data buffer len + *\return Error code + */ +extern errcode mini_isp_drv_write_calibration_data(u8 info_id, + u8 *buf_addr, u32 buf_len); + + +/** + *\brief Set Sensor Mode 0x300A + *\param sensor_on_off [In],sensor on/off + *\param scenario_id[In], Scenario ID + *\param mipi_tx_skew_enable[In], mipi tx skew on(1)/off(0) + *\param ae_weighting_table_index[In] + *\param merge_mode_enable[In] + *\ bit[0:3] : + *\ set 0 for normal mode + *\ set 1 for merge mode, only for image samller than 640X480 case + *\ set 2 for depth test pattern mode + *\ bit[4] : + *\ set 0 for turn on sensor by AP. + *\ set 1 for turn on sensor by AL6100. + *\return Error code + */ +extern errcode mini_isp_drv_set_sensor_mode(u8 sensor_on_off, + u8 scenario_id, + u8 mipi_tx_skew_enable, + u8 ae_weighting_table_index, + u8 merge_mode_enable); + +/** + *\brief Set Output Format 0x300D + *\param depth_map_setting [In] + *\param depth_process_type[In] value 0x6 as reserve + *\param function on/off[In] + *\return Error code + */ +extern errcode mini_isp_drv_set_output_format( + struct isp_cmd_set_output_format *output_format); + +/** + *\brief Set CP Mode 0x300E + *\return Error code + */ +extern errcode mini_isp_drv_set_cp_mode(void); + +/** + *\brief Leave CP Mode + *\using set sensor mode opcode :0x300A + *\param sensor_on_off [In],sensor on/off + *\param scenario_id[In], Scenario ID + *\param mipi_tx_skew_enable[In], mipi tx skew on(1)/off(0) + *\param ae_weighting_table_index[In] + *\param merge_mode_enable[In] + *\return Error code + */ +extern errcode mini_isp_drv_leave_cp_mode(u8 sensor_on_off, u8 scenario_id, + u8 mipi_tx_skew_enable, u8 ae_weighting_table_index, + u8 merge_mode_enable); + +/** + *\brief Set AE statistics 0x300F + *\param gr_channel_weight [In], + *\param gb_channel_weight [In], + *\param r_channel_weight [In], + *\param b_channel_weight [In], + *\param shift_bits [In], + *\return Error code + */ +extern errcode mini_isp_drv_set_ae_statistics( + struct isp_cmd_ae_statistics *ae_statistics); + +/** + *\brief Preview stream on/off 0x3010 + *\param tx0_stream_on_off [In], Tx0 stream on/off + *\param tx1_stream_on_off [In], Tx1 stream on/off + *\return Error code + */ +errcode mini_isp_drv_preview_stream_on_off(u8 tx0_stream_on_off, + u8 tx1_stream_on_off); + +/** + *\brief Dual PD Y Calcualtion Weighting 0x3011 + *\param isp_cmd_dual_pd_y_calculation_weightings [In], + dual PD Y calculation weightings + *\return Error code + */ +errcode mini_isp_drv_dual_pd_y_calculation_weighting( + struct isp_cmd_dual_pd_y_calculation_weightings *calculation_weighting); + +/** + *\brief LED power control 0x3012 + *\param projector_control_param, + *\return Error code + */ +errcode mini_isp_drv_led_power_control( + struct isp_cmd_led_power_control *projector_control_param); + +/** + *\brief Active AE 0x3013 + *\param active_ae [In], + *\return Error code + */ +extern errcode mini_isp_drv_active_ae( + struct isp_cmd_active_ae *active_ae_param); + +/** + *\brief ISP AE control mode on off 0x3014 + *\param isp_ae_control_mode_on_off [In], 0:off 1:on + *\return Error code + */ +extern errcode mini_isp_drv_isp_ae_control_mode_on_off( + u8 isp_ae_control_mode_on_off); + +/** + *\brief Set Frame Rate Limite 0x3015 + *\param set_frame_rate_param [In], + *\return Error code + */ +extern errcode mini_isp_drv_set_frame_rate_limits( + struct isp_cmd_frame_rate_limits *set_frame_rate_param); + +extern errcode mini_isp_drv_get_sensor_mode(void); + +extern errcode mini_isp_drv_get_last_exec_cmd(void); + +extern errcode mini_isp_drv_get_err_code_cmd(void); + +extern errcode mini_isp_drv_get_err_code_cmd_in_irq(void); + +extern u16 mini_isp_drv_read_spi_status(void); + + +/** + *\brief Set ISP register 0x0100 + *\param reg_start_addr [In], Reg start addr + *\param reg_value [In], Reg value + *\return Error code + */ +extern errcode mini_isp_drv_set_isp_register(u32 reg_start_addr, + u32 reg_value); + + +/** + *\brief Get ISP register + *\param reg_start_addr [In], Reg start addr + *\param reg_count [In], Reg count + *\return Error code + */ +extern errcode mini_isp_drv_get_isp_register(u32 reg_start_addr, + u32 reg_count); + +/** + *\brief Get Chip test Report 0x010A + *\return Error code + */ +extern errcode mini_isp_drv_get_chip_test_report(void); + +/** + *\brief Set Depth 3A Information 0x10B9 + *\param depth_3a_info [In], Depth 3A parameter + *\return Error code + */ +extern errcode mini_isp_drv_set_depth_3a_info( + struct isp_cmd_depth_3a_info *depth_3a_info); + +/** + *\brief Set Depth auto interleave mode 0x10BC + *\param depth_auto_interleave_param [In], ISP Depth auto interleave parameter + *\return Error code + */ +extern errcode mini_isp_drv_set_depth_auto_interleave_mode( + struct isp_cmd_depth_auto_interleave_param + *depth_auto_interleave_param); + +/** + *\brief Set Projector Interleave Mode with Depth Type 0x10BD + *\param mini_isp_drv_projector_interleave_mode_depth_type [In], + *\ 0: depth active, 1: depth passive + *\return Error code + */ +extern errcode mini_isp_drv_projector_interleave_mode_depth_type( + u8 projector_interleave_mode_with_depth_type); + +/** + *\brief Set Depth Polish LEVEL 0x10BE + *\param depth_polish_level [In], 0~100 + *\return Error code + */ +extern errcode mini_isp_drv_set_depth_polish_level( + u8 depth_polish_level); + +/** + *\brief Set Exposure Parameter 0x10BF + *\param exposure_param [In], ISP Exposure parameter + *\return Error code + */ +extern errcode mini_isp_drv_set_exposure_param( + struct isp_cmd_exposure_param *exposure_param); + +/** + *\brief Set depth stream size 0x10C0 + *\param depth_stream_size [In], ISP depth stream size + *\return Error code + */ +extern errcode mini_isp_drv_set_depth_stream_size( + struct isp_cmd_depth_stream_size *depth_stream_size); + +/** + *\brief Reading Common Log + *\param stop [In], Stop to log flag + *\return Error code + */ +extern errcode mini_isp_drv_read_com_log(bool stop); + +/** + *\brief Read memory + *\param start_addr [In]starting address + *\param read_size [In]TotalReadSize + *\return Error code + */ +extern errcode mini_isp_drv_read_memory(u32 start_addr, u32 read_size); + +/** + *\brief Read Calibration Data + *\param info_param [In], + *\return Error code + */ +extern errcode mini_isp_drv_read_calibration_data(void); + +/** + *\brief Get Depth rect A, B, invrect parameter + *\param 0 : depth rect A, B InvRect parameter structure array buffer + *\param 1 : transfer mode. (Default set to 0) + *\param 2 : bluk block size + *\return Error code + */ +extern errcode mini_isp_drv_write_depth_rectab_invrect( + struct depth_rectab_invrect_param *rect_param, + u8 trans_mode, + u32 block_size); + +extern errcode mini_isp_drv_set_com_log_level(u32 log_level); + +/** + *\brief Master boot miniISP + *\param e [In], MINI_ISP_EVENT + *\return Errorcode + */ +extern int mini_isp_drv_wait_for_event(u16 e); + +extern errcode mini_isp_drv_setting(u16 mini_isp_mode); + +extern errcode mini_isp_drv_set_bypass_mode(u16 bypass_mode); + +extern errcode mini_isp_drv_set_max_exposure( + struct isp_cmd_exposure_param *max_exposure_info); + +extern errcode mini_isp_drv_set_target_mean( + struct isp_cmd_target_mean *target_mean_info); + +extern errcode mini_isp_drv_frame_sync_control( + struct isp_cmd_frame_sync_control *frame_sync_control_param); + +extern errcode mini_isp_drv_set_shot_mode( + struct isp_cmd_set_shot_mode *set_shot_mode_param); + +extern errcode mini_isp_drv_lighting_ctrl( + struct isp_cmd_lighting_ctrl *lighting_ctrl); + +extern errcode mini_isp_drv_depth_compensation( + struct isp_cmd_depth_compensation_param *depth_compensation_param); + +extern errcode mini_isp_drv_cycle_trigger_depth_process( + struct isp_cmd_cycle_trigger_depth_process *param); + +extern errcode mini_isp_drv_led_active_delay(u32 delay_ms); + +extern errcode mini_isp_drv_set_min_exposure( + struct isp_cmd_exposure_param *min_exposure_info); + +extern errcode mini_isp_drv_set_max_exposure_slope( + struct isp_cmd_max_exposure_slope *max_exposure_slope_info); + +extern errcode mini_isp_drv_isp_control_led_level(u8 on); + +extern errcode mini_isp_drv_get_chip_thermal(u16 *thermal_val); + +extern void mini_isp_drv_altek_i2c_mode_change(void); + +extern errcode mini_isp_drv_load_fw(void); + +extern void mini_isp_reset(void); + + +/** \brief Master boot miniISP + *\param None + *\return None + */ +extern int mini_isp_drv_boot_mini_isp(void); + +/******End of File******/ + +/** + *@} + */ + +#endif /* _MINIISP_CTRL_H_*/ diff --git a/drivers/media/platform/altek/include/miniisp_ctrl_intf.h b/drivers/media/platform/altek/include/miniisp_ctrl_intf.h new file mode 100755 index 000000000000..d9532e0d56e3 --- /dev/null +++ b/drivers/media/platform/altek/include/miniisp_ctrl_intf.h @@ -0,0 +1,46 @@ +/* + * File: miniisp_ctrl_intf.h + * Description: mini ISP control cmd interface. + * use for handling the control cmds instead of debug cmds + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2018/08/28; PhenixChen; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _MINIISP_CTRL_INTF_H_ +#define _MINIISP_CTRL_INTF_H_ + +#define P_F_INTERLEAVE + +extern int handle_ControlFlowCmd_II(u16 miniisp_op_code, u8 *param); +extern long handle_ControlFlowCmd(unsigned int cmd, unsigned long arg); +/*AL6100 Kernel Base Solution */ +enum miniisp_firmware { + ECHO_IQ_CODE, + ECHO_DEPTH_CODE, + ECHO_OTHER_MAX +}; + +extern long handle_ControlFlowCmd_Kernel(unsigned int cmd, unsigned long arg); +extern void mini_isp_other_drv_open(char *file_name, u8 type); +extern void mini_isp_other_drv_read(struct file *filp, u8 type); +/*AL6100 Kernel Base Solution */ +#endif diff --git a/drivers/media/platform/altek/include/miniisp_customer_define.h b/drivers/media/platform/altek/include/miniisp_customer_define.h new file mode 100755 index 000000000000..be3780827df3 --- /dev/null +++ b/drivers/media/platform/altek/include/miniisp_customer_define.h @@ -0,0 +1,114 @@ +/* + * File: miniisp_customer_define.h + * Description: miniISP customer define + * + * Copyright 2019-2030 Altek Semiconductor Corporation + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _MINIISP_CUSTOMER_DEFINE_H_ +#define _MINIISP_CUSTOMER_DEFINE_H_ + +#include +/******Public Define******/ + +/*SPI MODE*/ +#define SPI_MODE (SPI_MODE_3) /*SPI_MODE_3 | SPI_CS_HIGH*/ + +/* SPI SPEED */ +/* SPI speed for generally using. */ +/* Note: QCOM605 need to configure beyond 32000000Hz*/ +/* ,otherwise it may happen SPI timeout*/ +#define SPI_BUS_SPEED 32000000 +#define SPI_BUS_SPEED_BOOT 2000000 /* SPI Speed before boot code ready phase */ +#define SPI_BUS_SPEED_LOW 3000000 /* For code persistence mode */ + +/*boot file location*/ +#define BOOT_FILE_LOCATION "/data/firmware/miniBoot.bin" +/*basic code location*/ +#define BASIC_FILE_LOCATION "/data/firmware/TBM_SK1.bin" +/*advanced code location*/ +#define ADVANCED_FILE_LOCATION NULL +/*scenario table location*/ +#define SCENARIO_TABLE_FILE_LOCATION "/data/firmware/SCTable.asb" + +/*hdr qmerge data location*/ +#define HDR_QMERGE_DATA_FILE_LOCATION "/data/firmware/HDR.bin" +/*irp0 qmerge data location*/ +#define IRP0_QMERGE_DATA_FILE_LOCATION "/data/firmware/IRP0.bin" +/*irp1 qmerge data location*/ +#define IRP1_QMERGE_DATA_FILE_LOCATION "/data/firmware/IRP1.bin" +/*pp map location*/ +#define PP_MAP_FILE_LOCATION NULL/*"/system/etc/firmware/PPmap.bin"*/ +/*depth qmerge data location*/ +#define DPETH_QMERGE_DATA_FILE_LOCATION "/data/firmware/Depth.bin" + +/*iq calibaration data location*/ +#define IQCALIBRATIONDATA_FILE_LOCATION \ + "/data/misc/camera_otp/IQCalibrationData_Decrypt.bin" + /*"/system/etc/firmware/PPmap.bin"*/ +/*depth pack data location*/ +#define DEPTHPACKDATA_FILE_LOCATION \ + "/data/misc/camera_otp/DepthPackData_Decrypt.bin" + /*"/system/etc/firmware/PPmap.bin"*/ + +/*miniISP dump info save location*/ +/*Add location folder where you let Altek debug info saving in your device*/ +#define MINIISP_INFO_DUMPLOCATION "/data/local/tmp/" + +/*miniISP bypass setting file location*/ +/*Add location folder where you let Altek debug info saving in your device*/ +#define MINIISP_BYPASS_SETTING_FILE_PATH "/data/firmware/" + +/*define for gpio*/ +/*vcc1 : if no use, set NULL*/ +#define VCC1_GPIO NULL /*"vcc1-gpios"*/ + +/*vcc2 : if no use, set NULL*/ +#define VCC2_GPIO NULL/*"vcc2-gpios"*/ + +/*vcc3 : if no use, set NULL*/ +#define VCC3_GPIO NULL/*"vcc3-gpios"*/ + +/*reset*/ +#define RESET_GPIO NULL /*"reset-gpios"*/ + +/*irq*/ +#define IRQ_GPIO "irq-gpios" + +/*wp*/ +#define WP_GPIO NULL /*"wp-gpios"*/ + +/*isp_clk : if no use, set NULL*/ +#define ISP_CLK NULL /*"al6100_clk"*/ + +/*Enable SPI short length mode*/ +#define SPI_SHORT_LEN_MODE (false) +#define SPI_BLOCK_LEN (14) +#define SPI_SHORT_LEN_MODE_WRITE_ENABLE (false) +#define SPI_SHORT_LEN_MODE_READ_ENABLE (true) + +#define INTERRUPT_METHOD 0 +#define POLLING_METHOD 1 +/* choose INT or polling mechanism to get AL6100 status */ +#define ISR_MECHANISM INTERRUPT_METHOD + +#define EN_605_IOCTRL_INTF 1 +/******Public Function Prototype******/ +#endif diff --git a/drivers/media/platform/altek/include/miniisp_debug_if.h b/drivers/media/platform/altek/include/miniisp_debug_if.h new file mode 100755 index 000000000000..1cf1af5dfaf2 --- /dev/null +++ b/drivers/media/platform/altek/include/miniisp_debug_if.h @@ -0,0 +1,68 @@ +/* + * File: miniisp_debug_if.h + * Description: mini ISP debug daemon interface + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2017/04/20; PhenixChen; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _ISPDBG_IOCTL_H +#define _ISPDBG_IOCTL_H + +#include /*_IOW(), _IOR()*/ +#include + +struct ioctl_regRW_cmd { + u32 RegAddr; + u32 RegVal; +}; + +struct ioctl_regBulkRW_cmd { + u32 StartAddr; + u32 EndAddr; +}; + +struct ioctl_memRW_cmd { + u32 MemAddr; + u32 len; +}; + +#define IOC_REGCMD_MAGIC 'R' +#define IOC_MEMCMD_MAGIC 'M' +#define IOC_BULKCMD_MAGIC 'B' +#define IOC_INFOCMD_MAGIC 'I' +#define IOC_PREPARECMD_MAGIC 'P' + +/*------------------ _IOX(TYPE 8bits, nr 8bits, size 14bits) */ +#define IOCTL_REGREAD _IOR(IOC_REGCMD_MAGIC, 1, struct ioctl_regRW_cmd) +#define IOCTL_REGWRITE _IOW(IOC_REGCMD_MAGIC, 2, struct ioctl_regRW_cmd) +#define IOCTL_REGBULKREAD _IOR(IOC_BULKCMD_MAGIC, 3, struct ioctl_regBulkRW_cmd) +#define IOCTL_REGBULKWRITE _IOR(IOC_BULKCMD_MAGIC, 4,\ + struct ioctl_regBulkRW_cmd) +#define IOCTL_MEMREAD _IOR(IOC_MEMCMD_MAGIC, 5, struct ioctl_memRW_cmd) +#define IOCTL_MEMWRITE _IOW(IOC_MEMCMD_MAGIC, 6, struct ioctl_memRW_cmd) +#define IOCTL_MUNMAP_DONE _IOW(IOC_MEMCMD_MAGIC, 7, struct ioctl_memRW_cmd) +#define IOCTL_MEMGET _IOW(IOC_MEMCMD_MAGIC, 8, struct ioctl_memRW_cmd) +#define IOCTL_IRP_DEPTH_INFO _IOR(IOC_INFOCMD_MAGIC, 9,\ + struct irp_and_depth_information) +#define IOCTL_REFRESH_MODULE _IOR(IOC_PREPARECMD_MAGIC, 10, u8) + +#endif diff --git a/drivers/media/platform/altek/include/moduleid.h b/drivers/media/platform/altek/include/moduleid.h new file mode 100755 index 000000000000..0e92ea65cc44 --- /dev/null +++ b/drivers/media/platform/altek/include/moduleid.h @@ -0,0 +1,71 @@ +/* + * File: moduleid.h + * Description: Define module id + * + * Copyright 2019-2030 Altek Semiconductor Corporation + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +/** + *@file moduleid.h + *@author Gene Hung + *@version 2005/08/22; Gene; Add Doxygen remark + *@defgroup ModuleID Module ID definition + *@brief TBirdOS 2.0 and later module ID definition. + *code number definition: + *Bits 31~20: Module id + *Bits 19~12: Reserved + *Bits 11~0: Code defined in each module + */ + +#ifndef _MODULEID_H_ +#define _MODULEID_H_ + +/** + *@ingroup ModuleID + *@{ + */ + +/** + *@def MODULEID_SHIFTBITS + *@brief Module ID MARCO definition + */ +#define MODULEID_SHIFTBITS 20 +/** + *@def MODULEID_ModuleID + *@brief Get ID number from a CODE + */ +#define MODULEID_ModuleID(code) (code >> MODULEID_SHIFTBITS) +/** + *@def MODULEID_ModuleBase + *@brief Get CODE BASE from a module ID + */ +#define MODULEID_ModuleBase(id) (id << MODULEID_SHIFTBITS) + +/* Project-dependent module starts from this ID*/ +#define MODULEID_PROJECT 0x400 + + +/* Let Project use MODULEID_PROJECT to extend. */ +/*Don't define module ID 0x401 0x402... here.*/ + +/** + *@} + */ +#endif /*_MODULEID_H_*/ diff --git a/drivers/media/platform/altek/include/moduleid_pj.h b/drivers/media/platform/altek/include/moduleid_pj.h new file mode 100755 index 000000000000..d820e243e187 --- /dev/null +++ b/drivers/media/platform/altek/include/moduleid_pj.h @@ -0,0 +1,39 @@ +/* + * File: Moduleid_PJ.h + * Description: Define module id in project + * + * Copyright 2019-2030 Altek Semiconductor Corporation + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _MODULEID_PJ_H_ +#define _MODULEID_PJ_H_ + +#include "moduleid.h" + +/* Project-dependent module starts from MODULEID_PROJECT (0x400)*/ +#define MODULEID_PJ_MINIISP_STATE (MODULEID_PROJECT + 0x2C) +#define MODULEID_PJ_ISPCTRLIF_SLAVE (MODULEID_PROJECT + 0x2D) +#define MODULEID_PJ_ISPCTRLIF_MASTER (MODULEID_PROJECT + 0x2E) +#define MODULEID_PJ_MINIISP (MODULEID_PROJECT + 0x2F) +#endif + + + + diff --git a/drivers/media/platform/altek/include/mtype.h b/drivers/media/platform/altek/include/mtype.h new file mode 100755 index 000000000000..db3174130668 --- /dev/null +++ b/drivers/media/platform/altek/include/mtype.h @@ -0,0 +1,38 @@ +/* + * File: mtype.h + * Description: Global type definition + * Please don't add new definition arbitrarily + * Only system-member is allowed to modify this file + * + * Copyright 2019-2030 Altek Semiconductor Corporation + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + +#ifndef _MTYPE_H_ +#define _MTYPE_H_ + +#include +#include + +typedef u32 errcode; + +/* Other definition*/ +/*#define _Uncached volatile __attribute__ ((section(".ucdata")))*/ + +#endif diff --git a/drivers/media/platform/altek/ispctrl_if_master.c b/drivers/media/platform/altek/ispctrl_if_master.c new file mode 100644 index 000000000000..7823cf1cf69f --- /dev/null +++ b/drivers/media/platform/altek/ispctrl_if_master.c @@ -0,0 +1,1113 @@ +/* + * File: ispctrl_if_master.c + * Description: ISP Ctrl IF Master + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/10/14; Aaron Chuang; Initial version + * 2013/12/05; Bruce Chung; 2nd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/******Include File******/ +/* Linux headers*/ +#include +#include +#include +#include + +#include "include/miniisp.h" +#include "include/ispctrl_if_master.h" +#include "include/isp_camera_cmd.h" +#include "include/error/ispctrl_if_master_err.h" +#include "include/ispctrl_if_master_local.h" +#include "include/miniisp_ctrl.h" +#include "include/miniisp_chip_base_define.h" + + +/*extern struct misp_data *misp_drv_data;*/ + +/******Private Constant Definition******/ +#define MASTERTX_BLOCK_SIZE SPI_TX_BULK_SIZE +#define MINI_ISP_LOG_TAG "[_mini_ispctrl_if_master]" + + +/******Private Type Definition******/ +struct file *g_filp[FIRMWARE_MAX]; +struct spi_device *spictrl; +/******Private Function Prototype******/ + + +static errcode execute_system_manage_cmd(void *devdata, u16 opcode, + u8 *param); +static errcode execute_basic_setting_cmd(void *devdata, u16 opcode, + u8 *param); +static errcode execute_bulk_data_cmd(void *devdata, u16 opcode, + u8 *param); +static errcode execute_camera_profile_cmd(void *devdata, u16 opcode, + u8 *param); +static errcode execute_operation_cmd(void *devdata, u16 opcode, + char *param); +static u16 isp_mast_calculate_check_sum(u8 *input_buffer_addr, + u16 input_buffer_size, bool b2sCom); + +/******Private Global Variable******/ + + +/******Private Global Variable******/ + + + + +/******Public Function******/ + +/* + *\brief Execute SPI master command + *\param opcode [In], Op code + *\param param [In], CMD param buffer + *\return Error code + */ +errcode ispctrl_if_mast_execute_cmd(u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + struct misp_global_variable *devdata_global_variable; + void *devdata; + + misp_info("%s opcode: %#04x >>>", + __func__, opcode); + + devdata_global_variable = get_mini_isp_global_variable(); + devdata = (void *)get_mini_isp_intf(MINIISP_I2C_TOP); + + if (!devdata) + return -ENODEV; + + if (!devdata_global_variable->en_cmd_send && opcode != 0x210B) { + misp_info("%s, disable cmd send!", __func__); + return err; + } + + + mutex_lock(&devdata_global_variable->busy_lock); + + /* System Management 0x0000~0x0FFF*/ + if (opcode <= 0x0FFF) + err = execute_system_manage_cmd(devdata, opcode, param); + /* Basic Setting 0x1000~0x1FFF*/ + else if (opcode <= 0x1FFF) + err = execute_basic_setting_cmd(devdata, opcode, param); + /* Bulk Data 0x2000~0x2FFF*/ + else if (opcode <= 0x2FFF) + err = execute_bulk_data_cmd(devdata, opcode, param); + /* Camera Profile 0x3000~0x3FFF*/ + else if (opcode <= 0x3FFF) + err = execute_camera_profile_cmd(devdata, opcode, param); + /*Operation 0x4000~0x4FFF*/ + else if (opcode <= 0x4FFF) + err = execute_operation_cmd(devdata, opcode, param); + else + err = ERR_MASTER_OPCODE_UNSUPPORT; + + /* delay 2ms */ + msleep(20); + + mutex_unlock(&devdata_global_variable->busy_lock); + + misp_info("%s opcode: %#04x <<<", + __func__, opcode); + + return err; +} +EXPORT_SYMBOL(ispctrl_if_mast_execute_cmd); + +/* + *\brief Send command to slave + *\param devdata [In], misp_data + *\param opcode [In], Op code + *\param param [In], CMD param buffer + *\param len [In], CMD param size + *\return Error code + */ +errcode ispctrl_mast_send_cmd_to_slave(void *devdata, + u16 opcode, u8 *param, u32 len) +{ + u16 *send_len, *send_opcode, total_len; + errcode err = ERR_SUCCESS; + u16 chksum; + u8 *tx_buf; + struct misp_global_variable *devdata_global_variable; + + devdata_global_variable = get_mini_isp_global_variable(); + tx_buf = ((struct misp_data *)devdata)->tx_buf; + + memset(tx_buf, 0, TX_BUF_SIZE); + + send_len = (u16 *)&tx_buf[0]; + send_opcode = (u16 *)&tx_buf[ISPCMD_LENFLDBYTES]; + + /*[2-byte len field] + [2-byte opcode field] + (params len)*/ + total_len = ISPCMD_CMDSIZE + len; + /* totoal - 2-byte length field*/ + *send_len = total_len - ISPCMD_LENFLDBYTES; + + *send_opcode = opcode; + if (len > 0) + memcpy(&tx_buf[ISPCMD_CMDSIZE], param, len); + + /*calculate checksum*/ + chksum = isp_mast_calculate_check_sum(tx_buf, total_len, true); + memcpy(&tx_buf[total_len], &chksum, ISPCMD_CKSUMBYTES); + + /*add bytes for checksum*/ + total_len += ISPCMD_CKSUMBYTES; + + /** + * tx_buf: + * |--len_field(2)--| + * |--opcode(2)--|--param(len)--| + * |--cksum(2)--| + * len_field size: ISPCMD_LENFLDBYTES (2 bytes) + * opcode size: ISPCMD_OPCODEBYTES (2 bytes) + * param size: (len bytes) + * ISP_CMD_HDR_SIZE = ISPCMD_LENFLDBYTES + ISPCMD_OPCODEBYTES (4 bytes) + * + * total_len: (len_field_size + opcode_size + param_size + cksum_size) + * len(param_len) = (opcode_size + param_size), excluding cksum + */ + + /* Send command to slave*/ + err = ((struct misp_data *)devdata)->intf_fn->send(devdata, total_len); + + + return err; +} + +/* + *\brief Receive response from slave + *\param devdata [In], misp_data + *\param param [Out], Respons e buffer + *\param len [Out], Response size + *\return Error code + */ +errcode ispctrl_mast_recv_response_from_slave(void *devdata, + u8 *param, u32 len, bool wait_int) +{ + errcode err = ERR_SUCCESS; + u32 total_len; + u16 org_chk_sum; + u8 *rx_buf; + struct misp_global_variable *devdata_global_variable; + + devdata_global_variable = get_mini_isp_global_variable(); + rx_buf = ((struct misp_data *)devdata)->rx_buf; + + memset(rx_buf, 0, RX_BUF_SIZE); + total_len = len + ISPCMD_CMDSIZEWDUMMY + ISPCMD_CKSUMBYTES; + + /*Receive command from slave*/ + err = ((struct misp_data *)devdata)->intf_fn-> + recv(devdata, total_len, wait_int); + if (err != ERR_SUCCESS) + goto ispctrl_mast_recv_response_from_slave_end; + + + /*checksum*/ + memcpy(&org_chk_sum, &rx_buf[(total_len - ISPCMD_CKSUMBYTES)], + ISPCMD_CKSUMBYTES); + if (org_chk_sum != isp_mast_calculate_check_sum(rx_buf, + (total_len - ISPCMD_CKSUMBYTES), true)) { + misp_err("%s - checksum error", __func__); + err = ERR_MASTERCMDCKSM_INVALID; + goto ispctrl_mast_recv_response_from_slave_end; + } + + + /* Copy param data*/ + memcpy(param, &rx_buf[ISPCMD_CMDSIZEWDUMMY], len); + +ispctrl_mast_recv_response_from_slave_end: + + return err; + +} + +/* + *\brief Receive Memory data from slave + *\param devdata [In], misp_data + *\param response_buf [Out], Response buffer + *\param response_size [Out], Response size + *\param wait_int [In], waiting INT flag + *\return Error code + */ +errcode ispctrl_if_mast_recv_memory_data_from_slave( + void *devdata, + u8 *response_buf, + u32 *response_size, + u32 block_size, + bool wait_int) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 expect_size; + u32 altek_event_state; + u16 i; + + expect_size = *response_size; + + misp_info("%s - Start.", __func__); + + if (wait_int) { + err = mini_isp_wait_for_event(MINI_ISP_RCV_CMD_READY); + if (err) { + misp_err("%s - irq error: status=%d", + __func__, err); + goto ispctrl_if_mast_recv_memory_data_from_slave_end; + } + } else { + for (i = 0; i < 200; i++) { + err = mini_isp_get_altek_status(devdata, + &altek_event_state); + if (altek_event_state & COMMAND_COMPLETE) { + altek_event_state = (altek_event_state & + ~((~0) << 1)); + break; + } + /* delay 5ms */ + msleep(20); + } + if (i >= 200) { + misp_err("%s time out.", __func__); + err = ERR_MASTER_EVENT_TIMEOUT; + goto ispctrl_if_mast_recv_memory_data_from_slave_end; + } + + } + + err = mini_isp_get_bulk((struct misp_data *)devdata, + response_buf, expect_size, block_size); + +ispctrl_if_mast_recv_memory_data_from_slave_end: + + return err; +} + +#if ENABLE_LINUX_FW_LOADER +/* + * \brief Master send bulk (large data) to slave + * \param devdata [In], misp_data + * \param buffer [In], Data buffer to be sent, address 8-byte alignment + * \param filp [In], file pointer, used to read the file and send the data + * \param total_size [In], file size + * \param block_size [In], transfer buffer block size + * \param is_raw [In], true: mini boot code false: other files + * \return Error code + */ +errcode ispctrl_if_mast_send_bulk(void *devdata, const u8 *buffer, + u32 total_size, u32 block_size, bool is_raw) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + + if (buffer == NULL) + return -ENOENT; + + misp_info("ispctrl_if_master_send_bulk Start ============"); + /* Transfer basic code*/ + err = ((struct misp_data *)devdata)->intf_fn->send_bulk(devdata, + total_size, block_size, is_raw, buffer); + + if (err != ERR_SUCCESS) + misp_err("ispctrl_if_master_send_bulk failed!!"); + + misp_info("ispctrl_if_master_send_bulk End ============"); + return err; + +} + +#else +/* + * \brief Master send bulk (large data) to slave + * \param devdata [In], misp_data + * \param buffer [In], Data buffer to be sent, address 8-byte alignment + * \param filp [In], file pointer, used to read the file and send the data + * \param total_size [In], file size + * \param block_size [In], transfer buffer block size + * \param is_raw [In], true: mini boot code false: other files + * \return Error code + */ +errcode ispctrl_if_mast_send_bulk(void *devdata, u8 *buffer, + struct file *filp, u32 total_size, u32 block_size, bool is_raw) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + + + if ((!filp) && (buffer == NULL)) + return -ENOENT; + + misp_info("ispctrl_if_master_send_bulk Start ============"); + /* Transfer basic code*/ + err = ((struct misp_data *)devdata)->intf_fn->send_bulk(devdata, + filp, total_size, block_size, is_raw, buffer); + + if (err != ERR_SUCCESS) + misp_err("ispctrl_if_master_send_bulk failed!!"); + misp_info("ispctrl_if_master_send_bulk End ============"); + + + /*close the file*/ + if (filp && (buffer == NULL)) + filp_close(filp, NULL); + return err; + +} +#endif + + +/* open boot / basic / advanced / sc table file*/ +errcode ispctrl_if_mast_request_firmware(u8 *filepath, u8 firmwaretype) +{ + errcode err = ERR_SUCCESS; + + misp_info("%s filepath : %s", __func__, filepath); +#if ENABLE_FILP_OPEN_API + /* use file open */ +#else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + return err; +#endif + if (IS_ERR(g_filp[firmwaretype])) { + err = PTR_ERR(g_filp[firmwaretype]); + misp_err("%s open file failed. err: %x", __func__, err); + } else { + misp_info("%s open file success!", __func__); + } + + return err; +} + + +/* current no use +u16 ispctrl_if_mast_read_spi_status(void) +{ + return mini_isp_get_status(); +} +*/ + +/* + *\brief Receive ISP register response from slave + *\param devdata [In], misp_data + *\param response_buf [Out], Response buffer + *\param response_size [Out], Response size + *\param total_count [In], Total reg count + *\return Error code + */ +errcode ispctrl_if_mast_recv_isp_register_response_from_slave( + void *devdata, u8 *response_buf, + u32 *response_size, u32 total_count) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 total_len; + u16 org_chk_sum; + + /* Last packet flag*/ + bool last_packet = false; + /* Get Reg count*/ + u8 reg_count = 0; + /* Total count*/ + u32 use_total_count = total_count; + /* Total return size*/ + u32 total_ret_size = 0; + /* Max count*/ + u8 max_reg_count = 12; + /* Checksum*/ + u16 check_sum = 0; + bool wait_int = true; + u8 *rx_buf; + struct misp_global_variable *devdata_global_variable; + + devdata_global_variable = get_mini_isp_global_variable(); + rx_buf = ((struct misp_data *)devdata)->rx_buf; + + /* Update expect size*/ + total_len = ISPCMD_CMDSIZEWDUMMY + ISP_REGISTER_PARA_SIZE; + + /* Multi SPI Tx transfer*/ + /*if One SPI Rx recv*/ + while (last_packet == false) { + /* One SPI Rx recv*/ + if (use_total_count <= max_reg_count) { + /* Set reg count*/ + reg_count = use_total_count; + /* Set last packet*/ + last_packet = true; + } else { + /*Multi SPI Rx recv*/ + reg_count = max_reg_count; + } + /* Update expect size*/ + total_len += reg_count*ISP_REGISTER_VALUE; + + /* Add bytes for checksum*/ + if (last_packet == true) + total_len += ISPCMD_CKSUMBYTES; + + + /* Receive command from slave*/ + err = ((struct misp_data *)devdata)->intf_fn->recv( + devdata, total_len, wait_int); + if (err != ERR_SUCCESS) + break; + + /* Last packet*/ + if (last_packet == true) { + /* Get checksum*/ + memcpy(&org_chk_sum, + &rx_buf[(total_len - ISPCMD_CKSUMBYTES)], + ISPCMD_CKSUMBYTES); + + /* Count checksum*/ + check_sum += isp_mast_calculate_check_sum( + &rx_buf[total_ret_size], + total_len - ISPCMD_CKSUMBYTES, false); + /* Do 2's complement*/ + check_sum = 65536 - check_sum; + + /* Checksum error*/ + if (org_chk_sum != check_sum) { + /* Set error code*/ + err = ERR_MASTERCMDCKSM_INVALID; + break; + } + } else { + /* Normal packet*/ + /* checksum is valid or not*/ + check_sum += isp_mast_calculate_check_sum( + &rx_buf[total_ret_size], total_len, + false); + } + + /* Update total count*/ + use_total_count -= reg_count; + /* Update total ret size*/ + total_ret_size += total_len; + + /* Reset expect size*/ + total_len = 0; + /* Update max reg count*/ + max_reg_count = 16; + + } + + + #ifdef OUTPUT_ISP_REGISTER + /*write out the buffer to .arw file here*/ + #endif + + + return err; + +} + +/******Private Function******/ + + +/** + *\brief Execute system manage command + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +static errcode execute_system_manage_cmd(void *devdata, u16 opcode, + u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + + /* Get status of Last Executed Command*/ + if (opcode == ISPCMD_SYSTEM_GET_STATUSOFLASTEXECUTEDCOMMAND) + err = mast_sys_manage_cmd_get_status_of_last_exec_command( + devdata, opcode, param); + else if (opcode == ISPCMD_SYSTEM_GET_ERRORCODE) + err = mast_sys_manage_cmd_get_error_code_command(devdata, + opcode, param); + /* Set ISP register*/ + else if (opcode == ISPCMD_SYSTEM_SET_ISPREGISTER) + err = mast_sys_manage_cmd_set_isp_register(devdata, + opcode, param); + /* Get ISP register*/ + else if (opcode == ISPCMD_SYSTEM_GET_ISPREGISTER) + err = mast_sys_manage_cmd_get_isp_register(devdata, + opcode, param); + /* Set common log level*/ + else if (opcode == ISPCMD_SYSTEM_SET_COMLOGLEVEL) + err = mast_sys_manage_cmd_set_comomn_log_level(devdata, + opcode, param); + /*Get chip test report*/ + else if (opcode == ISPCMD_SYSTEM_GET_CHIPTESTREPORT) + err = mast_sys_manage_cmd_get_chip_test_report(devdata, + opcode, param); + /*Get chip thermal*/ + else if (opcode == ISPCMD_SYSTEM_GET_CHIP_THERMAL) + err = mast_sys_manage_cmd_get_chip_thermal(devdata, + opcode, param); + return err; + +} + +/** + *\brief Execute basic setting command + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +static errcode execute_basic_setting_cmd(void *devdata, u16 opcode, + u8 *param) +{ + /*Error Code*/ + errcode err = ERR_SUCCESS; + + + /* Set Depth 3A info*/ + if (opcode == ISPCMD_BASIC_SET_DEPTH_3A_INFO) + err = mast_basic_setting_cmd_set_depth_3a_info(devdata, + opcode, param); + /* Set Depth Auto interleave mode*/ + else if (opcode == ISPCMD_BASIC_SET_DEPTH_AUTO_INTERLEAVE_MODE) + err = mast_basic_setting_cmd_set_depth_auto_interleave_mode( + devdata, opcode, param); + /* Set Depth Auto interleave mode*/ + else if (opcode == ISPCMD_BASIC_SET_INTERLEAVE_MODE_DEPTH_TYPE) + err = mast_basic_setting_cmd_set_interleave_mode_depth_type( + devdata, opcode, param); + /* Set Depth polish level*/ + else if (opcode == ISPCMD_BASIC_SET_DEPTH_POLISH_LEVEL) + err = mast_basic_setting_cmd_set_depth_polish_level( + devdata, opcode, param); + /* Set exposure param*/ + else if (opcode == ISPCMD_BASIC_SET_EXPOSURE_PARAM) + err = mast_basic_setting_cmd_set_exposure_param( + devdata, opcode, param); + /* Set exposure param*/ + else if (opcode == ISPCMD_BASIC_SET_DEPTH_STREAM_SIZE) + err = mast_basic_setting_cmd_set_depth_stream_size( + devdata, opcode, param); + + return err; + +} +#if ENABLE_LINUX_FW_LOADER +/** + *\brief Execute bulk data command + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +static errcode execute_bulk_data_cmd(void *devdata, + u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 *block_size; + char filename[ISPCMD_FILENAME_SIZE]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + memcpy(filename, param, ISPCMD_FILENAME_SIZE); + + + misp_info("%s Start", __func__); + + /*set the size*/ + block_size = (u32 *)¶m[8]; + + if (opcode == ISPCMD_BULK_WRITE_BOOTCODE) { + /* Write Boot Code*/ + misp_info("%s : write BOOT_CODE", __func__); + + dev_global_variable->before_booting = 1; + *block_size = MASTERTX_BLOCK_SIZE; + +#ifndef AL6100_SPI_NOR + err = mast_bulk_data_cmd_write_boot_code(devdata, param); +#endif + dev_global_variable->before_booting = 0; + } else if (opcode == ISPCMD_BULK_WRITE_BOOTCODE_SHORT_LEN) { + /* Write Boot Code (short SPI len)*/ + misp_info("%s : write BOOT_CODE", __func__); + dev_global_variable->before_booting = 1; + *block_size = MASTERTX_BLOCK_SIZE; +#ifndef AL6100_SPI_NOR + err = mast_bulk_data_cmd_write_boot_code_shortlen( + devdata, param); +#endif + dev_global_variable->before_booting = 0; + } else if (opcode == ISPCMD_BULK_WRITE_BASICCODE) { + /* Write Basic Code*/ + misp_info("%s : write BASIC_CODE", __func__); + +#ifndef AL6100_SPI_NOR + err = mast_bulk_data_cmd_write_basic_code( + devdata, param); +#endif + } else if (opcode == ISPCMD_BULK_WRITE_BASICCODE_CODESUM) { + /* Write Basic Code (short SPI len)*/ + misp_info("%s : write BASIC_CODE", __func__); +#ifndef AL6100_SPI_NOR + err = mast_bulk_data_cmd_write_basic_code_shortlen( + devdata, param); +#endif + + } else if (opcode == ISPCMD_BULK_WRITE_CALIBRATION_DATA) { + /*Write Calibration Data*/ + if (param[8] == 0) { + misp_info("%s : write IQ_CALIBRATION_DATA", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param); + } else if (param[8] == 1) { + misp_info("%s : write DEPTH_CALIBRATION_DATA", + __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param); + } else if (param[8] == 2) { + misp_info("%s : write SCENARIO_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param); + } else if (param[8] == 3) { + misp_info("%s : write HDR_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param); + } else if (param[8] == 4) { + misp_info("%s : write IRP0_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param); + } else if (param[8] == 5) { + misp_info("%s : write IRP1_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param); + } else if (param[8] == 6) { + misp_info("%s : write PPMAP_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param); + } else if (param[8] == 7) { + misp_info("%s : write BLENDING_TABLE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param); + } else if (param[8] == 8) { + misp_info("%s : write DEPTH_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param); + } else if (param[8] == 9) { + misp_info("%s : write OTP DATA", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param); + } + } + /* Read Calibration Data*/ + else if (opcode == ISPCMD_BULK_READ_CALIBRATION_DATA) + err = mast_bulk_data_cmd_read_calibration_data(devdata, param); + + /* Read memory Data*/ + else if (opcode == ISPCMD_BULK_READ_MEMORY) + err = mast_bulk_data_cmd_read_memory_data(devdata, param); + /* Read Common Log Data*/ + else if (opcode == ISPCMD_BULK_READ_COMLOG) + err = bulk_data_cmd_read_common_log(devdata, param); + /* Read Depth RectA, B, Invrect*/ + else if (opcode == ISPCMD_BULK_WRITE_DEPTH_RECTAB_INVRECT) { + err = mast_bulk_data_cmd_write_depth_rectab_invrect( + devdata, opcode, param); + } else if (opcode == ISPCMD_BULK_WRITE_SPINOR_DATA) { + /*Write SPINOR Data*/ + if (param[8] == 0) { + misp_info("%s : write SPINOR BOOT DATA ", __func__); + err = mast_bulk_data_cmd_write_spinor_data( + devdata, param); + } else if (param[8] == 1) { + misp_info("%s : write SPINOR MAIN DATA", __func__); + err = mast_bulk_data_cmd_write_spinor_data( + devdata, param); + } + } + misp_info("execute_bulk_data_cmd - end Errcode: %d ======", + (int)err); + + return err; + +} + +#else +/** + *\brief Execute bulk data command + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +static errcode execute_bulk_data_cmd(void *devdata, + u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 *block_size; + char filename[ISPCMD_FILENAME_SIZE]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + memcpy(filename, param, ISPCMD_FILENAME_SIZE); + + + misp_info("%s Start", __func__); + + /*set the size*/ + block_size = (u32 *)¶m[8]; + + if (opcode == ISPCMD_BULK_WRITE_BOOTCODE) { + /* Write Boot Code*/ + misp_info("%s : write BOOT_CODE", __func__); + + dev_global_variable->before_booting = 1; + *block_size = MASTERTX_BLOCK_SIZE; + +#ifndef AL6100_SPI_NOR + err = mast_bulk_data_cmd_write_boot_code(devdata, param, + g_filp[BOOT_CODE]); + + if (g_filp[BOOT_CODE] != NULL) { + filp_close(g_filp[BOOT_CODE], NULL); + g_filp[BOOT_CODE] = NULL; + } +#endif + + dev_global_variable->before_booting = 0; + } else if (opcode == ISPCMD_BULK_WRITE_BOOTCODE_SHORT_LEN) { + /* Write Boot Code (short SPI len)*/ + misp_info("%s : write BOOT_CODE", __func__); + dev_global_variable->before_booting = 1; + *block_size = MASTERTX_BLOCK_SIZE; +#ifndef AL6100_SPI_NOR + err = mast_bulk_data_cmd_write_boot_code_shortlen( + devdata, param, g_filp[BOOT_CODE]); + + if (g_filp[BOOT_CODE] != NULL) { + filp_close(g_filp[BOOT_CODE], NULL); + g_filp[BOOT_CODE] = NULL; + } +#endif + dev_global_variable->before_booting = 0; + } else if (opcode == ISPCMD_BULK_WRITE_BASICCODE) { + /* Write Basic Code*/ + misp_info("%s : write BASIC_CODE", __func__); + +#ifndef AL6100_SPI_NOR + err = mast_bulk_data_cmd_write_basic_code(devdata, param, + g_filp[BASIC_CODE]); + + if (g_filp[BASIC_CODE] != NULL) { + filp_close(g_filp[BASIC_CODE], NULL); + g_filp[BASIC_CODE] = NULL; + } +#endif + } else if (opcode == ISPCMD_BULK_WRITE_BASICCODE_CODESUM) { + /* Write Basic Code (short SPI len)*/ + misp_info("%s : write BASIC_CODE", __func__); +#ifndef AL6100_SPI_NOR + err = mast_bulk_data_cmd_write_basic_code_shortlen( + devdata, param, g_filp[BASIC_CODE]); + + if (g_filp[BASIC_CODE] != NULL) { + filp_close(g_filp[BASIC_CODE], NULL); + g_filp[BASIC_CODE] = NULL; + } +#endif + + } else if (opcode == ISPCMD_BULK_WRITE_CALIBRATION_DATA) { + /*Write Calibration Data*/ + if (param[8] == 0) { + misp_info("%s : write IQ_CALIBRATION_DATA", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param, NULL); + } else if (param[8] == 1) { + misp_info("%s : write DEPTH_CALIBRATION_DATA", + __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param, NULL); + } else if (param[8] == 2) { + misp_info("%s : write SCENARIO_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param, g_filp[SCENARIO_CODE]); + + if (g_filp[SCENARIO_CODE] != NULL) { + filp_close(g_filp[SCENARIO_CODE], NULL); + g_filp[SCENARIO_CODE] = NULL; + } + + } else if (param[8] == 3) { + misp_info("%s : write HDR_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param, g_filp[HDR_CODE]); + + if (g_filp[HDR_CODE] != NULL) { + filp_close(g_filp[HDR_CODE], NULL); + g_filp[HDR_CODE] = NULL; + } + } else if (param[8] == 4) { + misp_info("%s : write IRP0_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param, g_filp[IRP0_CODE]); + + if (g_filp[IRP0_CODE] != NULL) { + filp_close(g_filp[IRP0_CODE], NULL); + g_filp[IRP0_CODE] = NULL; + } + } else if (param[8] == 5) { + misp_info("%s : write IRP1_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param, g_filp[IRP1_CODE]); + + if (g_filp[IRP1_CODE] != NULL) { + filp_close(g_filp[IRP1_CODE], NULL); + g_filp[IRP1_CODE] = NULL; + } + } else if (param[8] == 6) { + misp_info("%s : write PPMAP_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param, g_filp[PPMAP_CODE]); + + if (g_filp[PPMAP_CODE] != NULL) { + filp_close(g_filp[PPMAP_CODE], NULL); + g_filp[PPMAP_CODE] = NULL; + } + } else if (param[8] == 7) { + misp_info("%s : write BLENDING_TABLE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param, NULL); + } else if (param[8] == 8) { + misp_info("%s : write DEPTH_CODE", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param, g_filp[DEPTH_CODE]); + + if (g_filp[DEPTH_CODE] != NULL) { + filp_close(g_filp[DEPTH_CODE], NULL); + g_filp[DEPTH_CODE] = NULL; + } + } else if (param[8] == 9) { + misp_info("%s : write OTP DATA", __func__); + err = mast_bulk_data_cmd_write_calibration_data( + devdata, param, NULL); + } + } + /* Read Calibration Data*/ + else if (opcode == ISPCMD_BULK_READ_CALIBRATION_DATA) + err = mast_bulk_data_cmd_read_calibration_data(devdata, param); + /* Read memory Data*/ + else if (opcode == ISPCMD_BULK_READ_MEMORY) + err = mast_bulk_data_cmd_read_memory_data(devdata, param); + /* Read Common Log Data*/ + else if (opcode == ISPCMD_BULK_READ_COMLOG) + err = bulk_data_cmd_read_common_log(devdata, param); + /* Read Depth RectA, B, Invrect*/ + else if (opcode == ISPCMD_BULK_WRITE_DEPTH_RECTAB_INVRECT) { + err = mast_bulk_data_cmd_write_depth_rectab_invrect( + devdata, opcode, param); + } else if (opcode == ISPCMD_BULK_WRITE_SPINOR_DATA) { + /*Write SPINOR Data*/ + if (param[8] == 0) { + misp_info("%s : write SPINOR BOOT DATA ", __func__); + err = mast_bulk_data_cmd_write_spinor_data( + devdata, param, g_filp[BOOT_CODE]); + } else if (param[8] == 1) { + misp_info("%s : write SPINOR MAIN DATA", __func__); + err = mast_bulk_data_cmd_write_spinor_data( + devdata, param, g_filp[BASIC_CODE]); + } + } + misp_info("execute_bulk_data_cmd - end Errcode: %d ======", (int)err); + + return err; + +} +#endif +/** + *\brief Execute camera profile command + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +static errcode execute_camera_profile_cmd(void *devdata, u16 opcode, + u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + + /* Set Sensor Mode*/ + if (opcode == ISPCMD_CAMERA_SET_SENSORMODE) + err = mast_camera_profile_cmd_set_sensor_mode(devdata, + opcode, param); + /* Get Sensor Mode*/ + else if (opcode == ISPCMD_CAMERA_GET_SENSORMODE) + err = mast_camera_profile_cmd_get_sensor_mode(devdata, + opcode, param); + /*Set Output format*/ + else if (opcode == ISPCMD_CAMERA_SET_OUTPUTFORMAT) + err = mast_camera_profile_cmd_set_output_format(devdata, + opcode, param); + /*Set CP Mode*/ + else if (opcode == ISPCMD_CAMERA_SET_CP_MODE) + err = mast_camera_profile_cmd_set_cp_mode(devdata, + opcode, param); + /* Preview stream on*/ + else if (opcode == ISPCMD_CAMERA_PREVIEWSTREAMONOFF) + err = mast_camera_profile_cmd_preview_stream_on_off( + devdata, opcode, param); + /* Set AE statistic*/ + else if (opcode == ISPCMD_CAMERA_SET_AE_STATISTICS) + err = mast_basic_setting_cmd_set_ae_statistics( + devdata, opcode, param); + /* Dual PD Y calculation weightings*/ + else if (opcode == ISPCMD_CAMERA_DUALPDYCALCULATIONWEIGHT) + err = mast_camera_profile_cmd_dual_pd_y_cauculation_weightings( + devdata, opcode, param); + /* LED power control*/ + else if (opcode == ISPCMD_LED_POWERCONTROL) + err = mast_camera_profile_cmd_led_power_control( + devdata, opcode, param); + /* Active AE*/ + else if (opcode == ISPCMD_CAMERA_ACTIVE_AE) + err = mast_camera_profile_cmd_active_ae( + devdata, opcode, param); + /* ISP AE Control*/ + else if (opcode == ISPCMD_ISP_AECONTROLONOFF) + err = mast_camera_profile_cmd_isp_ae_control_on_off( + devdata, opcode, param); + /* Set Frame Rate Limits*/ + else if (opcode == ISPCMD_CAMERA_SET_FRAMERATELIMITS) + err = mast_camera_profile_cmd_set_frame_rate_limits( + devdata, opcode, param); + /* Set Period Drop Frame*/ + else if (opcode == ISPCMD_CAMERA_SET_PERIODDROPFRAME) + err = mast_camera_profile_cmd_set_period_drop_frame( + devdata, opcode, param); + /* Set Max exposure*/ + else if (opcode == ISPCMD_CAMERA_SET_MAX_EXPOSURE) + err = mast_camera_profile_cmd_set_max_exposure( + devdata, opcode, param); + /* Set AE Target Mean*/ + else if (opcode == ISPCMD_CAMERA_SET_AE_TARGET_MEAN) + err = mast_camera_profile_cmd_set_target_mean( + devdata, opcode, param); + /* Frame Sync Control*/ + else if (opcode == ISPCMD_CAMERA_FRAME_SYNC_CONTROL) + err = mast_camera_profile_cmd_frame_sync_control( + devdata, opcode, param); + /* Set Shot Mode */ + else if (opcode == ISPCMD_CAMERA_SET_SHOT_MODE) + err = mast_camera_profile_cmd_set_shot_mode( + devdata, opcode, param); + /* Lighting Control*/ + else if (opcode == ISPCMD_CAMERA_LIGHTING_CTRL) + err = mast_camera_profile_cmd_lighting_ctrl( + devdata, opcode, param); + /* Set Depth shift */ + else if (opcode == ISPCMD_CAMERA_DEPTH_COMPENSATION) + err = mast_camera_profile_cmd_set_depth_compensation( + devdata, opcode, param); + /* set cycle trigger depth process */ + else if (opcode == ISPCMD_CAMERA_TRIGGER_DEPTH_PROCESS_CTRL) + err = mast_camera_profile_cmd_set_cycle_trigger_depth( + devdata, opcode, param); + /* Set Min exposure*/ + else if (opcode == ISPCMD_CAMERA_SET_MIN_EXPOSURE) + err = mast_camera_profile_cmd_set_min_exposure( + devdata, opcode, param); + /* Set Max exposure slope*/ + else if (opcode == ISPCMD_CAMERA_SET_MAX_EXPOSURE_SLOPE) + err = mast_camera_profile_cmd_set_max_exposure_slope( + devdata, opcode, param); + /* Set led active delay time */ + else if (opcode == ISPCMD_CAMERA_SET_LED_ACTIVE_DELAY) + err = mast_camera_profile_cmd_set_led_active_delay( + devdata, opcode, param); + /* Set ISP control led level */ + else if (opcode == ISPCMD_CAMERA_ISPLEDLEVELCONTROLONOFF) + err = mast_camera_profile_cmd_isp_control_led_level( + devdata, opcode, param); + else + misp_err("%s : unknown opcode: %#04x", __func__, opcode); + return err; + +} + + +/** + *\brief Execute operation command + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +static errcode execute_operation_cmd(void *devdata, + u16 opcode, char *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + + /* mini_isp_drv_open*/ + if (opcode == ISPCMD_MINIISPOPEN) + err = mast_operation_cmd_miniisp_open(devdata, + opcode, (char **)param); + + return err; +} + + +static u16 isp_mast_calculate_check_sum(u8 *input_buffer_addr, + u16 input_buffer_size, bool b2sCom) +{ + u16 i; + u32 sum = 0; + u16 sumvalue; + + for (i = 0; i < input_buffer_size; i++) { + if (0 == (i%2)) + sum += input_buffer_addr[i]; + else + sum += (input_buffer_addr[i] << 8); + } + + /* Do 2's complement*/ + if (b2sCom == true) + sumvalue = (u16) (65536 - (sum & 0x0000FFFF)); + /* Update total sum*/ + else + sumvalue = sum; + + return sumvalue; +} + + +/******End Of File******/ diff --git a/drivers/media/platform/altek/miniisp_chip_base_define.c b/drivers/media/platform/altek/miniisp_chip_base_define.c new file mode 100755 index 000000000000..ec995ea21731 --- /dev/null +++ b/drivers/media/platform/altek/miniisp_chip_base_define.c @@ -0,0 +1,756 @@ +/* + * File: miniisp_chip_base_define.c.c + * Description: Mini ISP ChipBase Define Code + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2017/10/18; Louis Wang; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + + /******Include File******/ +#include "linux/init.h" +#include "linux/module.h" + +#include "include/miniisp.h" +#include "include/error.h" +#include "include/miniisp_chip_base_define.h" +#include "include/miniisp_customer_define.h" + +#define MINI_ISP_LOG_TAG "[miniisp_chip_base_define]" + +/******Private Variable******/ +static u32 clk_gen_array[] = clk_gen_dump_field; +static u32 mipi_tx_phy_if_0_array[] = mipi_tx_phy_if_0_dump_field; +static u32 mipi_tx_phy_if_1_array[] = mipi_tx_phy_if_1_dump_field; +static u32 gen_reg_array[] = gen_reg_dump_field; +static u32 mipi_slvds_rx_phy_if_0_array[] = mipi_slvds_rx_phy_if_0_dump_field; +static u32 mipi_slvds_rx_phy_if_1_array[] = mipi_slvds_rx_phy_if_1_dump_field; +static u32 ppi_bridge_a_0_array[] = ppi_bridge_a_0_dump_field; +static u32 ppi_bridge_a_1_array[] = ppi_bridge_a_1_dump_field; +static u32 tx_top_out_mux_a_0_array[] = tx_top_out_mux_a_0_dump_field; +static u32 tx_top_out_mux_a_1_array[] = tx_top_out_mux_a_1_dump_field; +static u32 tx_line_merge_21_a_0_array[] = tx_line_merge_21_a_0_dump_field; +static u32 tx_line_merge_21_b_0_array[] = tx_line_merge_21_b_0_dump_field; +static u32 tx_line_merge_21_c_0_array[] = tx_line_merge_21_c_0_dump_field; +static u32 tx_line_merge_21_d_0_array[] = tx_line_merge_21_d_0_dump_field; +static u32 mipi_csi2_tx_0_array[] = mipi_csi2_tx_0_dump_field; +static u32 mipi_csi2_tx_1_array[] = mipi_csi2_tx_1_dump_field; +static u32 gen_reg_depth_top_array[] = gen_reg_depth_top_dump_field; +static u32 gen_reg_dpc_top_array[] = gen_reg_dpc_top_dump_field; +static u32 gen_reg_hdr_top_array[] = gen_reg_hdr_top_dump_field; +static u32 gen_reg_irp_top_array[] = gen_reg_irp_top_dump_field; +static u32 gen_reg_standby_top_array[] = gen_reg_standby_top_dump_field; +static u32 gen_reg_tx_top_array[] = gen_reg_tx_top_dump_field; +static u32 id_det_a_0_array[] = id_det_a_0_dump_field; +static u32 id_det_a_1_array[] = id_det_a_1_dump_field; +static u32 bayer_binning_a_0_array[] = bayer_binning_a_0_dump_field; +static u32 bayer_binning_a_1_array[] = bayer_binning_a_1_dump_field; +static u32 bayer_scl_a_0_array[] = bayer_scl_a_0_dump_field; +static u32 bayer_scl_a_1_array[] = bayer_scl_a_1_dump_field; +static u32 rlb_a_0_array[] = rlb_a_0_dump_field; +static u32 rlb_b_0_array[] = rlb_b_0_dump_field; +static u32 mipi_csi2_rx_0_array[] = mipi_csi2_rx_0_dump_field; +static u32 mipi_csi2_rx_1_array[] = mipi_csi2_rx_1_dump_field; +static u32 dg_ca_a_0_array[] = dg_ca_a_0_dump_field; +static u32 dg_mcc_a_0_array[] = dg_mcc_a_0_dump_field; +static u32 dp_top_a_0_array[] = dp_top_a_0_dump_field; +static u32 lvhwirp_top_a_0_array[] = lvhwirp_top_a_0_dump_field; +static u32 lvhwirp_top_b_0_array[] = lvhwirp_top_b_0_dump_field; +static u32 lvlumanr_a_0_array[] = lvlumanr_a_0_dump_field; +static u32 lvlumanr_a_1_array[] = lvlumanr_a_1_dump_field; +static u32 lvsharp_a_0_array[] = lvsharp_a_0_dump_field; +static u32 lvsharp_a_1_array[] = lvsharp_a_1_dump_field; +static u32 rectify_a_0_array[] = rectify_a_0_dump_field; +static u32 rectify_b_0_array[] = rectify_b_0_dump_field; +static u32 hdr_ae_a_0_array[] = hdr_ae_a_0_dump_field; +static u32 hdr_ae_a_1_array[] = hdr_ae_a_1_dump_field; + +/******Public Function******/ + +void mini_isp_chip_base_define_module_reg_dump( + char *dest_path, char *module_name) +{ + int i = 0; + + /*clk_gen*/ + if (strcmp(module_name, "clk_gen") == 0) + for (i = 0; i < sizeof(clk_gen_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + clk_gen_array[i], + clk_gen_array[i+1], + dest_path, + module_name); + /*mipi_tx_phy_if_0*/ + else if (strcmp(module_name, "mipi_tx_phy_if_0") == 0) + for (i = 0; i < sizeof(mipi_tx_phy_if_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + mipi_tx_phy_if_0_array[i], + mipi_tx_phy_if_0_array[i+1], + dest_path, + module_name); + /*mipi_tx_phy_if_1*/ + else if (strcmp(module_name, "mipi_tx_phy_if_1") == 0) + for (i = 0; i < sizeof(mipi_tx_phy_if_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + mipi_tx_phy_if_1_array[i], + mipi_tx_phy_if_1_array[i+1], + dest_path, + module_name); + /*gen_reg*/ + else if (strcmp(module_name, "gen_reg") == 0) + for (i = 0; i < sizeof(gen_reg_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + gen_reg_array[i], + gen_reg_array[i+1], + dest_path, + module_name); + /*mipi_slvds_rx_phy_if_0*/ + else if (strcmp(module_name, "mipi_slvds_rx_phy_if_0") == 0) + for (i = 0; + i < sizeof(mipi_slvds_rx_phy_if_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + mipi_slvds_rx_phy_if_0_array[i], + mipi_slvds_rx_phy_if_0_array[i+1], + dest_path, + module_name); + /*mipi_slvds_rx_phy_if_1*/ + else if (strcmp(module_name, "mipi_slvds_rx_phy_if_1") == 0) + for (i = 0; + i < sizeof(mipi_slvds_rx_phy_if_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + mipi_slvds_rx_phy_if_1_array[i], + mipi_slvds_rx_phy_if_1_array[i+1], + dest_path, + module_name); + /*ppi_bridge_a_0*/ + else if (strcmp(module_name, "ppi_bridge_a_0") == 0) + for (i = 0; i < sizeof(ppi_bridge_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + ppi_bridge_a_0_array[i], + ppi_bridge_a_0_array[i+1], + dest_path, + module_name); + /*ppi_bridge_a_1*/ + else if (strcmp(module_name, "ppi_bridge_a_1") == 0) + for (i = 0; i < sizeof(ppi_bridge_a_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + ppi_bridge_a_1_array[i], + ppi_bridge_a_1_array[i+1], + dest_path, + module_name); + /*tx_top_out_mux_a_0*/ + else if (strcmp(module_name, "tx_top_out_mux_a_0") == 0) + for (i = 0; i < sizeof(tx_top_out_mux_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + tx_top_out_mux_a_0_array[i], + tx_top_out_mux_a_0_array[i+1], + dest_path, + module_name); + /*tx_top_out_mux_a_1*/ + else if (strcmp(module_name, "tx_top_out_mux_a_1") == 0) + for (i = 0; i < sizeof(tx_top_out_mux_a_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + tx_top_out_mux_a_1_array[i], + tx_top_out_mux_a_1_array[i+1], + dest_path, + module_name); + /*tx_line_merge_21_a_0*/ + else if (strcmp(module_name, "tx_line_merge_21_a_0") == 0) + for (i = 0; + i < sizeof(tx_line_merge_21_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + tx_line_merge_21_a_0_array[i], + tx_line_merge_21_a_0_array[i+1], + dest_path, + module_name); + /*tx_line_merge_21_b_0*/ + else if (strcmp(module_name, "tx_line_merge_21_b_0") == 0) + for (i = 0; + i < sizeof(tx_line_merge_21_b_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + tx_line_merge_21_b_0_array[i], + tx_line_merge_21_b_0_array[i+1], + dest_path, + module_name); + /*tx_line_merge_21_c_0*/ + else if (strcmp(module_name, "tx_line_merge_21_c_0") == 0) + for (i = 0; + i < sizeof(tx_line_merge_21_c_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + tx_line_merge_21_c_0_array[i], + tx_line_merge_21_c_0_array[i+1], + dest_path, + module_name); + /*tx_line_merge_21_d_0*/ + else if (strcmp(module_name, "tx_line_merge_21_d_0") == 0) + for (i = 0; + i < sizeof(tx_line_merge_21_d_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + tx_line_merge_21_d_0_array[i], + tx_line_merge_21_d_0_array[i+1], + dest_path, + module_name); + /*mipi_csi2_tx_0*/ + else if (strcmp(module_name, "mipi_csi2_tx_0") == 0) + for (i = 0; i < sizeof(mipi_csi2_tx_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + mipi_csi2_tx_0_array[i], + mipi_csi2_tx_0_array[i+1], + dest_path, + module_name); + /*mipi_csi2_tx_1*/ + else if (strcmp(module_name, "mipi_csi2_tx_1") == 0) + for (i = 0; i < sizeof(mipi_csi2_tx_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + mipi_csi2_tx_1_array[i], + mipi_csi2_tx_1_array[i+1], + dest_path, + module_name); + /*gen_reg_depth_top*/ + else if (strcmp(module_name, "gen_reg_depth_top") == 0) + for (i = 0; i < sizeof(gen_reg_depth_top_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + gen_reg_depth_top_array[i], + gen_reg_depth_top_array[i+1], + dest_path, + module_name); + /*gen_reg_dpc_top*/ + else if (strcmp(module_name, "gen_reg_dpc_top") == 0) + for (i = 0; i < sizeof(gen_reg_dpc_top_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + gen_reg_dpc_top_array[i], + gen_reg_dpc_top_array[i+1], + dest_path, + module_name); + /*gen_reg_hdr_top*/ + else if (strcmp(module_name, "gen_reg_hdr_top") == 0) + for (i = 0; i < sizeof(gen_reg_hdr_top_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + gen_reg_hdr_top_array[i], + gen_reg_hdr_top_array[i+1], + dest_path, + module_name); + /*gen_reg_irp_top*/ + else if (strcmp(module_name, "gen_reg_irp_top") == 0) + for (i = 0; i < sizeof(gen_reg_irp_top_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + gen_reg_irp_top_array[i], + gen_reg_irp_top_array[i+1], + dest_path, + module_name); + /*gen_reg_standby_top*/ + else if (strcmp(module_name, "gen_reg_standby_top") == 0) + for (i = 0; i < sizeof(gen_reg_standby_top_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + gen_reg_standby_top_array[i], + gen_reg_standby_top_array[i+1], + dest_path, + module_name); + /*gen_reg_tx_top*/ + else if (strcmp(module_name, "gen_reg_tx_top") == 0) + for (i = 0; i < sizeof(gen_reg_tx_top_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + gen_reg_tx_top_array[i], + gen_reg_tx_top_array[i+1], + dest_path, + module_name); + /*id_det_a_0*/ + else if (strcmp(module_name, "id_det_a_0") == 0) + for (i = 0; i < sizeof(id_det_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + id_det_a_0_array[i], + id_det_a_0_array[i+1], + dest_path, + module_name); + /*id_det_a_1*/ + else if (strcmp(module_name, "id_det_a_1") == 0) + for (i = 0; i < sizeof(id_det_a_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + id_det_a_1_array[i], + id_det_a_1_array[i+1], + dest_path, + module_name); + /*bayer_binning_a_0*/ + else if (strcmp(module_name, "bayer_binning_a_0") == 0) + for (i = 0; i < sizeof(bayer_binning_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + bayer_binning_a_0_array[i], + bayer_binning_a_0_array[i+1], + dest_path, + module_name); + /*bayer_binning_a_1*/ + else if (strcmp(module_name, "bayer_binning_a_1") == 0) + for (i = 0; i < sizeof(bayer_binning_a_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + bayer_binning_a_1_array[i], + bayer_binning_a_1_array[i+1], + dest_path, + module_name); + /*bayer_scl_a_0*/ + else if (strcmp(module_name, "bayer_scl_a_0") == 0) + for (i = 0; i < sizeof(bayer_scl_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + bayer_scl_a_0_array[i], + bayer_scl_a_0_array[i+1], + dest_path, + module_name); + /*bayer_scl_a_1*/ + else if (strcmp(module_name, "bayer_scl_a_1") == 0) + for (i = 0; i < sizeof(bayer_scl_a_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + bayer_scl_a_1_array[i], + bayer_scl_a_1_array[i+1], + dest_path, + module_name); + /*rlb_a_0*/ + else if (strcmp(module_name, "rlb_a_0") == 0) + for (i = 0; i < sizeof(rlb_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + rlb_a_0_array[i], + rlb_a_0_array[i+1], + dest_path, + module_name); + /*rlb_b_0*/ + else if (strcmp(module_name, "rlb_b_0") == 0) + for (i = 0; i < sizeof(rlb_b_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + rlb_b_0_array[i], + rlb_b_0_array[i+1], + dest_path, + module_name); + /*mipi_csi2_rx_0*/ + else if (strcmp(module_name, "mipi_csi2_rx_0") == 0) + for (i = 0; i < sizeof(mipi_csi2_rx_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + mipi_csi2_rx_0_array[i], + mipi_csi2_rx_0_array[i+1], + dest_path, + module_name); + /*mipi_csi2_rx_1*/ + else if (strcmp(module_name, "mipi_csi2_rx_1") == 0) + for (i = 0; i < sizeof(mipi_csi2_rx_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + mipi_csi2_rx_1_array[i], + mipi_csi2_rx_1_array[i+1], + dest_path, + module_name); + /*dg_ca_a_0*/ + else if (strcmp(module_name, "dg_ca_a_0") == 0) + for (i = 0; i < sizeof(dg_ca_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + dg_ca_a_0_array[i], + dg_ca_a_0_array[i+1], + dest_path, + module_name); + /*dg_mcc_a_0*/ + else if (strcmp(module_name, "dg_mcc_a_0") == 0) + for (i = 0; i < sizeof(dg_mcc_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + dg_mcc_a_0_array[i], + dg_mcc_a_0_array[i+1], + dest_path, + module_name); + /*dp_top_a_0*/ + else if (strcmp(module_name, "dp_top_a_0") == 0) + for (i = 0; i < sizeof(dp_top_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + dp_top_a_0_array[i], + dp_top_a_0_array[i+1], + dest_path, + module_name); + /*lvhwirp_top_a_0*/ + else if (strcmp(module_name, "lvhwirp_top_a_0") == 0) + for (i = 0; i < sizeof(lvhwirp_top_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + lvhwirp_top_a_0_array[i], + lvhwirp_top_a_0_array[i+1], + dest_path, + module_name); + /*lvhwirp_top_b_0*/ + else if (strcmp(module_name, "lvhwirp_top_b_0") == 0) + for (i = 0; i < sizeof(lvhwirp_top_b_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + lvhwirp_top_b_0_array[i], + lvhwirp_top_b_0_array[i+1], + dest_path, + module_name); + /*lvlumanr_a_0*/ + else if (strcmp(module_name, "lvlumanr_a_0") == 0) + for (i = 0; i < sizeof(lvlumanr_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + lvlumanr_a_0_array[i], + lvlumanr_a_0_array[i+1], + dest_path, + module_name); + /*lvlumanr_a_1*/ + else if (strcmp(module_name, "lvlumanr_a_1") == 0) + for (i = 0; i < sizeof(lvlumanr_a_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + lvlumanr_a_1_array[i], + lvlumanr_a_1_array[i+1], + dest_path, + module_name); + /*lvsharp_a_0*/ + else if (strcmp(module_name, "lvsharp_a_0") == 0) + for (i = 0; i < sizeof(lvsharp_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + lvsharp_a_0_array[i], + lvsharp_a_0_array[i+1], + dest_path, + module_name); + /*lvsharp_a_1*/ + else if (strcmp(module_name, "lvsharp_a_1") == 0) + for (i = 0; i < sizeof(lvsharp_a_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + lvsharp_a_1_array[i], + lvsharp_a_1_array[i+1], + dest_path, + module_name); + /*rectify_a_0*/ + else if (strcmp(module_name, "rectify_a_0") == 0) + for (i = 0; i < sizeof(rectify_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + rectify_a_0_array[i], + rectify_a_0_array[i+1], + dest_path, + module_name); + /*rectify_b_0*/ + else if (strcmp(module_name, "rectify_b_0") == 0) + for (i = 0; i < sizeof(rectify_b_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + rectify_b_0_array[i], + rectify_b_0_array[i+1], + dest_path, + module_name); + /*hdr_ae_a_0*/ + else if (strcmp(module_name, "hdr_ae_a_0") == 0) + for (i = 0; i < sizeof(hdr_ae_a_0_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + hdr_ae_a_0_array[i], + hdr_ae_a_0_array[i+1], + dest_path, + module_name); + /*hdr_ae_a_1*/ + else if (strcmp(module_name, "hdr_ae_a_1") == 0) + for (i = 0; i < sizeof(hdr_ae_a_1_array)/(sizeof(u32)); + i = i + 2) + mini_isp_register_read_then_write_file( + hdr_ae_a_1_array[i], + hdr_ae_a_1_array[i+1], + dest_path, + module_name); + else + misp_err("%s %s dump field not exit, please add", + __func__, module_name); +} + +/** + *\brief dump bypass mode reg + *\descript should use SPI e mode or I2C slave + *\return Error code + */ +errcode mini_isp_chip_base_dump_bypass_mode_register(char *dest_path) +{ + errcode err = ERR_SUCCESS; + + /*clk_gen*/ + misp_info("%s clk_gen", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "clk_gen"); + /*mipi_tx_phy_if_0*/ + misp_info("%s mipi_tx_phy_if_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_tx_phy_if_0"); + /*mipi_tx_phy_if_1*/ + misp_info("%s mipi_tx_phy_if_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_tx_phy_if_1"); + /*gen_reg*/ + misp_info("%s gen_reg", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "gen_reg"); + /*mipi_slvds_rx_phy_if_0*/ + misp_info("%s mipi_slvds_rx_phy_if_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_slvds_rx_phy_if_0"); + /*mipi_slvds_rx_phy_if_1*/ + misp_info("%s mipi_slvds_rx_phy_if_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_slvds_rx_phy_if_1"); + /*ppi_bridge_a_0*/ + misp_info("%s ppi_bridge_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "ppi_bridge_a_0"); + /*ppi_bridge_a_1*/ + misp_info("%s ppi_bridge_a_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "ppi_bridge_a_1"); + return err; +} + + +/** + *\brief dump normal mode reg + *\descript should use SPI e mode or I2C slave + *\return Error code + */ +errcode mini_isp_chip_base_dump_normal_mode_register(char *dest_path) +{ + errcode err = ERR_SUCCESS; + + /*clk_gen*/ + misp_info("%s clk_gen", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "clk_gen"); + /*tx_top_out_mux_a_0*/ + misp_info("%s tx_top_out_mux_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "tx_top_out_mux_a_0"); + /*tx_top_out_mux_a_1*/ + misp_info("%s tx_top_out_mux_a_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "tx_top_out_mux_a_1"); + /*tx_line_merge_21_a_0*/ + misp_info("%s tx_line_merge_21_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "tx_line_merge_21_a_0"); + /*tx_line_merge_21_b_0*/ + misp_info("%s tx_line_merge_21_b_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "tx_line_merge_21_b_0"); + /*tx_line_merge_21_c_0*/ + misp_info("%s tx_line_merge_21_c_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "tx_line_merge_21_c_0"); + /*tx_line_merge_21_d_0*/ + misp_info("%s tx_line_merge_21_d_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "tx_line_merge_21_d_0"); + /*mipi_csi2_tx_0*/ + misp_info("%s mipi_csi2_tx_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_csi2_tx_0"); + /*mipi_tx_phy_if_0*/ + misp_info("%s mipi_tx_phy_if_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_tx_phy_if_0"); + /*mipi_csi2_tx_1*/ + misp_info("%s mipi_csi2_tx_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_csi2_tx_1"); + /*mipi_tx_phy_if_1*/ + misp_info("%s mipi_tx_phy_if_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_tx_phy_if_1"); + /*gen_reg_depth_top*/ + misp_info("%s gen_reg_depth_top", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "gen_reg_depth_top"); + /*gen_reg_dpc_top*/ + misp_info("%s gen_reg_dpc_top", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "gen_reg_dpc_top"); + /*gen_reg_hdr_top*/ + misp_info("%s gen_reg_hdr_top", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "gen_reg_hdr_top"); + /*gen_reg_irp_top*/ + misp_info("%s gen_reg_irp_top", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "gen_reg_irp_top"); + /*gen_reg_standby_top*/ + misp_info("%s gen_reg_standby_top", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "gen_reg_standby_top"); + /*gen_reg_tx_top*/ + misp_info("%s gen_reg_tx_top", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "gen_reg_tx_top"); + /*id_det_a_0*/ + misp_info("%s id_det_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "id_det_a_0"); + /*id_det_a_1*/ + misp_info("%s id_det_a_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "id_det_a_1"); + /*bayer_binning_a_0*/ + misp_info("%s bayer_binning_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "bayer_binning_a_0"); + /*bayer_binning_a_1*/ + misp_info("%s bayer_binning_a_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "bayer_binning_a_1"); + /*bayer_scl_a_0*/ + misp_info("%s bayer_scl_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "bayer_scl_a_0"); + /*bayer_scl_a_1*/ + misp_info("%s bayer_scl_a_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "bayer_scl_a_1"); + /*rlb_a_0*/ + misp_info("%s rlb_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "rlb_a_0"); + /*rlb_b_0*/ + misp_info("%s rlb_b_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "rlb_b_0"); + /*mipi_slvds_rx_phy_if_0*/ + misp_info("%s mipi_slvds_rx_phy_if_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_slvds_rx_phy_if_0"); + /*mipi_csi2_rx_0*/ + misp_info("%s mipi_csi2_rx_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_csi2_rx_0"); + /*mipi_slvds_rx_phy_if_1*/ + misp_info("%s mipi_slvds_rx_phy_if_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_slvds_rx_phy_if_1"); + /*mipi_csi2_rx_1*/ + misp_info("%s mipi_csi2_rx_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "mipi_csi2_rx_1"); + /*ppi_bridge_a_0*/ + misp_info("%s ppi_bridge_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "ppi_bridge_a_0"); + /*ppi_bridge_a_1*/ + misp_info("%s ppi_bridge_a_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "ppi_bridge_a_1"); + /*hdr_ae_a_0*/ + misp_info("%s hdr_ae_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "hdr_ae_a_0"); + /*hdr_ae_a_1*/ + misp_info("%s hdr_ae_a_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "hdr_ae_a_1"); + /*gen_reg*/ + misp_info("%s gen_reg", __func__); + mini_isp_chip_base_define_module_reg_dump( + dest_path, "gen_reg"); + return err; +} + +/** + *\brief dump irp and depth based reg + *\descript should use SPI e mode or I2C slave + *\return Error code + */ +errcode mini_isp_chip_base_dump_irp_and_depth_based_register(void) +{ + errcode err = ERR_SUCCESS; + + /*dg_ca_a_0*/ + misp_info("%s dg_ca_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "dg_ca_a_0"); + /*dg_mcc_a_0*/ + misp_info("%s dg_mcc_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "dg_mcc_a_0"); + /*dp_top_a_0*/ + misp_info("%s dp_top_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "dp_top_a_0"); + /*lvhwirp_top_a_0*/ + misp_info("%s lvhwirp_top_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "lvhwirp_top_a_0"); + /*lvhwirp_top_b_0*/ + misp_info("%s lvhwirp_top_b_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "lvhwirp_top_b_0"); + /*lvlumanr_a_0*/ + misp_info("%s lvlumanr_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "lvlumanr_a_0"); + /*lvlumanr_a_1*/ + misp_info("%s lvlumanr_a_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "lvlumanr_a_1"); + /*lvsharp_a_0*/ + misp_info("%s lvsharp_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "lvsharp_a_0"); + /*lvsharp_a_1*/ + misp_info("%s lvsharp_a_1", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "lvsharp_a_1"); + /*rectify_a_0*/ + misp_info("%s rectify_a_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "rectify_a_0"); + /*rectify_b_0*/ + misp_info("%s rectify_b_0", __func__); + mini_isp_chip_base_define_module_reg_dump( + MINIISP_INFO_DUMPLOCATION, "rectify_b_0"); + return err; +} diff --git a/drivers/media/platform/altek/miniisp_ctrl.c b/drivers/media/platform/altek/miniisp_ctrl.c new file mode 100755 index 000000000000..63e82bbfc50b --- /dev/null +++ b/drivers/media/platform/altek/miniisp_ctrl.c @@ -0,0 +1,1901 @@ +/* + * File: miniisp_ctrl.c + * Description: Mini ISP Ctrl sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/10/14; Aaron Chuang; Initial version + * 2013/12/05; Bruce Chung; 2nd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/******Include File******/ +#include + +#include "include/miniisp_customer_define.h" +#include "include/ispctrl_if_master.h" +#include "include/miniisp_ctrl.h" +#include "include/error/altek_state_err.h" +#include "include/miniisp_chip_base_define.h" +/******Private Constant Definition******/ +#define MINI_ISP_LOG_TAG "[miniisp_ctrl]" + +/******Private Function Prototype******/ + +static int load_code_task(void *data); +#if (!ENABLE_LINUX_FW_LOADER) +static u16 calibration_check_sum(u8 *input_buffer_addr, u16 input_buffer_size); +#endif +/******Private Type Declaration******/ + + +/******Private Global Variable******/ + +static struct memmory_dump_hdr_info mem_dum_hdr_cfg = {0}; +static struct common_log_hdr_info com_log_hdr_cfg = {0}; +static bool stop_to_log; + +/*Command parameter buffer*/ +/*static u8 cmd_param_buf[T_SPI_CMD_LENGTH];*/ +static u8 rcv_cmd_param_buf[T_SPI_CMD_LENGTH]; + + +bool load_code_ready; + +/******Public Global Variable******/ + + +/******Public Function******/ + +/*************************************************************************/ +/*operation cmd*/ + +/** + *\brief Mini ISP open 0x4000 + *\param boot_code_file_name [In], Boot code filename + *\param basic_code_file_name [In], Basic code filename + *\param advanced_code_file_name [In], Advanced code filename + *\param scenario_table_file_name [In], SC table filename + *\param hdr_qmerge_data_file_name [In], HDR Qmerge data filename + *\param irp0_qmerge_data_file_name [In], IRP0 Qmerge data filename + *\param irp1_qmerge_data_file_name [In], IRP1 Qmerge data filename + *\param pp_map_file_name [In], pp map filename + *\return Error code + */ +errcode mini_isp_drv_open(char *pBoot_code_file_name, + char *pBasic_code_file_name, + char *pAdvanced_code_file_name, + char *pScenario_table_file_name, + char *pHdr_qmerge_data_file_name, + char *pIrp0_qmerge_data_file_name, + char *pIrp1_qmerge_data_file_name, + char *pPP_map_file_name, + char *pDepth_qmerge_file_name) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_MINIISPOPEN; /*0x4000*/ + char *cmd_param_buf[9]; + + /* Command parameter buffer*/ + memset(cmd_param_buf, 0, sizeof(cmd_param_buf)); + misp_info("%s - start", __func__); + /* Parameter 0 boot code filename*/ + cmd_param_buf[0] = pBoot_code_file_name; + /* Parameter 1 basic code filename*/ + cmd_param_buf[1] = pBasic_code_file_name; + /* Parameter 2 advanced code filename*/ + cmd_param_buf[2] = pAdvanced_code_file_name; + /* Parameter 3 calibration filename(sc atable)*/ + cmd_param_buf[3] = pScenario_table_file_name; + /* Parameter 4 hdr qmerge data filename*/ + cmd_param_buf[4] = pHdr_qmerge_data_file_name; + /* Parameter 5 irp0 qmerge data filename*/ + cmd_param_buf[5] = pIrp0_qmerge_data_file_name; + /* Parameter 6 irp1 qmerge data filename*/ + cmd_param_buf[6] = pIrp1_qmerge_data_file_name; + /* Parameter 7 PP map filename*/ + cmd_param_buf[7] = pPP_map_file_name; + /* Parameter 8 depth qmerge filename*/ + cmd_param_buf[8] = pDepth_qmerge_file_name; + + /* mini ISP open*/ + err = ispctrl_if_mast_execute_cmd(opcode, (u8 *)cmd_param_buf); + + if (err != ERR_SUCCESS) + misp_err("%s open file failed. err: 0x%x", __func__, err); + else + misp_info("%s - open files success", __func__); + + return err; + +} + +/*************************************************************************/ +/*bulk cmd*/ + +/** + *\brief Mini ISP write boot code 0x2008 + *\return Error code + */ +errcode mini_isp_drv_write_boot_code(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + u16 opcode = ISPCMD_BULK_WRITE_BOOTCODE; /*0x2008*/ + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + misp_info("%s write boot code state: %d", __func__, err); + + return err; +} + +/** + *\brief Mini ISP write boot code (short SPI Len) 0x2009 + *\return Error code + */ +errcode mini_isp_drv_write_boot_code_shortlen(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + u16 opcode = ISPCMD_BULK_WRITE_BOOTCODE_SHORT_LEN; /*0x2009*/ + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + misp_info("%s write boot code state: %d", __func__, err); + return err; +} +/** + *\brief Mini ISP write basic code 0x2002 + *\return Error code + */ +errcode mini_isp_drv_write_basic_code(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + u16 opcode = ISPCMD_BULK_WRITE_BASICCODE; /*0x2002*/ + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + misp_info("%s write basic code state: %d", __func__, err); + + return err; +} + +/** + *\brief Mini ISP write basic code (short SPI Len) 0x2003/0x2004/0x2005 + *\return Error code + */ +errcode mini_isp_drv_write_basic_code_shortlen(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + u16 opcode = ISPCMD_BULK_WRITE_BASICCODE_CODESUM; /*0x2005*/ + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + misp_info("%s write basic code state: %d", __func__, err); + return err; +} + +/** + *\brief MiniISP Write Calibration Data 0x210B + *\param info_id [In], 0 : boot data + * 1 : basic data + *\return Error code + */ +errcode mini_isp_drv_write_spinor_data(u8 info_id) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u16 opcode = ISPCMD_BULK_WRITE_SPINOR_DATA; /*0x210E*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + /* Parameter 8 Info ID*/ + cmd_param_buf[8] = info_id; + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + misp_info("%s write calibration data state: %d", __func__, err); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_write_spinor_data); + +#if ENABLE_LINUX_FW_LOADER +/** + *\brief MiniISP Write Calibration Data 0x210B + *\param info_id [In], 0 : IQ data + * 1 : packet data + * 2 : scenario table + * 3 : qmerge hdr + * 4 : qmerge irp0 + * 5 : qmerge irp1 + * 6 : PP map + * 7 : blending table + * 8 : qmerge depth + * 9 : OTP data + *\param buf_addr [In], otp/packet data buffer start address + *\param buf_len [In], otp/packet data buffer len + *\return Error code + */ +errcode mini_isp_drv_write_calibration_data(u8 info_id, u8 *buf_addr, + u32 buf_len) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u16 opcode = ISPCMD_BULK_WRITE_CALIBRATION_DATA; /*0x210B*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + u8 *allocated_memmory = 0; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + /* + *misp_info("%s info_id %d buf_addr %p buf_len %d", + * __func__, info_id, buf_addr, buf_len); + */ + /* Parameter 0 Info ID*/ + cmd_param_buf[8] = info_id; + if (((info_id >= 2) && (info_id < 7)) || (info_id == 8)) { + err = ispctrl_if_mast_execute_cmd(opcode, + cmd_param_buf); + } else { + /* Request memory*/ + allocated_memmory = kzalloc(buf_len+T_SPI_CMD_LENGTH, + GFP_KERNEL); + if (!allocated_memmory) { + err = ~ERR_SUCCESS; + goto allocate_memory_fail; + } + + /* fill checksum and block size at + * mast_bulk_data_cmd_write_calibration_data api + */ + memcpy(allocated_memmory + T_SPI_CMD_LENGTH, + buf_addr, buf_len); + memcpy(allocated_memmory, &buf_len, sizeof(u32)); + memcpy(allocated_memmory + 8, &info_id, sizeof(u8)); + + /* + *misp_info("%s Cal_param[0][1][2][3]:%02x %02x %02x %02x", + * __func__, allocated_memmory[0], + * allocated_memmory[1], + * allocated_memmory[2], + * allocated_memmory[3]); + *misp_info("%s Cal_param[4][5][6][7]:%02x %02x %02x %02x", + * __func__, allocated_memmory[4], + * allocated_memmory[5], + * allocated_memmory[6], + * allocated_memmory[7]); + *misp_info("%s Cal_param[8][9][10]:%02x %02x %02x", + * __func__, allocated_memmory[8], + * allocated_memmory[9], + * allocated_memmory[10]); + */ + err = ispctrl_if_mast_execute_cmd(opcode, + allocated_memmory); + kfree(allocated_memmory); + } + misp_info("%s write calibration data state: %d", __func__, err); + + + goto miniisp_drv_write_calibration_data_end; +allocate_memory_fail: + misp_err("%s Allocate memory failed.", __func__); + kfree(allocated_memmory); +miniisp_drv_write_calibration_data_end: + + return err; + +} +EXPORT_SYMBOL(mini_isp_drv_write_calibration_data); + +#else +/** + *\brief MiniISP Write Calibration Data 0x210B + *\param info_id [In], 0 : IQ data + * 1 : packet data + * 2 : scenario table + * 3 : qmerge hdr + * 4 : qmerge irp0 + * 5 : qmerge irp1 + * 6 : PP map + * 7 : blending table + * 8 : qmerge depth + * 9 : OTP data + *\param buf_addr [In], otp/packet data buffer start address + *\param buf_len [In], otp/packet data buffer len + *\return Error code + */ +errcode mini_isp_drv_write_calibration_data(u8 info_id, u8 *buf_addr, + u32 buf_len) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u16 opcode = ISPCMD_BULK_WRITE_CALIBRATION_DATA; /*0x210B*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + u16 chk_sum; + u32 block_size = 384*1024; + u8 *allocated_memmory = 0; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + if ((dev_global_variable->now_state != MINI_ISP_STANDBY) && + (dev_global_variable->now_state != MINI_ISP_SENSOR_MODE)) + return ERR_MINIISP_STATE_ERROR_SEQUENCE; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + /* + *misp_info("%s info_id %d buf_addr %p buf_len %d", + * __func__, info_id, buf_addr, buf_len); + */ + /* Parameter 0 Info ID*/ + cmd_param_buf[8] = info_id; + if (((info_id >= 2) && (info_id < 7)) || (info_id == 8)) { + err = ispctrl_if_mast_execute_cmd(opcode, + cmd_param_buf); + } else { + /* Request memory*/ + allocated_memmory = kzalloc(buf_len+T_SPI_CMD_LENGTH, + GFP_KERNEL); + if (!allocated_memmory) { + err = ~ERR_SUCCESS; + goto allocate_memory_fail; + } + memcpy(allocated_memmory + T_SPI_CMD_LENGTH, buf_addr, + buf_len); + memcpy(allocated_memmory, &buf_len, sizeof(u32)); + memcpy(allocated_memmory + 4, &block_size, sizeof(u32)); + memcpy(allocated_memmory + 8, &info_id, sizeof(u8)); + chk_sum = calibration_check_sum( + allocated_memmory + T_SPI_CMD_LENGTH, + buf_len); + memcpy(allocated_memmory+9, &chk_sum, sizeof(u16)); + /* + *misp_info("%s Cal_param[0][1][2][3]:%02x %02x %02x %02x", + * __func__, allocated_memmory[0], + * allocated_memmory[1], + * allocated_memmory[2], + * allocated_memmory[3]); + *misp_info("%s Cal_param[4][5][6][7]:%02x %02x %02x %02x", + * __func__, allocated_memmory[4], + * allocated_memmory[5], + * allocated_memmory[6], + * allocated_memmory[7]); + *misp_info("%s Cal_param[8][9][10]:%02x %02x %02x", + * __func__, allocated_memmory[8], + * allocated_memmory[9], + * allocated_memmory[10]); + */ + err = ispctrl_if_mast_execute_cmd(opcode, + allocated_memmory); + kfree(allocated_memmory); + } + misp_info("%s write calibration data state: %d", __func__, err); + + + goto miniisp_drv_write_calibration_data_end; +allocate_memory_fail: + misp_err("%s Allocate memory failed.", __func__); + kfree(allocated_memmory); +miniisp_drv_write_calibration_data_end: + + return err; + +} +EXPORT_SYMBOL(mini_isp_drv_write_calibration_data); +#endif + +/** + *\brief Read Calibration Data + *\param info_param [In], + *\return Error code + */ +errcode mini_isp_drv_read_calibration_data(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_BULK_READ_CALIBRATION_DATA; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + mem_dum_hdr_cfg.start_addr = EEPROM_BUFFER_ADDRESS; + mem_dum_hdr_cfg.total_size = EEPROM_BUFFER_SIZE; + if (SPI_SHORT_LEN_MODE_READ_ENABLE) + mem_dum_hdr_cfg.block_size = SPI_BLOCK_LEN; + else + mem_dum_hdr_cfg.block_size = SPI_TX_BULK_SIZE; + mem_dum_hdr_cfg.dump_mode = T_MEMDUMP_CPURUN; + + /*Copy it to transmission header*/ + memcpy(&cmd_param_buf[0], (u8 *)&mem_dum_hdr_cfg, + sizeof(struct memmory_dump_hdr_info)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_read_calibration_data); + +/** + *\brief Read memory + *\param start_addr [In]starting address + *\param read_size [In]TotalReadSize + *\return Error code + */ +errcode mini_isp_drv_read_memory(u32 start_addr, u32 read_size) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_BULK_READ_MEMORY; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + mem_dum_hdr_cfg.start_addr = start_addr;/*0x0;//0x9DC00;*/ + mem_dum_hdr_cfg.total_size = read_size;/*T_MEMSIZE;*/ + mem_dum_hdr_cfg.block_size = SPI_TX_BULK_SIZE; + mem_dum_hdr_cfg.dump_mode = T_MEMDUMP_CPURUN; + + /*Copy it to transmission header*/ + memcpy(&cmd_param_buf[0], (u8 *)&mem_dum_hdr_cfg, + sizeof(struct memmory_dump_hdr_info)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_read_memory); + +/** + *\brief Get Depth rect A, B, invrect parameter + *\param 0 : depth rect A, B InvRect parameter structure array buffer + *\param 1 : transfer mode. (Default set to 0) + *\param 2 : bluk block size + *\return Error code + */ +errcode mini_isp_drv_write_depth_rectab_invrect( + struct depth_rectab_invrect_param *rect_param, + u8 trans_mode, + u32 block_size) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_BULK_WRITE_DEPTH_RECTAB_INVRECT; /*0x210C*/ + u32 rect_set_num = 0; + u32 rectinfo_total_size = 0; + static struct isp_cmd_depth_rectab_invrect_info rect_info; + + if (trans_mode == 0) + rect_set_num = 3; + else + rect_set_num = 1; + + rectinfo_total_size + = rect_set_num*sizeof(struct depth_rectab_invrect_param); + /* copy to local static structure */ + memcpy(&(rect_info.rect_param[0]), rect_param, + rectinfo_total_size); + + rect_info.trans_mode = trans_mode; + rect_info.block_size = block_size; + + err = ispctrl_if_mast_execute_cmd(opcode, (u8 *)&rect_info); + return err; +} +EXPORT_SYMBOL(mini_isp_drv_write_depth_rectab_invrect); + +/** + *\brief Reading Common Log + *\param stop [In], Stop to log flag + *\return Error code + */ +errcode mini_isp_drv_read_com_log(bool stop) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_BULK_READ_COMLOG; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + /* Wait semaphore*/ + /*SEMAPHORE_LW_Wait( ISPCTRLIFMASTER_SEMAPHORE_LOGDUMP,*/ + /* SEMAPHORE_WAITFOREVER );*/ + + /* Force to stop log*/ + /*To inform isp to set log level as 0 for stoping log reight away*/ + if (stop) + mini_isp_drv_set_com_log_level(0); + + if (!stop_to_log) { + com_log_hdr_cfg.total_size = LEVEL_LOG_BUFFER_SIZE; + com_log_hdr_cfg.block_size = SPI_TX_BULK_SIZE; + + /*Copy it to transmission header*/ + memcpy(&cmd_param_buf[0], (u8 *)&com_log_hdr_cfg, + sizeof(struct common_log_hdr_info)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + /* Force to stop log*/ + if (stop) + stop_to_log = true; + } + + /* Post semaphore*/ + /*SEMAPHORE_LW_Post( ISPCTRLIFMASTER_SEMAPHORE_LOGDUMP );*/ + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_read_com_log); + +/*************************************************************************/ +/*camera profile cmd*/ + +/** + *\brief Set Sensor Mode 0x300A + *\param sensor_on_off [In],sensor on/off + *\param scenario_id[In], Scenario ID + *\param mipi_tx_skew_enable[In], mipi tx skew on(1)/off(0) + *\param ae_weighting_table_index[In] + *\param merge_mode_enable[In] + *\ bit[0:3] : + *\ set 0 for normal mode + *\ set 1 for merge mode, only for image samller than 640X480 case + *\ set 2 for depth test pattern mode + *\ bit[4] : + *\ set 0 for turn on sensor by AP. + *\ set 1 for turn on sensor by AL6100. + *\return Error code + */ +errcode mini_isp_drv_set_sensor_mode(u8 sensor_on_off, u8 scenario_id, + u8 mipi_tx_skew_enable, u8 ae_weighting_table_index, + u8 merge_mode_enable) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + misp_info("%s no FSM", __func__); + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + /* Parameter 0 sensor on/off*/ + cmd_param_buf[0] = sensor_on_off; + /* Parameter 1 Scenario ID*/ + cmd_param_buf[1] = scenario_id; + /* Parameter 2 mipi tx skew on/off*/ + cmd_param_buf[2] = mipi_tx_skew_enable; + /* Parameter 3 ae weighting table index*/ + cmd_param_buf[3] = ae_weighting_table_index; + /* Parameter 4 merge_mode_enable*/ + cmd_param_buf[4] = merge_mode_enable; + /* Parameter 5 reserve*/ + cmd_param_buf[5] = 0; + /* Parameter 6 reserve*/ + cmd_param_buf[6] = 0; + + if (sensor_on_off == 0) { + /* Set Sensor Mode*/ + err = ispctrl_if_mast_execute_cmd(ISPCMD_CAMERA_SET_SENSORMODE, + cmd_param_buf); + + if (err != 0) { + misp_err("%s err, error code = %x", + __func__, err); + return err; + } + } else { + /* Set Sensor Mode*/ + err = ispctrl_if_mast_execute_cmd(ISPCMD_CAMERA_SET_SENSORMODE, + cmd_param_buf); + if (err != 0) { + misp_err("%s err, error code = %x", + __func__, err); + return err; + } + } + return err; + +} +EXPORT_SYMBOL(mini_isp_drv_set_sensor_mode); + +/*0x300B*/ +errcode mini_isp_drv_get_sensor_mode(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_GET_SENSORMODE; /*0x300B*/ + err = ispctrl_if_mast_execute_cmd(opcode, rcv_cmd_param_buf); + + return err; + +} +EXPORT_SYMBOL(mini_isp_drv_get_sensor_mode); + +/* +brief Set Output format 0x300D +param1[In]depth_map_setting = resolution | opereation_mode +resolution + 0: Disable depth function (Depth engine is disable) + 1: 180p + 2: 360p + 3: 720p + 4: 480p + 5: 400p +opereation_mode, + 0x00: DEPTH_BIT_DG_ONLY + 0x10: DEPTH_BIT_DP + 0x40: DEPTH_BIT_HIGH_DISTORTION_RATE +*/ +/* + param2 [In]depth_process_type_and_qlevel = process_type | quality level + B[0:2] process_type: value 0x6 as reserve + B[3:6] quality level: 0 ~ 15 + + param3 [In] + B[0:0] InvRect bypass: set 1 for enable InvRect bypass. set 0 disable. + (This function is incompatible with + mini_isp_drv_write_depth_rectab_invrect, + Do not configure this bit if set + mini_isp_drv_write_depth_rectab_invrect before) + return Error code +*/ +errcode mini_isp_drv_set_output_format( + struct isp_cmd_set_output_format *output_format) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_SET_OUTPUTFORMAT; /*0x300D*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + memcpy(cmd_param_buf, output_format, + sizeof(struct isp_cmd_set_output_format)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; + +} +EXPORT_SYMBOL(mini_isp_drv_set_output_format); + +/** + *\brief Set CP mode 0x300E + *\return Error code + */ +errcode mini_isp_drv_set_cp_mode(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + misp_info("%s no FSM", __func__); + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) + mini_isp_e_to_a(); + + dev_global_variable->spi_low_speed_mode = 1; + + err = ispctrl_if_mast_execute_cmd(ISPCMD_CAMERA_SET_CP_MODE, + NULL); + if (err != 0) { + dev_global_variable->spi_low_speed_mode = 0; + return err; + } + + if (dev_global_variable->intf_status & INTF_SPI_READY) + mini_isp_a_to_e(); + /*enter code here*/ + mini_isp_cp_mode_suspend_flow(); + + if (err != 0) { + misp_err("%s err, error code = %x", __func__, err); + return err; + } + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_cp_mode); + +/** + *\brief Set AE statistics 0x300F + *\param ae_statistics [In], ae statistics + *\return Error code + */ +errcode mini_isp_drv_set_ae_statistics( + struct isp_cmd_ae_statistics *ae_statistics) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + misp_info("%s no FSM", __func__); + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, ae_statistics, + sizeof(struct isp_cmd_ae_statistics)); + err = ispctrl_if_mast_execute_cmd(ISPCMD_CAMERA_SET_AE_STATISTICS, + cmd_param_buf); + + if (err != 0) + misp_err("%s err, error code = %x", __func__, err); + + return err; + +} +EXPORT_SYMBOL(mini_isp_drv_set_ae_statistics); + +/** + *\brief Preview stream on/off 0x3010 + *\param tx0_stream_on_off [In], Tx0 stream on/off + *\param tx1_stream_on_off [In], Tx1 stream on/off + *\return Error code + */ +errcode mini_isp_drv_preview_stream_on_off(u8 tx0_stream_on_off, + u8 tx1_stream_on_off) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + misp_info("%s no FSM", __func__); + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + /* Parameter 0 Tx0 stream on/off*/ + cmd_param_buf[0] = tx0_stream_on_off; + /* Parameter 1 Tx1 stream on/off*/ + cmd_param_buf[1] = tx1_stream_on_off; + + err = ispctrl_if_mast_execute_cmd(ISPCMD_CAMERA_PREVIEWSTREAMONOFF, + cmd_param_buf); + + if (err != 0) + misp_err("%s err, error code = %x", __func__, err); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_preview_stream_on_off); + +/** + *\brief Dual PD Y Calcualtion Weighting 0x3011 + *\param isp_cmd_dual_pd_y_calculation_weightings [In], + dual PD Y calculation weightings + *\return Error code + */ +errcode mini_isp_drv_dual_pd_y_calculation_weighting( + struct isp_cmd_dual_pd_y_calculation_weightings *calculation_weighting) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_DUALPDYCALCULATIONWEIGHT; /*0x3010*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, calculation_weighting, + sizeof(struct isp_cmd_dual_pd_y_calculation_weightings)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_dual_pd_y_calculation_weighting); + + +/** + *\brief LED power control 0x3012 + *\param projector_control_param [In], + *\return Error code + */ +errcode mini_isp_drv_led_power_control( + struct isp_cmd_led_power_control *projector_control_param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_LED_POWERCONTROL; /*0x3012*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, projector_control_param, + sizeof(struct isp_cmd_led_power_control)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_led_power_control); + +/** + *\brief Active AE 0x3013 + *\param active_ae_param [In], + *\return Error code + */ +errcode mini_isp_drv_active_ae( + struct isp_cmd_active_ae *active_ae_param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_ACTIVE_AE; /*0x3013*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, active_ae_param, + sizeof(struct isp_cmd_active_ae)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_active_ae); + + +/** + *\brief ISP AE control mode on off 0x3014 + *\param isp_ae_control_mode_on_off [In], 0:off 1:on + *\return Error code + */ +errcode mini_isp_drv_isp_ae_control_mode_on_off(u8 isp_ae_control_mode_on_off) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_ISP_AECONTROLONOFF; /*0x3014*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + /* Parameter 0 isp_ae_control_mode_on_off*/ + cmd_param_buf[0] = isp_ae_control_mode_on_off; + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_isp_ae_control_mode_on_off); + +/** + *\brief Set Frame Rate Limite 0x3015 + *\param set_frame_rate_param [In], + *\return Error code + */ +errcode mini_isp_drv_set_frame_rate_limits( + struct isp_cmd_frame_rate_limits *set_frame_rate_param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_SET_FRAMERATELIMITS; /*0x3015*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, set_frame_rate_param, + sizeof(struct isp_cmd_frame_rate_limits)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_frame_rate_limits); + +/** + *\brief Set period drop frame 0x3016 + *\param set_period_drop_fram_param [In], + *\return Error code + */ +errcode mini_isp_drv_set_period_drop_frame( + struct isp_cmd_period_drop_frame *set_period_drop_fram_param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_SET_PERIODDROPFRAME; /*0x3016*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, set_period_drop_fram_param, + sizeof(struct isp_cmd_period_drop_frame)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_period_drop_frame); + +/** + *\brief Leave CP Mode + *\using set sensor mode opcode :0x300A + *\param sensor_on_off [In],sensor on/off + *\param scenario_id[In], Scenario ID + *\param mipi_tx_skew_enable[In], mipi tx skew on(1)/off(0) + *\param ae_weighting_table_index[In] + *\return Error code + */ +errcode mini_isp_drv_leave_cp_mode(u8 sensor_on_off, u8 scenario_id, + u8 mipi_tx_skew_enable, u8 ae_weighting_table_index, + u8 merge_mode_enable) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + int original_altek_spi_mode; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + original_altek_spi_mode = dev_global_variable->altek_spi_mode; + + misp_info("%s no FSM", __func__); + /* Parameter 0 sensor on/off*/ + cmd_param_buf[0] = sensor_on_off; + /* Parameter 1 Scenario ID*/ + cmd_param_buf[1] = scenario_id; + /* Parameter 2 mipi tx skew on/off*/ + cmd_param_buf[2] = mipi_tx_skew_enable; + /* Parameter 3 ae_weighting_table_index*/ + cmd_param_buf[3] = ae_weighting_table_index; + /* Parameter 4 merge_mode_enable*/ + cmd_param_buf[4] = merge_mode_enable; + /* Parameter 5 reserve*/ + cmd_param_buf[5] = 0; + /* Parameter 6 reserve*/ + cmd_param_buf[6] = 0; + + if (sensor_on_off) { + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (original_altek_spi_mode == ALTEK_SPI_MODE_A)) + mini_isp_a_to_e(); + mini_isp_cp_mode_resume_flow(); + + dev_global_variable->spi_low_speed_mode = 0; + + if (dev_global_variable->intf_status & INTF_SPI_READY) + mini_isp_e_to_a(); + + /* Set Sensor Mode*/ + err = ispctrl_if_mast_execute_cmd(ISPCMD_CAMERA_SET_SENSORMODE, + cmd_param_buf); + + if (err != 0) { + misp_err("mini_isp_drv_leave_cp_mode err, errcode = %x", + err); + return err; + } + } else { + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) + mini_isp_a_to_e(); + + mini_isp_cp_mode_resume_flow(); + dev_global_variable->spi_low_speed_mode = 0; + + if (dev_global_variable->intf_status & INTF_SPI_READY) + mini_isp_e_to_a(); + } + + return err; + +} +EXPORT_SYMBOL(mini_isp_drv_leave_cp_mode); + +/*************************************************************************/ +/*system cmd*/ + +/** + *\brief Set ISP register 0x0100 + *\param a_udStartAddr [In], Reg start addr + *\param reg_value [In], Reg value + *\return Error code + */ +errcode mini_isp_drv_set_isp_register(u32 reg_start_addr, u32 reg_value) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_SYSTEM_SET_ISPREGISTER; /*0x0100*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + /* Reg start addr*/ + memcpy(&cmd_param_buf[0], ®_start_addr, 4); + /* Reg count*/ + memcpy(&cmd_param_buf[4], ®_value, 4); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_isp_register); + + +/** + *\brief Set ISP register 0x0101 + *\param a_udStartAddr [In], Reg start addr + *\param reg_count [In], Reg count + *\return Error code + */ +errcode mini_isp_drv_get_isp_register(u32 reg_start_addr, u32 reg_count) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_SYSTEM_GET_ISPREGISTER; /*0x0101*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + /* Reg start addr*/ + memcpy(&cmd_param_buf[0], ®_start_addr, 4); + /* Reg count*/ + memcpy(&cmd_param_buf[4], ®_count, 4); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_get_isp_register); + + +errcode mini_isp_drv_set_com_log_level(u32 log_level) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_SYSTEM_SET_COMLOGLEVEL; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + memcpy(cmd_param_buf, &log_level, sizeof(u32)); + + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_com_log_level); + +/*0x0015*/ +errcode mini_isp_drv_get_last_exec_cmd(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_SYSTEM_GET_STATUSOFLASTEXECUTEDCOMMAND; /*0x0015*/ + err = ispctrl_if_mast_execute_cmd(opcode, rcv_cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_get_last_exec_cmd); + +/*0x0016*/ +errcode mini_isp_drv_get_err_code_cmd(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_SYSTEM_GET_ERRORCODE; /*0x0016*/ + err = ispctrl_if_mast_execute_cmd(opcode, rcv_cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_get_err_code_cmd); + +/*0x0016*/ +errcode mini_isp_drv_get_err_code_cmd_in_irq(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + void *devdata = (void *)get_mini_isp_intf(MINIISP_I2C_TOP); + u8 param[64]; + u32 al6100_errcode = 0; + /* Parameter size*/ + /*get last ten error code and error status*/ + u32 para_size = (sizeof(errcode))*10; + + misp_err("%s - enter + + + + +", __func__); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave( + devdata, ISPCMD_SYSTEM_GET_ERRORCODE, param, 0); + if (err != ERR_SUCCESS) + goto mast_sys_manage_cmd_get_error_code_command_end; + + /* Get data from slave*/ + err = ispctrl_mast_recv_response_from_slave(devdata, param, + para_size, false); + if (err != ERR_SUCCESS) + goto mast_sys_manage_cmd_get_error_code_command_end; + + al6100_errcode = *(u32 *)param; + misp_err("%s last error code %#x", __func__, al6100_errcode); + +mast_sys_manage_cmd_get_error_code_command_end: + + misp_err("%s - leave - - - - -", __func__); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_get_err_code_cmd_in_irq); + + +/** + *\brief Get Chip test Report 0x010A + *\return Error code + */ +errcode mini_isp_drv_get_chip_test_report(void) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_SYSTEM_GET_CHIPTESTREPORT; /*0x010A*/ + err = ispctrl_if_mast_execute_cmd(opcode, rcv_cmd_param_buf); + + misp_info("%s chip test report: %x %x %x %x", __func__, + rcv_cmd_param_buf[0], rcv_cmd_param_buf[1], + rcv_cmd_param_buf[2], rcv_cmd_param_buf[3]); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_get_chip_test_report); + +/*************************************************************************/ +/*basic cmd*/ + +/** + *\brief Set Depth 3A Information 0x10B9 + *\param depth_3a_info [In], ISP Depth 3A parameter + *\return Error code + */ +errcode mini_isp_drv_set_depth_3a_info( + struct isp_cmd_depth_3a_info *depth_3a_info) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u8 *param; + + misp_info("%s no FSM", __func__); + param = kzalloc(sizeof(struct isp_cmd_depth_3a_info), GFP_KERNEL); + if (param != NULL) { + /* Copy ISP Depth 3A Info*/ + memcpy(param, depth_3a_info, + sizeof(struct isp_cmd_depth_3a_info)); + } else { + misp_info("%s buf alloc fail!", __func__); + return err; + } + + err = ispctrl_if_mast_execute_cmd( + ISPCMD_BASIC_SET_DEPTH_3A_INFO, param); + + kfree(param); + + if (err != 0) + misp_err("%s err, error code = %x", __func__, err); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_depth_3a_info); + + +/** + *\brief Set Depth auto interleave mode 0x10BC + *\param depth_auto_interleave_param [In], ISP Depth auto interleave parameter + *\return Error code + */ +errcode mini_isp_drv_set_depth_auto_interleave_mode( + struct isp_cmd_depth_auto_interleave_param *depth_auto_interleave_param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_BASIC_SET_DEPTH_AUTO_INTERLEAVE_MODE; /*0x10BC*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, depth_auto_interleave_param, + sizeof(struct isp_cmd_depth_auto_interleave_param)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_depth_auto_interleave_mode); + +/** + *\brief Set Projector Interleave Mode with Depth Type 0x10BD + *\param projector_interleave_mode_with_depth_type [In], + *\ 0: depth active, 1: depth passive + *\return Error code + */ +errcode mini_isp_drv_projector_interleave_mode_depth_type( + u8 projector_interleave_mode_with_depth_type) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_BASIC_SET_INTERLEAVE_MODE_DEPTH_TYPE; /*0x10BD*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + cmd_param_buf[0] = projector_interleave_mode_with_depth_type; + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_projector_interleave_mode_depth_type); + +/** + *\brief Set Depth Polish LEVEL 0x10BE + *\param depth_polish_level [In], 0~100 + *\return Error code + */ +errcode mini_isp_drv_set_depth_polish_level(u8 depth_polish_level) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_BASIC_SET_DEPTH_POLISH_LEVEL; /*0x10BE*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + cmd_param_buf[0] = depth_polish_level; + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_depth_polish_level); + +/** + *\brief Set Exposure Parameter 0x10BF + *\param exposure_param [In], ISP Exposure parameter + *\return Error code + */ +errcode mini_isp_drv_set_exposure_param( + struct isp_cmd_exposure_param *exposure_param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_BASIC_SET_EXPOSURE_PARAM; /*0x10BF*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, exposure_param, + sizeof(struct isp_cmd_exposure_param)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_exposure_param); + +/** + *\brief Set Exposure Parameter 0x10BF + *\param exposure_param [In], ISP Exposure parameter + *\return Error code + */ +errcode mini_isp_drv_set_depth_stream_size( + struct isp_cmd_depth_stream_size *depth_stream_size) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_BASIC_SET_DEPTH_STREAM_SIZE; /*0x10C0*/ + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, depth_stream_size, + sizeof(struct isp_cmd_depth_stream_size)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_depth_stream_size); + +/*************************************************************************/ +/* cuurent no use +u16 mini_isp_drv_read_spi_status(void) +{ + return ispctrl_if_mast_read_spi_status(); +} +EXPORT_SYMBOL(mini_isp_drv_read_spi_status); +*/ +/** + *\brief Write boot code and basic code + *\param None + *\return None + */ +int mini_isp_drv_boot_mini_isp(void) +{ + errcode err = ERR_SUCCESS; + + + /* Write boot code*/ + err = mini_isp_drv_write_boot_code(); + if (err != ERR_SUCCESS) + goto mini_isp_drv_boot_mini_isp_end; + + udelay(500); + + /* Write basic code*/ + err = mini_isp_drv_write_basic_code(); + +mini_isp_drv_boot_mini_isp_end: + + return err; + +} +EXPORT_SYMBOL(mini_isp_drv_boot_mini_isp); + +/** + *\brief Write boot code and basic code (short SPI Len) + *\param None + *\return None + */ +int mini_isp_drv_boot_mini_isp_shortlen(void) +{ + errcode err = ERR_SUCCESS; + + + /* Write boot code*/ + err = mini_isp_drv_write_boot_code_shortlen(); + if (err != ERR_SUCCESS) + goto mini_isp_drv_boot_mini_isp_shortlen_end; + + udelay(500); + + /* Write basic code*/ + err = mini_isp_drv_write_basic_code_shortlen(); + +mini_isp_drv_boot_mini_isp_shortlen_end: + + return err; + +} +EXPORT_SYMBOL(mini_isp_drv_boot_mini_isp_shortlen); + +/** + *\brief Open boot and FW file then write boot code and FW code + *\param None + *\return Error code + */ +errcode mini_isp_drv_load_fw(void) +{ + errcode err = ERR_SUCCESS; + + misp_info("mini_isp_drv_setting(0) mini_isp_drv_load_fw start"); + /* Clear load code ready flag;*/ + load_code_ready = false; + /*spi isr task*/ + /*g_ptload_code_task = kthread_run(load_code_task, NULL, */ + /* "miniISP_loadcode_thread");*/ + + load_code_task(NULL); + + misp_info("mini_isp_drv_setting(0) mini_isp_drv_load_fw X"); + return err; + +} +EXPORT_SYMBOL(mini_isp_drv_load_fw); + +/** + *\brief Wait miniISP event + *\param e [In], MINI_ISP_EVENT + *\return Errorcode + */ +int mini_isp_drv_wait_for_event(u16 e) +{ + return mini_isp_wait_for_event(e); +} +EXPORT_SYMBOL(mini_isp_drv_wait_for_event); + + +/** + *\brief Set mode to miniISP + *\param mini_isp_mode [In], Select ISP MODE, + *0:(isp already in state A)normal case load FW directly, + *1 :(isp state inital in state E)set state E to state A + *2 :(isp already in state A)set state A to state E for debug , + *3 :leave HW bypass + *4 :Get Chip ID + *else : None Support + *\return Errorcode + */ +errcode mini_isp_drv_setting(u16 mini_isp_mode) +{ + errcode err = ERR_SUCCESS; + struct misp_global_variable *dev_global_variable; + + misp_info("%s no FSM", __func__); + dev_global_variable = get_mini_isp_global_variable(); + + if (mini_isp_mode == MINI_ISP_MODE_NORMAL) { + /*check bypass mode be set or not*/ + /*if yes, leave bypass mode*/ + mini_isp_check_and_leave_bypass_mode(); + /*normal case load FW*/ + err = mini_isp_drv_load_fw(); + + if (err != 0) + goto mini_isp_drv_setting_err; + } else if (mini_isp_mode == MINI_ISP_MODE_E2A) { + /*isp, inital in E,*/ + mini_isp_e_to_a(); + } else if (mini_isp_mode == MINI_ISP_MODE_A2E) { + mini_isp_a_to_e(); + } else if (mini_isp_mode == MINI_ISP_MODE_LEAVE_BYPASS) { + /*check bypass mode be set or not*/ + /*if yes, leave bypass mode*/ + mini_isp_check_and_leave_bypass_mode(); + if (err != 0) + goto mini_isp_drv_setting_err; + } else if (mini_isp_mode == MINI_ISP_MODE_GET_CHIP_ID) { + mini_isp_get_chip_id(); + } else if (mini_isp_mode == MINI_ISP_MODE_CHIP_INIT) { + /*set some reg value to let it know should chang to A*/ + /* For SPI_Nor, do not call this */ + mini_isp_chip_init(); + } else { + misp_err("%s err, none support setting", __func__); + } + return err; +mini_isp_drv_setting_err: + misp_err("%s err, mini_isp_mode = %d, error code = %x", __func__, + mini_isp_mode, err); + return err; +} +EXPORT_SYMBOL(mini_isp_drv_setting); + +void mini_isp_drv_altek_i2c_mode_change(void) +{ + mini_isp_register_write(0xffea0100, 0x3201); + mini_isp_register_write(0xffea0104, 0x3201); +} +EXPORT_SYMBOL(mini_isp_drv_altek_i2c_mode_change); + +/** + *\brief set bypass mode + *\param bypass_mode [In], Select bypass MODE, + *\return Errorcode + */ +errcode mini_isp_drv_set_bypass_mode(u16 bypass_mode) +{ + errcode err = ERR_SUCCESS; + misp_info("%s no FSM", __func__); + /*check bypass mode be set or not*/ + /*if yes, leave bypass mode*/ + mini_isp_check_and_leave_bypass_mode(); + /*Pure bypass by sensor*/ + err = mini_isp_pure_bypass(bypass_mode); + + if (err != 0) + goto mini_isp_drv_setting_err; + + return err; +mini_isp_drv_setting_err: + misp_err("%s err, bypass_mode = %d, error code = %x", __func__, + bypass_mode, err); + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_bypass_mode); + +/** + *\brief set Max exposure + *\param paramlength [In], Select bypass MODE, + *\return Errorcode + */ +errcode mini_isp_drv_set_max_exposure( + struct isp_cmd_exposure_param *max_exposure_info) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_SET_MAX_EXPOSURE; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + memcpy(cmd_param_buf, max_exposure_info, + sizeof(struct isp_cmd_exposure_param)); + + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_max_exposure); + +/** + *\brief set target mean + *\param paramlength [In], Select bypass MODE, + *\return Errorcode + */ +errcode mini_isp_drv_set_target_mean( + struct isp_cmd_target_mean *target_mean_info) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_SET_AE_TARGET_MEAN; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + memcpy(cmd_param_buf, target_mean_info, + sizeof(struct isp_cmd_target_mean)); + + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_target_mean); + +errcode mini_isp_drv_frame_sync_control( + struct isp_cmd_frame_sync_control *frame_sync_control_param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_FRAME_SYNC_CONTROL; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + memcpy(cmd_param_buf, frame_sync_control_param, + sizeof(struct isp_cmd_frame_sync_control)); + + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_frame_sync_control); + +errcode mini_isp_drv_set_shot_mode( + struct isp_cmd_set_shot_mode *set_shot_mode_param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_SET_SHOT_MODE; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + memcpy(cmd_param_buf, set_shot_mode_param, + sizeof(struct isp_cmd_set_shot_mode)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_shot_mode); + +errcode mini_isp_drv_lighting_ctrl( + struct isp_cmd_lighting_ctrl *lighting_ctrl) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_LIGHTING_CTRL; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + memcpy(cmd_param_buf, lighting_ctrl, + sizeof(struct isp_cmd_lighting_ctrl)); + + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_lighting_ctrl); + +errcode mini_isp_drv_set_min_exposure( + struct isp_cmd_exposure_param *min_exposure_info) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_SET_MIN_EXPOSURE; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + memcpy(cmd_param_buf, min_exposure_info, + sizeof(struct isp_cmd_exposure_param)); + + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_min_exposure); + +errcode mini_isp_drv_set_max_exposure_slope( + struct isp_cmd_max_exposure_slope *max_exposure_slope_info) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_SET_MAX_EXPOSURE_SLOPE; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + + memcpy(cmd_param_buf, max_exposure_slope_info, + sizeof(struct isp_cmd_max_exposure_slope)); + + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_set_max_exposure_slope); + +/** + *\brief Set Sensor Mode 0x301C + *\param en_update + *\ [In], en_update = update short distance | update compensation + *\bit[0:3] = update compensation + *\bit[4:7] = update short distance + *\param short_distance [In], short distance + *\param compensation [In], compensation value, Ground mode only + *\return Error code + */ + +errcode mini_isp_drv_depth_compensation( + struct isp_cmd_depth_compensation_param *depth_compensation_param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_DEPTH_COMPENSATION; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, depth_compensation_param, + sizeof(struct isp_cmd_depth_compensation_param)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_depth_compensation); + +/** + *\brief Set Sensor Mode 0x301D + *\param cycleLen + *\ [In], en_update = update short distance | update global shift + *\param depth_triggerBitField + *\ [In], bit 0 : 1st frame, bit 1 : 2nd frame + *\param depthoutput_triggerBitField + *\ [In], bit 0 : 1st frame, bit 1 : 2nd frame + *\return Error code + */ +errcode mini_isp_drv_cycle_trigger_depth_process( + struct isp_cmd_cycle_trigger_depth_process *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_TRIGGER_DEPTH_PROCESS_CTRL; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, param, sizeof( + struct isp_cmd_cycle_trigger_depth_process)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_cycle_trigger_depth_process); + +/** + *\brief Set led first power on delay time 0x3020 + *\param delay_ms [In], delay time (mini second) + *\return Error code + */ +errcode mini_isp_drv_led_active_delay(u32 delay_ms) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_SET_LED_ACTIVE_DELAY; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, &delay_ms, sizeof(u32)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_led_active_delay); + + +/** + *\brief Set isp control led level 0x3021 + *\param AL6100 control Led Level [In], 1: on, 0: off + *\return Error code + */ +errcode mini_isp_drv_isp_control_led_level(u8 on) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Op code*/ + u16 opcode = ISPCMD_CAMERA_ISPLEDLEVELCONTROLONOFF; + u8 cmd_param_buf[T_SPI_CMD_LENGTH]; + + memset(cmd_param_buf, 0, T_SPI_CMD_LENGTH); + memcpy(cmd_param_buf, &on, sizeof(u8)); + + err = ispctrl_if_mast_execute_cmd(opcode, cmd_param_buf); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_isp_control_led_level); + +/** + *\brief Get isp thermal 0x0115 + *\param None + *\return Error code + */ +errcode mini_isp_drv_get_chip_thermal(u16 *thermal_val) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u8 recv_buf[T_SPI_CMD_LENGTH]; + + /* Op code*/ + u16 opcode = ISPCMD_SYSTEM_GET_CHIP_THERMAL; + + memset(recv_buf, 0, T_SPI_CMD_LENGTH); + + /* recv buffer must use local buffer, can not be global or static. */ + err = ispctrl_if_mast_execute_cmd(opcode, recv_buf); + misp_info("%s - 0x%x", __func__, *(u16 *)recv_buf); + + memcpy((u8 *)thermal_val, recv_buf, 2); + + return err; +} +EXPORT_SYMBOL(mini_isp_drv_get_chip_thermal); + +/******Private Function******/ + +static int load_code_task(void *data) +{ + /* Error code*/ + errcode err = ERR_SUCCESS; + + misp_info("misp_load_fw start"); + + /* Reset mini-isp low for at least 200us, release to high for 20ms*/ + /*mini_isp_reset();*/ + +#if ENABLE_LINUX_FW_LOADER + /* Write boot code and basic code*/ + if (!SPI_SHORT_LEN_MODE) + err = mini_isp_drv_boot_mini_isp(); + /* SPI "Write" NO short Len limitation */ + else if (!SPI_SHORT_LEN_MODE_WRITE_ENABLE) + err = mini_isp_drv_boot_mini_isp(); + else + err = mini_isp_drv_boot_mini_isp_shortlen(); /* short SPI Len */ + if (err != ERR_SUCCESS) + goto load_code_task_end; +#else + /* Open boot file and FW file*/ + err = mini_isp_drv_open(BOOT_FILE_LOCATION, + BASIC_FILE_LOCATION, + ADVANCED_FILE_LOCATION, + SCENARIO_TABLE_FILE_LOCATION, + HDR_QMERGE_DATA_FILE_LOCATION, + IRP0_QMERGE_DATA_FILE_LOCATION, + IRP1_QMERGE_DATA_FILE_LOCATION, + PP_MAP_FILE_LOCATION, + DPETH_QMERGE_DATA_FILE_LOCATION); + if (err != ERR_SUCCESS) + goto load_code_task_end; + + /* Write boot code and basic code*/ + if (!SPI_SHORT_LEN_MODE) + err = mini_isp_drv_boot_mini_isp(); + /* SPI "Write" NO short Len limitation*/ + else if (!SPI_SHORT_LEN_MODE_WRITE_ENABLE) + err = mini_isp_drv_boot_mini_isp(); + else + err = mini_isp_drv_boot_mini_isp_shortlen(); /* short SPI Len*/ + if (err != ERR_SUCCESS) + goto load_code_task_end; +#endif + /* Set load code ready flag*/ + load_code_ready = true; + +load_code_task_end: + + return (int)err; +} + +#if (!ENABLE_LINUX_FW_LOADER) +static u16 calibration_check_sum(u8 *input_buffer_addr, u16 input_buffer_size) +{ + u16 i; + u32 sum = 0; + u16 sumvalue; + + /* calculating unit is 2 bytes*/ + for (i = 0; i < input_buffer_size; i++) { + if (0 == (i % 2)) + sum += input_buffer_addr[i]; + else + sum += (input_buffer_addr[i] << 8); + } + + /* Do 2's complement*/ + sumvalue = (u16)(65536 - (sum & 0x0000FFFF)); /*get 2's complement*/ + + return sumvalue; +} +#endif + + + + + +/******End Of File******/ diff --git a/drivers/media/platform/altek/miniisp_ctrl_intf.c b/drivers/media/platform/altek/miniisp_ctrl_intf.c new file mode 100755 index 000000000000..4c0005553188 --- /dev/null +++ b/drivers/media/platform/altek/miniisp_ctrl_intf.c @@ -0,0 +1,129 @@ +/* + * File: miniisp_ctrl_intf.c + * Description: mini ISP control cmd interface. + * use for handling the control cmds instead of debug cmds + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 018/08/28 PhenixChen; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/******Include File******/ +#include +#include /* copy_*_user() */ +#include "include/miniisp.h" +#include "include/miniisp_ctrl.h" /* mini_isp_drv_setting() */ +#include "include/isp_camera_cmd.h" +#include "include/ispctrl_if_master.h" /* ispctrl_if_mast_execute_cmd() */ +#include "include/miniisp_customer_define.h" +#include "include/miniisp_ctrl_intf.h" + +/******Private Constant Definition******/ +#define MINI_ISP_LOG_TAG "[miniisp_ctrl_intf]" +#define MAX_DATA_SIZE (64 * 1024) + +/******Private Function Prototype******/ + +/******Public Function Prototype******/ + +/******Private Global Variable******/ + + + +long handle_ControlFlowCmd(unsigned int cmd, unsigned long arg) +{ + long retval = 0; + struct miniISP_cmd_config *config = NULL; + u8 *param = NULL; + + misp_info("%s - enter", __func__); + + /* step1: allocate & receive cmd struct from user space */ + config = kzalloc(sizeof(struct miniISP_cmd_config), GFP_KERNEL); + if (NULL == config) { + retval = -ENOMEM; + goto done; + } + if (copy_from_user(config, (void __user *)arg, + sizeof(struct miniISP_cmd_config))) { + retval = -EFAULT; + goto done; + } + + /* step2: allocate & receive cmd parameter from user space if needed*/ + if ((config->size > 0) && (config->size < MAX_DATA_SIZE)) { + param = kzalloc(config->size, GFP_KERNEL); + if (NULL == param) { + retval = -ENOMEM; + goto done; + } + if (copy_from_user((void *)param, + (void __user *)(config->param), config->size)) { + retval = -EFAULT; + goto done; + } + } + + switch (cmd) { + case IOCTL_ISP_LOAD_FW: + misp_info("%s - IOCTL_ISP_LOAD_FW", __func__); + /* open boot and FW file then write boot code and FW code */ + mini_isp_poweron(); + mini_isp_drv_setting(MINI_ISP_MODE_GET_CHIP_ID); +#ifndef AL6100_SPI_NOR + /* if boot form SPI NOR, do not call this */ + mini_isp_drv_setting(MINI_ISP_MODE_CHIP_INIT); +#endif + mini_isp_drv_setting(MINI_ISP_MODE_E2A); + mini_isp_drv_setting(MINI_ISP_MODE_NORMAL); + break; + case IOCTL_ISP_PURE_BYPASS: + misp_info("%s - IOCTL_ISP_PURE_BYPASS", __func__); + mini_isp_poweron(); + mini_isp_drv_setting(MINI_ISP_MODE_GET_CHIP_ID); + mini_isp_drv_set_bypass_mode(1); + break; + case IOCTL_ISP_CTRL_CMD: + if (param == NULL) { + misp_info("%s - cmd parameter is NULL", __func__); + break; + } + retval = ispctrl_if_mast_execute_cmd(config->opcode, param); + break; + case IOCTL_ISP_DEINIT: + misp_info("%s - IOCTL_ISP_DEINIT", __func__); + mini_isp_poweroff(); + break; + default: + misp_info("%s - UNKNOWN CMD[0x%x]", __func__, cmd); + retval = -ENOTTY; + break; + } + +done: + if (param != NULL) + kfree(param); + if (config != NULL) + kfree(config); + + misp_info("%s - leave", __func__); + return retval; +} diff --git a/drivers/media/platform/altek/miniisp_customer_define.c b/drivers/media/platform/altek/miniisp_customer_define.c new file mode 100755 index 000000000000..04e3055753fb --- /dev/null +++ b/drivers/media/platform/altek/miniisp_customer_define.c @@ -0,0 +1,399 @@ +/* + * File: miniisp_customer_define.c + * Description: Mini ISP sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2017/03/14 LouisWang; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/******Include File******/ +/* Linux headers*/ +#include +#include + +#include "include/miniisp_customer_define.h" +#include "include/miniisp.h" +#include "include/miniisp_ctrl.h" + +#define MINI_ISP_LOG_TAG "[miniisp_customer_define]" + + +extern void mini_isp_poweron(void) +{ + errcode ret = 0; + void *devdata; + struct misp_global_variable *dev_global_variable; + + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + dev_global_variable = get_mini_isp_global_variable(); + misp_info("%s no FSM", __func__); + misp_err("[miniISP]mini_isp_poweron"); + +#if (ISR_MECHANISM == INTERRUPT_METHOD) + if (IRQ_GPIO != NULL) { + ret = request_threaded_irq( + gpio_to_irq(dev_global_variable->irq_gpio), + NULL, mini_isp_irq, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "mini_isp", devdata); + } + + if (ret != 0) { + misp_err("%s err, %x", __func__, ret); + return; + } + + misp_info("%s request_threaded_irq succeed, irq_gpio: %d, irg_num %d" + , __func__, dev_global_variable->irq_gpio, + gpio_to_irq(dev_global_variable->irq_gpio)); +#endif + + if (RESET_GPIO != NULL) { + gpio_direction_output(dev_global_variable->reset_gpio, 0); + gpio_set_value(dev_global_variable->reset_gpio, 0); + msleep(20); + } + if (VCC1_GPIO != NULL) + gpio_set_value(dev_global_variable->vcc1_gpio, 0); + if (VCC2_GPIO != NULL) + gpio_set_value(dev_global_variable->vcc2_gpio, 0); + if (VCC3_GPIO != NULL) + gpio_set_value(dev_global_variable->vcc3_gpio, 0); + + msleep(20); + + if (VCC1_GPIO != NULL) + gpio_set_value(dev_global_variable->vcc1_gpio, 1); + if (VCC2_GPIO != NULL) + gpio_set_value(dev_global_variable->vcc2_gpio, 1); + if (VCC3_GPIO != NULL) + gpio_set_value(dev_global_variable->vcc3_gpio, 1); + + msleep(20); + if (ISP_CLK != NULL) + if (clk_prepare_enable(dev_global_variable->isp_clk) < 0) + misp_err("mini_isp_poweron clk_prepare_enable failed"); + + if (RESET_GPIO != NULL) { + gpio_direction_output(dev_global_variable->reset_gpio, 1); + gpio_set_value(dev_global_variable->reset_gpio, 1); + msleep(20); + } + + if (RESET_GPIO != NULL) + misp_err("%s -reset_gpio gpio_get_value = %d", __func__, + gpio_get_value(dev_global_variable->reset_gpio)); + if (VCC1_GPIO != NULL) + misp_err("%s -vcc1_gpio gpio_get_value = %d", __func__, + gpio_get_value(dev_global_variable->vcc1_gpio)); + if (VCC2_GPIO != NULL) + misp_err("%s -vcc2_gpio gpio_get_value = %d", __func__, + gpio_get_value(dev_global_variable->vcc2_gpio)); + if (VCC3_GPIO != NULL) + misp_err("%s -vcc3_gpio gpio_get_value = %d", __func__, + gpio_get_value(dev_global_variable->vcc3_gpio)); + + misp_err("%s - leave", __func__); + + if (ret != 0) { + misp_err("%s err, %x", __func__, ret); + return; + } + + dev_global_variable->before_booting = 1; + dev_global_variable->be_set_to_bypass = 0; +} +EXPORT_SYMBOL(mini_isp_poweron); + +extern void mini_isp_poweroff(void) +{ + int ret = 0; + struct misp_global_variable *dev_global_variable; + void *devdata; + + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + dev_global_variable = get_mini_isp_global_variable(); + + misp_info("%s no FSM", __func__); + misp_err("[miniISP]mini_isp_poweroff"); + + if (RESET_GPIO != NULL) + gpio_set_value(dev_global_variable->reset_gpio, 0); + msleep(20); + if (VCC1_GPIO != NULL) + gpio_set_value(dev_global_variable->vcc1_gpio, 0); + if (VCC2_GPIO != NULL) + gpio_set_value(dev_global_variable->vcc2_gpio, 0); + if (VCC3_GPIO != NULL) + gpio_set_value(dev_global_variable->vcc3_gpio, 0); + if (ISP_CLK != NULL) + clk_disable_unprepare(dev_global_variable->isp_clk); + msleep(20); + +#if (ISR_MECHANISM == INTERRUPT_METHOD) + if (IRQ_GPIO != NULL) + free_irq(gpio_to_irq(dev_global_variable->irq_gpio), devdata); + +#endif + + if (ret != 0) { + misp_err("%s err, %x", __func__, ret); + return; + } + + dev_global_variable->be_set_to_bypass = 0; + dev_global_variable->before_booting = 1; + + misp_info("%s - X", __func__); +} +EXPORT_SYMBOL(mini_isp_poweroff); + +extern void mini_isp_eeprom_wpon(void) +{ + struct misp_global_variable *dev_global_variable; + + misp_err("[miniISP]mini_isp_eeprom_wpon"); + if (WP_GPIO != NULL) { + dev_global_variable = get_mini_isp_global_variable(); + gpio_set_value(dev_global_variable->wp_gpio, 1); + } + misp_info("%s - X", __func__); +} +EXPORT_SYMBOL(mini_isp_eeprom_wpon); + +extern void mini_isp_eeprom_wpoff(void) +{ + struct misp_global_variable *dev_global_variable; + + misp_err("[miniISP]mini_isp_eeprom_wpoff"); + if (WP_GPIO != NULL) { + dev_global_variable = get_mini_isp_global_variable(); + gpio_set_value(dev_global_variable->wp_gpio, 0); + } + misp_info("%s - X", __func__); +} +EXPORT_SYMBOL(mini_isp_eeprom_wpoff); + +extern int mini_isp_gpio_init(struct device *dev, + struct misp_data *drv_data, + struct misp_global_variable *drv_global_variable) +{ + int ret = 0; + + if (VCC1_GPIO != NULL) { + drv_global_variable->vcc1_gpio = + of_get_named_gpio(dev->of_node, VCC1_GPIO, 0); + misp_info("%s - probe vcc1-gpios = %d", __func__, + drv_global_variable->vcc1_gpio); + + ret = devm_gpio_request(dev, + drv_global_variable->vcc1_gpio, VCC1_GPIO); + if (ret) { + misp_err("%s -step 4. request vcc1-gpio error", + __func__); + goto err_gpio1_config; + } + + gpio_direction_output(drv_global_variable->vcc1_gpio, 1); + msleep(20); + gpio_set_value(drv_global_variable->vcc1_gpio, 1); + msleep(20); + } + + if (VCC2_GPIO != NULL) { + drv_global_variable->vcc2_gpio = of_get_named_gpio( + dev->of_node, VCC2_GPIO, 0); + misp_info("%s - probe vcc2-gpios = %d", __func__, + drv_global_variable->vcc2_gpio); + + ret = devm_gpio_request(dev, + drv_global_variable->vcc2_gpio, VCC2_GPIO); + if (ret) { + misp_err("%s -step 4. request vcc2-gpios error", + __func__); + goto err_gpio2_config; + } + + gpio_direction_output(drv_global_variable->vcc2_gpio, 1); + msleep(20); + gpio_set_value(drv_global_variable->vcc2_gpio, 1); + msleep(20); + } + + if (VCC3_GPIO != NULL) { + drv_global_variable->vcc3_gpio = of_get_named_gpio( + dev->of_node, VCC3_GPIO, 0); + misp_err("%s - probe vcc3-gpios = %d", __func__, + drv_global_variable->vcc3_gpio); + + ret = devm_gpio_request(dev, + drv_global_variable->vcc3_gpio, VCC3_GPIO); + if (ret) { + misp_err("%s -step 4. request vcc3-gpio error", + __func__); + goto err_gpio_config; + } + + gpio_direction_output(drv_global_variable->vcc3_gpio, 1); + gpio_set_value(drv_global_variable->vcc3_gpio, 1); + msleep(20); + + } + + if (WP_GPIO != NULL) { + drv_global_variable->wp_gpio = of_get_named_gpio( + dev->of_node, WP_GPIO, 0); + misp_info("%s - probe wp-gpios = %d", __func__, + drv_global_variable->wp_gpio); + + ret = devm_gpio_request(dev, + drv_global_variable->wp_gpio, WP_GPIO); + if (ret) { + misp_err("%s -step 4. request wp-gpio error", + __func__); + goto err_gpio_config; + } + + gpio_direction_output(drv_global_variable->wp_gpio, 1); + gpio_set_value(drv_global_variable->wp_gpio, 1); + msleep(20); + + } + + if (ISP_CLK != NULL) { + drv_global_variable->isp_clk = devm_clk_get(dev, + ISP_CLK); + misp_err("clk_ptr = %p", drv_global_variable->isp_clk); + ret = clk_set_rate(drv_global_variable->isp_clk, 19200000L); + if (ret < 0) + misp_err("clk_set_rate failed, not fatal\n"); + + misp_err("clk_get_rate %ld\n", clk_get_rate( + drv_global_variable->isp_clk)); + ret = clk_prepare_enable(drv_global_variable->isp_clk); + if (ret < 0) { + misp_err("clk_prepare_enable failed\n"); + goto err_clk_config; + } + msleep(20); + } + + if (RESET_GPIO != NULL) { + drv_global_variable->reset_gpio = + of_get_named_gpio(dev->of_node, RESET_GPIO, 0); + misp_info("%s - probe reset_gpio = %d", __func__, + drv_global_variable->reset_gpio); + + ret = devm_gpio_request(dev, + drv_global_variable->reset_gpio, RESET_GPIO); + if (ret) { + misp_err("%s -step 4. request reset gpio error", + __func__); + goto err_reset_config; + } + + gpio_direction_output(drv_global_variable->reset_gpio, 0); + gpio_set_value(drv_global_variable->reset_gpio, 0); + msleep(20); + + } + +#if (ISR_MECHANISM == INTERRUPT_METHOD) + if (IRQ_GPIO != NULL) { + + drv_global_variable->irq_gpio = + of_get_named_gpio(dev->of_node, IRQ_GPIO, 0); + + misp_info("%s - probe irq_gpio = %d", + __func__, drv_global_variable->irq_gpio); + + ret = gpio_request(drv_global_variable->irq_gpio, IRQ_GPIO); + if (ret) { + misp_err("%s -step 4. request irq gpio error", + __func__); + goto err_irq_config; + } + gpio_direction_input(drv_global_variable->irq_gpio); + + drv_global_variable->irq_num = + gpio_to_irq(drv_global_variable->irq_gpio); + + misp_err("%s - probe spi->irq = %d %d ", + __func__, drv_global_variable->irq_num, + gpio_to_irq(drv_global_variable->irq_gpio)); + + ret = request_threaded_irq( + drv_global_variable->irq_num, NULL, mini_isp_irq, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, "mini_isp", drv_data); + + if (ret) { + misp_err("%s - step4. probe - request irq error", + __func__); + goto err_dev_attr; + } + misp_info("%s - step4 done. irq number:%d", __func__, + drv_global_variable->irq_num); + + free_irq(drv_global_variable->irq_num, drv_data); + } +#endif + + /*step 5:other additional config*/ + + misp_info("%s - step5 done", __func__); + + if (RESET_GPIO != NULL) { + gpio_direction_output(drv_global_variable->reset_gpio, 1); + gpio_set_value(drv_global_variable->reset_gpio, 1); + msleep(20); + } + + return ret; + +#if (ISR_MECHANISM == INTERRUPT_METHOD) +err_dev_attr: + free_irq(drv_global_variable->irq_num, drv_data); + +err_irq_config: + if (IRQ_GPIO != NULL) + gpio_free(drv_global_variable->irq_gpio); +#endif + +err_reset_config: + if (RESET_GPIO != NULL) + gpio_free(drv_global_variable->reset_gpio); + +err_clk_config: + if (ISP_CLK != NULL) + clk_disable_unprepare(drv_global_variable->isp_clk); + +err_gpio_config: + if (VCC2_GPIO != NULL) + gpio_free(drv_global_variable->vcc2_gpio); +err_gpio2_config: + if (VCC1_GPIO != NULL) + gpio_free(drv_global_variable->vcc1_gpio); + +err_gpio1_config: + + return ret; +} diff --git a/drivers/media/platform/altek/miniisp_debug_if.c b/drivers/media/platform/altek/miniisp_debug_if.c new file mode 100755 index 000000000000..7d7363cf2e7c --- /dev/null +++ b/drivers/media/platform/altek/miniisp_debug_if.c @@ -0,0 +1,647 @@ +/* + * File: miniisp_debug_if.c + * Description: mini ISP debug daemon interface + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2017/04/20; PhenixChen; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/******Include File******/ +#include "include/miniisp.h" +#include "include/miniisp_debug_if.h" +#include "include/miniisp_customer_define.h" + +#include /* copy_*_user() */ +#include /* chrdev, struct file_operations */ +#include /* cdev_add()/cdev_del() */ +#include +#include /*msleep()*/ + +#if EN_605_IOCTRL_INTF +#include "include/miniisp_ctrl_intf.h" +#include +#endif + +/******Private Constant Definition******/ +#define MINI_ISP_LOG_TAG "[miniisp_debug_if]" +#define MAX_RW_SIZE (64 * 1024) + +/******Private Function Prototype******/ +static int miniisp_dev_open(struct inode*, struct file*); +static int miniisp_dev_release(struct inode *inode, struct file *filp); +static long miniisp_dev_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg); +static int miniisp_dev_map(struct file *filp, struct vm_area_struct *vma); +static u32 miniisp_debugif_memory_read(u32 start_addr, u32 len); +static u32 miniisp_debugif_RegBulk_read(u32 start_addr, u32 end_reg_addr); +static long miniisp_debugif_get_mem(u32 len); +static long miniisp_debugif_munmap_done(void); +static long handle_RegCmd(unsigned int cmd, unsigned long arg); +static long handle_MemCmd(unsigned int cmd, unsigned long arg); +static long handle_BulkCmd(unsigned int cmd, unsigned long arg); + +/******Public Function Prototype******/ +struct device *miniisp_chdev_create(struct class *mini_isp_class); + +/******Private Global Variable******/ +static int miniisp_dev_major; +static int miniisp_dev_minor; +static struct cdev *miniisp_dev_cdev; +static unsigned long *allocated_memmory_align; +static unsigned long *allocated_memmory; +static unsigned long allocated_size; +static u8 During_Refresh_Module; + +struct dbg_drvdata { + /* u32 val; */ + u32 reg_tbl[4]; /* for Test */ + /* unsigned char mem[16]; */ + rwlock_t lock; +}; + +static const struct file_operations miniisp_dev_fops = { + .owner = THIS_MODULE, + .open = miniisp_dev_open, + .release = miniisp_dev_release, + .mmap = miniisp_dev_map, + /* .read = dev_read, */ + /* .write = dev_write, */ + + .unlocked_ioctl = miniisp_dev_ioctl, +#if EN_605_IOCTRL_INTF + .compat_ioctl = miniisp_dev_ioctl, +#endif +}; + +static long miniisp_debugif_munmap_done(void) +{ + unsigned long virt_addr; + + misp_err("%s:called", __func__); + if (allocated_memmory_align) { + for (virt_addr = (unsigned long)allocated_memmory_align; + virt_addr < (unsigned long)allocated_memmory_align + + allocated_size; virt_addr += PAGE_SIZE) + ClearPageReserved(virt_to_page(virt_addr)); + kfree(allocated_memmory); + allocated_memmory = NULL; + allocated_memmory_align = NULL; + allocated_size = 0; + } + return 0; +} + +static long miniisp_debugif_get_mem(u32 len) +{ + long retval = 0; + unsigned long virt_addr; + unsigned long mask = ~(PAGE_SIZE - 1); + + /* page-aligned memory size */ + allocated_size = (len + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + misp_err("%s:memory length = %u, page-aligned memory size = %lu", + __func__, len, allocated_size); + + /* allocate page-aligned memory */ + allocated_memmory = kzalloc(allocated_size + PAGE_SIZE - 1, GFP_KERNEL); + if (!allocated_memmory) { + retval = -ENOMEM; + misp_err("%s:kzalloc failed", __func__); + goto done; + } + /* printf指標的位址通常使用%x,但它的寬度是 32-bit, + 無法在 64-bit 環境下顯示正確結果,需改用%p */ + misp_err("%s:allocated_memmory before align = %p", + __func__, allocated_memmory); + allocated_memmory_align = (unsigned long *) + (((unsigned long)allocated_memmory + PAGE_SIZE - 1) & mask); + misp_err("%s:allocated_memmory after align = %p", + __func__, allocated_memmory_align); + misp_err("%s:kzalloc succeed, total allocated_size = %lu", + __func__, allocated_size + PAGE_SIZE - 1); + + /* reserve all pages to make them remapable */ + for (virt_addr = (unsigned long)allocated_memmory_align; + virt_addr < ((unsigned long)allocated_memmory_align + + allocated_size); + virt_addr += PAGE_SIZE) + SetPageReserved(virt_to_page(virt_addr)); +done: + return retval; +} + + +static int miniisp_dev_map(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long page, pos; + unsigned long start = (unsigned long)vma->vm_start; + unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start); + + misp_err("%s:called", __func__); + + if (size > (unsigned long)allocated_size) { + misp_err("%s:ERROR1 mapsz = %lu, allocated_size = %lu", + __func__, size, (unsigned long)allocated_size); + return -EINVAL; + } + pos = (unsigned long)allocated_memmory_align; + page = virt_to_phys((void *)pos); + + if (remap_pfn_range(vma, + start, page >> PAGE_SHIFT, size, PAGE_SHARED)) { + misp_err("%s:ERROR2", __func__); + return -EAGAIN; + } + return 0; +} + +static u32 miniisp_debugif_RegBulk_read(u32 start_reg_addr, u32 end_reg_addr) +{ + struct misp_data *devdata; + struct misp_global_variable *dev_global_variable; + u32 count; + u32 rx_dummy_len; + u8 *send_buffer; + u8 *recv_buffer; + u8 *io_buffer = NULL; + u32 io_size; + u8 *dump_memory = NULL; + u8 *keep_dump_memory = NULL; + u32 ouput_size; + u8 ctrlbyte = CTRL_BYTE_REGRD; + + /* prepare for mmap >>>*/ + long retval = 0; + u8 *mmap_addr; + + /*how many registers(4 bytes) do you want to read?*/ + count = ((end_reg_addr - start_reg_addr) / 4) + 1; + ouput_size = (count + 2) * 4; /* read 4 bytes register value */ + + retval = miniisp_debugif_get_mem(ouput_size); + if (retval) + goto mini_isp_register_read_end; + mmap_addr = (u8 *)allocated_memmory_align; + /* prepare for mmap <<<*/ + + dev_global_variable = get_mini_isp_global_variable(); + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + + + rx_dummy_len = mini_isp_get_rx_dummy_byte(ctrlbyte); + +#if EN_SPIE_REG_DUMMY_BYTE + mini_isp_set_spie_dummy_byte(rx_dummy_len-1); /* 0 base */ +#endif + + /* read 4 bytes register value at a time */ + io_size = EMODE_TXCMD_LEN + rx_dummy_len + 4; + + io_buffer = kzalloc(io_size, GFP_KERNEL); + if (!io_buffer) { + retval = -ENOMEM; + misp_err("%s Allocate memory failed.", __func__); + goto allocate_memory_fail; + } + + dump_memory = kzalloc(ouput_size, GFP_KERNEL); + if (!dump_memory) { + retval = -ENOMEM; + misp_err("%s Allocate memory failed.", __func__); + goto allocate_memory_fail; + } + keep_dump_memory = dump_memory; + + send_buffer = io_buffer; + recv_buffer = io_buffer + EMODE_TXCMD_LEN; + + memcpy(dump_memory, &start_reg_addr, 4); + dump_memory = dump_memory + 4; + memcpy(dump_memory, &count, 4); + dump_memory = dump_memory + 4; + + while (start_reg_addr <= end_reg_addr) { + + memset(io_buffer, 0, io_size); + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &start_reg_addr, 4); + + retval = devdata->intf_fn->read((void *)devdata, + send_buffer, EMODE_TXCMD_LEN, + recv_buffer, rx_dummy_len + 4); + + if (retval) + goto mini_isp_register_read_get_fail; + + if (dev_global_variable->intf_status & INTF_SPI_READY) { + /* check if send len + recv len > 32. if yes then + rx_dummy_len need + EMODE_TXCMD_LEN */ + if (EMODE_TXCMD_LEN + rx_dummy_len + 4 > 32) + retval = mini_isp_check_rx_dummy( + &recv_buffer, rx_dummy_len+EMODE_TXCMD_LEN); + else + retval = mini_isp_check_rx_dummy( + &recv_buffer, rx_dummy_len); + + if (retval) + goto mini_isp_register_read_get_fail; + } + + memcpy(dump_memory, recv_buffer, 4); + start_reg_addr = start_reg_addr + 4; + dump_memory = dump_memory + 4; + } + memcpy(mmap_addr, keep_dump_memory, ouput_size); + kfree(io_buffer); + kfree(keep_dump_memory); + goto mini_isp_register_read_end; + +mini_isp_register_read_get_fail: + misp_err("%s read failed.", __func__); +allocate_memory_fail: + misp_err("%s Allocate memory failed.", __func__); + kfree(io_buffer); + kfree(keep_dump_memory); + miniisp_debugif_munmap_done(); +mini_isp_register_read_end: + return retval; +} + +static u32 miniisp_debugif_memory_read(u32 start_addr, u32 len) +{ + /* prepare for mmap >>>*/ + long retval = 0; + u8 *mmap_addr; + + retval = miniisp_debugif_get_mem(len); + if (retval) { + misp_err("%s alloc fail", __func__); + goto mini_isp_memory_read_fail; + } + mmap_addr = (u8 *)allocated_memmory_align; + /* prepare for mmap <<<*/ + + retval = mini_isp_memory_read(start_addr, mmap_addr, len); + if (retval) { + misp_err("%s read fail", __func__); + miniisp_debugif_munmap_done(); + goto mini_isp_memory_read_fail; + } + misp_err("%s dump_finish", __func__); + +mini_isp_memory_read_fail: + return retval; +} + +static long handle_PrepareCmd(unsigned int cmd, unsigned long arg) +{ + long retval = 0; + u8 state; /* 1:start, 0:done */ + + if (copy_from_user(&state, (int __user *)arg, sizeof(state))) { + retval = -EFAULT; + goto done; + } + switch (cmd) { + case IOCTL_REFRESH_MODULE: + if (state == 1) { + During_Refresh_Module = 1; + mini_isp_a_to_e(); + } else if (state == 0) { + mini_isp_e_to_a(); + During_Refresh_Module = 0; + } + break; + default: + retval = -ENOTTY; + break; + } +done: + return retval; +} + +static long handle_InfoCmd(unsigned int cmd, unsigned long arg) +{ + long retval = 0; + struct irp_and_depth_information data; + + memset(&data, 0, sizeof(data)); + if (copy_from_user(&data, (int __user *)arg, sizeof(data))) { + retval = -EFAULT; + goto done; + } + + mini_isp_a_to_e(); + + switch (cmd) { + case IOCTL_IRP_DEPTH_INFO: + misp_err("%s:IOCTL_IRP_DEPTH_INFO", __func__); + retval = mini_isp_utility_get_irp_and_depth_information(&data); + if (retval) { + misp_err("%s:miniisp driver spi error, retval = %u", + __func__, (u32)retval); + retval = -EIO; + break; + } + if (copy_to_user((int __user *)arg, &data, sizeof(data))) + retval = -EFAULT; + break; + default: + retval = -ENOTTY; + break; + } + + mini_isp_e_to_a(); +done: + return retval; +} + +static long handle_RegCmd(unsigned int cmd, unsigned long arg) +{ + long retval = 0; + u32 val = 0xFFFFFFFF; + struct ioctl_regRW_cmd data; + + memset(&data, 0, sizeof(data)); + if (copy_from_user(&data, (int __user *)arg, sizeof(data))) { + retval = -EFAULT; + goto done; + } + + if (!During_Refresh_Module) + mini_isp_a_to_e(); + + switch (cmd) { + case IOCTL_REGREAD: + misp_err("%s:IOCTL_REGREAD RegAddr = %#04x", + __func__, data.RegAddr); + retval = mini_isp_register_read(data.RegAddr, &val); + if (val == 0xFFFFFFFF) { + if (retval < 0) + misp_err("%s:miniisp driver sync_error, retval = %u", + __func__, (u32)retval); + else + misp_err("%s:miniisp driver can't get register.", + __func__); + retval = -EIO; + break; + } + data.RegVal = val; + if (copy_to_user((int __user *)arg, &data, sizeof(data))) + retval = -EFAULT; + break; + case IOCTL_REGWRITE: + misp_err("%s:IOCTL_REGWRITE RegAddr = %#04x; val = %#04x", + __func__, data.RegAddr, data.RegVal); + mini_isp_register_write(data.RegAddr, data.RegVal); + break; + default: + retval = -ENOTTY; + break; + } + + if (!During_Refresh_Module) + mini_isp_e_to_a(); + +done: + return retval; +} + + +static long handle_MemCmd(unsigned int cmd, unsigned long arg) +{ + long retval = 0; + struct ioctl_memRW_cmd data; + + memset(&data, 0, sizeof(data)); + if (copy_from_user(&data, (int __user *)arg, sizeof(data))) { + retval = -EFAULT; + goto done; + } + + if (data.len > MAX_RW_SIZE) { + misp_err("%s:Invalid length, MemAddr = %#04x len = %u", + __func__, data.MemAddr, data.len); + retval = -EFAULT; + goto done; + } + + if (!During_Refresh_Module) + mini_isp_a_to_e(); + + switch (cmd) { + case IOCTL_MEMREAD: + misp_err("%s:IOCTL_MEMREAD MemAddr = %#04x len = %u", + __func__, data.MemAddr, data.len); + retval = miniisp_debugif_memory_read(data.MemAddr, data.len); + break; + case IOCTL_MUNMAP_DONE: + misp_err("%s:IOCTL_MMAPDONE", __func__); + retval = miniisp_debugif_munmap_done(); + break; + case IOCTL_MEMGET: + misp_err("%s:IOCTL_MEMGET len = %u", __func__, data.len); + retval = miniisp_debugif_get_mem(data.len); + break; + case IOCTL_MEMWRITE: + misp_err("%s:IOCTL_MEMWRITE MemAddr = %#04x len = %u", + __func__, data.MemAddr, data.len); + mini_isp_memory_write(data.MemAddr, + (u8 *)allocated_memmory_align, data.len); + break; + default: + retval = -ENOTTY; + break; + } + + if (!During_Refresh_Module) + mini_isp_e_to_a(); + +done: + return retval; +} + +static long handle_BulkCmd(unsigned int cmd, unsigned long arg) +{ + long retval = 0; + struct ioctl_regBulkRW_cmd data; + + memset(&data, 0, sizeof(data)); + if (copy_from_user(&data, (int __user *)arg, sizeof(data))) { + retval = -EFAULT; + goto done; + } + + if ((data.StartAddr > data.EndAddr) || + ((data.EndAddr - data.StartAddr) > MAX_RW_SIZE)) { + misp_err("%s:Invalid address, StartAddr = %#04x EndAddr = %#04x", + __func__, data.StartAddr, data.EndAddr); + retval = -EFAULT; + goto done; + } + + if (!During_Refresh_Module) + mini_isp_a_to_e(); + + switch (cmd) { + case IOCTL_REGBULKREAD: + misp_err("%s:IOCTL_REGBULKREAD StartAddr = %#04x EndAddr = %#04x", + __func__, data.StartAddr, data.EndAddr); + retval = miniisp_debugif_RegBulk_read( + data.StartAddr, data.EndAddr); + misp_err("%s:IOCTL_REGBULKREAD end", __func__); + break; + default: + retval = -ENOTTY; + break; + } + if (!During_Refresh_Module) + mini_isp_e_to_a(); + +done: + return retval; +} + + +static long miniisp_dev_ioctl( + struct file *filp, unsigned int cmd, unsigned long arg) +{ + long retval = 0; + + misp_err("%s: IOCTL cmd:0x%08x", __func__, cmd); + /* + if (!access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd))) { + retval = -EFAULT; + goto done; + } + */ + switch (_IOC_TYPE(cmd)) { + case IOC_REGCMD_MAGIC: + retval = handle_RegCmd(cmd, arg); + break; + case IOC_MEMCMD_MAGIC: + retval = handle_MemCmd(cmd, arg); + break; + case IOC_BULKCMD_MAGIC: + retval = handle_BulkCmd(cmd, arg); + break; + case IOC_INFOCMD_MAGIC: + retval = handle_InfoCmd(cmd, arg); + break; + case IOC_PREPARECMD_MAGIC: + retval = handle_PrepareCmd(cmd, arg); + break; +#if EN_605_IOCTRL_INTF + case IOC_ISP_CTRL_FLOW_MAGIC: + retval = handle_ControlFlowCmd(cmd, arg); + break; +#endif + default: + retval = -ENOTTY; + break; + } + return retval; +} + +static int miniisp_dev_open(struct inode *inode, struct file *filp) +{ + struct dbg_drvdata *p; + + misp_err("%s:major %d minor %d (pid %d)", __func__, + imajor(inode), iminor(inode), current->pid); + inode->i_private = inode; + + p = kmalloc(sizeof(struct dbg_drvdata), GFP_KERNEL); + if (p == NULL) { + /* misp_err("%s:No memory", __func__); */ + return -ENOMEM; + } + + memset(p, 0, sizeof(*p)); + + rwlock_init(&p->lock); + filp->private_data = p; + + misp_err("%s:inode->i_private = %p, filp->private_data = %p", + __func__, inode->i_private, filp->private_data); + return 0; +} + +static int miniisp_dev_release(struct inode *inode, struct file *filp) +{ + misp_err("%s:major %d, minor %d, pid %d", + __func__, imajor(inode), iminor(inode), current->pid); + misp_err("%s:inode->i_private = %p, filp->private_data = %p", + __func__, inode->i_private, filp->private_data); + kfree(filp->private_data); + return 0; +} + +struct device *miniisp_chdev_create(struct class *mini_isp_class) +{ + dev_t miniisp_dev_nr; /* device number */ + int ret = 0; + struct device *mini_isp_dev; + + /* alloc major number */ + if (alloc_chrdev_region( + &miniisp_dev_nr, 0, 1, "mini_isp_device") != 0) { + misp_err("%s:Allocate major number failed", __func__); + mini_isp_dev = device_create( + mini_isp_class, NULL, 0, NULL, "mini_isp_device"); + } else { + misp_err("%s:Allocate major number succeed", __func__); + mini_isp_dev = device_create(mini_isp_class, NULL, + miniisp_dev_nr, NULL, "mini_isp_device"); + + miniisp_dev_major = MAJOR(miniisp_dev_nr); + miniisp_dev_minor = MINOR(miniisp_dev_nr); + misp_err("%s:register chrdev(%d,%d)", __func__, + miniisp_dev_major, miniisp_dev_minor); + /* alloc struct cdev */ + /* kmalloc(sizeof(struct cdev), GFP_KERNEL); + //alloc struct cdev */ + miniisp_dev_cdev = cdev_alloc(); + if (miniisp_dev_cdev == NULL) { + misp_err("%s:kmalloc dev_cdev failed", __func__); + return mini_isp_dev; + } else { + misp_err("%s:kmalloc dev_cdev succeed", __func__); + } + /* register handler to struct cdev */ + /* cdev_init(miniisp_dev_cdev, &miniisp_dev_fops); */ + miniisp_dev_cdev->ops = &miniisp_dev_fops; + miniisp_dev_cdev->owner = THIS_MODULE; + /* register driver (struct cdev with file handler) to kernel */ + ret = cdev_add(miniisp_dev_cdev, + MKDEV(miniisp_dev_major, miniisp_dev_minor), 1); + if (ret < 0) { + misp_err("%s:Add character device failed", __func__); + + kfree(miniisp_dev_cdev); + miniisp_dev_cdev = NULL; + } else { + misp_err("%s:Add character device succeed", __func__); + } + } + return mini_isp_dev; +} diff --git a/drivers/media/platform/altek/miniisp_intf_i2c.c b/drivers/media/platform/altek/miniisp_intf_i2c.c new file mode 100755 index 000000000000..0021ef89e08c --- /dev/null +++ b/drivers/media/platform/altek/miniisp_intf_i2c.c @@ -0,0 +1,487 @@ +/* + * File: miniisp_intf_i2c.c + * Description: Mini ISP i2c sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2017/03/30; Max Tseng; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/**************************************************************************** +* Include File * +****************************************************************************/ +/* Linux headers*/ +#include +#include + +#include "include/miniisp.h" +#include "include/miniisp_ctrl.h" +#include "include/error/miniisp_err.h" + +/**************************************************************************** +* Private Constant Definition * +****************************************************************************/ +#define MINI_ISP_LOG_TAG "[miniisp_intf_i2c]" +#define MINIISP_SLAVE_ADDR 0x11 +#define MINIISP_TOP_ADDR 0x77 + +/**************************************************************************** +* Private Global Variable * +****************************************************************************/ +static struct misp_data *misp_intf_i2c_slave_data; +static struct misp_data *misp_intf_i2c_top_data; +static u8 *i2c_bulkbuffer; + +/**************************************************************************** +* Private Function Prototype * +****************************************************************************/ + +/********************************************************************** +* Public Function * +**********************************************************************/ + +static const struct i2c_device_id mini_isp_intf_i2c_id[] = { + { "altek_i2c_slave", MINIISP_I2C_SLAVE}, + { "altek_i2c_top", MINIISP_I2C_TOP}, + {} /* NULL terminated*/ +}; +MODULE_DEVICE_TABLE(i2c, mini_isp_intf_i2c_id); + +/* + *get mini isp data + *return mini isp i2c data + */ +struct misp_data *get_mini_isp_intf_i2c_top_data(void) +{ + if (!misp_intf_i2c_top_data) { + misp_err("%s - get pdata error", __func__); + return NULL; + } else { + return misp_intf_i2c_top_data; + } +} + +struct misp_data *get_mini_isp_intf_i2c_slave_data(void) +{ + if (!misp_intf_i2c_slave_data) { + misp_err("%s - get pdata error", __func__); + return NULL; + } else { + return misp_intf_i2c_slave_data; + } +} +struct misp_data *get_mini_isp_intf_i2c(int i2c_type) +{ + if (i2c_type == MINIISP_I2C_SLAVE) { + return get_mini_isp_intf_i2c_slave_data(); + } else if (i2c_type == MINIISP_I2C_TOP) { + return get_mini_isp_intf_i2c_top_data(); + } else { + misp_err("%s - error i2c type %d", __func__, i2c_type); + return NULL; + } +} + + +/**************************************************************************** +* Private Function * +****************************************************************************/ +/*write command to miniISP through i2c,this function will block. + *return 0 successful + *others fail +*/ +static int mini_isp_intf_i2c_write(void *dev, u8 *tx_buf, u8 *rx_buf, u32 len) +{ + int status = 0; + struct misp_data *devdata = (struct misp_data *)dev; + + if (!devdata) { + misp_err("%s - invalid arg devdata = %p", __func__, devdata); + return -EINVAL; + } + + status = i2c_master_send(devdata->cfg.i2c, tx_buf, len); + + if (status < 0) + misp_err("%s - sync error: status=%d", __func__, status); + else + status = 0; + + return status; +} + +/*read command from device ,this function will block. + *return 0 successful + *others fail + */ +static int mini_isp_intf_i2c_read( + void *dev, u8 *tx_buf, u32 tx_len, u8 *rx_buf, u32 rx_len) +{ + int status = 0; + struct misp_data *devdata = (struct misp_data *)dev; + + if (!devdata) { + misp_err("%s - invalid arg devdata = %p", __func__, devdata); + return -EINVAL; + } + + misp_info("%s - i2c_master_send start.", __func__); + if (tx_len > 0) { + status = i2c_master_send(devdata->cfg.i2c, tx_buf, tx_len); + if (status != tx_len) + return status; + } + + misp_info("%s - i2c_master_recv start.", __func__); + /* read data from device through i2c */ + status = i2c_master_recv(devdata->cfg.i2c, rx_buf, rx_len); + + if (status < 0) + misp_err("%s - sync error: status=%d", __func__, status); + else + status = 0; + + return status; +} + +/* + *write command data to miniISP through i2c + *return 0 successful + *others fail +*/ +static int mini_isp_intf_i2c_send(void *dev, u32 len) +{ + int status = 0; + struct misp_data *devdata = (struct misp_data *)dev; + + misp_info("%s - enter", __func__); + + if (!devdata) { + misp_err("%s - invalid arg devdata = %p, len= %d", + __func__, devdata, len); + return -EINVAL; + } + + misp_info("%s - i2c_master_send start.", __func__); + /* send data to miniISP through i2c */ + status = mini_isp_intf_i2c_write( + devdata, devdata->tx_buf, devdata->rx_buf, len); + + misp_info("%s - devdata->cfg.i2c->addr = %x", + __func__, devdata->cfg.i2c->addr); + if (status < 0) + misp_err("%s - sync error: status=%d", __func__, status); + else + status = 0; + + return status; +} + +/* read miniISP using i2c ,this function will block. + *return 0 successful + *others fail + */ +static int mini_isp_intf_i2c_recv(void *dev, u32 len, bool waitINT) +{ + int status = 0; + struct misp_data *devdata = (struct misp_data *)dev; + + misp_info("%s - enter", __func__); + + if (!devdata) { + misp_err("%s - invalid arg devdata=%p,len=%d", __func__, + devdata, len); + return -EINVAL; + } + + if (waitINT) + /*wait for the interrupt*/ + status = mini_isp_wait_for_event(MINI_ISP_RCV_CMD_READY); + + if (status) { + misp_err("%s - irq error: status=%d", __func__, status); + return status; + } + + /* receive the data through i2c */ + status = mini_isp_intf_i2c_read( + devdata, devdata->tx_buf, 0, devdata->rx_buf, len); + + if (status) { + misp_err("%s - sync error: status=%d", __func__, status); + return status; + } + + misp_info("%s - recv buf len=%d:", __func__, len); + return status; +} + +#if ENABLE_LINUX_FW_LOADER +/*used to send the firmware*/ +static int mini_isp_intf_i2c_send_bulk(void *devdata, + u32 total_size, u32 block_size, bool is_raw, + const u8 *i2c_Sendbulkbuffer) +{ + int status = 0, count = 0; + int remain_size, one_size; + int shift = 0; + + misp_info("%s - enter", __func__); + + if (i2c_Sendbulkbuffer != NULL) { + misp_info("%s start. Total size: %d. block_size: %d", + __func__, total_size, block_size); + + if (total_size > I2C_TX_BULK_SIZE) + i2c_bulkbuffer = kzalloc(I2C_TX_BULK_SIZE, GFP_DMA); + /* Allocate boot code bulk buffer*/ + else + i2c_bulkbuffer = kzalloc(total_size, GFP_DMA); + + if (!i2c_bulkbuffer) { + status = -EINVAL; + goto T_EXIT; + } + + for (remain_size = total_size; remain_size > 0; remain_size -= one_size) { + one_size = (remain_size > block_size) ? block_size : remain_size; + + misp_info("remain size: %d one_size: %d.", remain_size, one_size); + + memcpy(i2c_bulkbuffer, i2c_Sendbulkbuffer + shift, one_size); + shift += one_size; + + /*send the data*/ + status = mini_isp_intf_i2c_write(devdata, + i2c_bulkbuffer, NULL, one_size); + + if (status != 0) { + misp_err("%s failed! block:%d status:%d", __func__, count, status); + break; + } + misp_info("%s write block %d success", __func__, count); + count++; + } + } + +T_EXIT: + + if (i2c_bulkbuffer != NULL) { + kfree(i2c_bulkbuffer); + i2c_bulkbuffer = NULL; + } + + if (status != ERR_SUCCESS) + misp_err("%s error: %d", __func__, status); + else + misp_info("%s success", __func__); + + return status; +} + +struct misp_intf_fn_t intf_i2c_fn = { + .send = mini_isp_intf_i2c_send, + .recv = mini_isp_intf_i2c_recv, + .read = mini_isp_intf_i2c_read, + .write = mini_isp_intf_i2c_write, + .send_bulk = mini_isp_intf_i2c_send_bulk, +}; + +#else +/*used to send the firmware*/ +static int mini_isp_intf_i2c_send_bulk(void *devdata, struct file *filp, + u32 total_size, u32 block_size, bool is_raw, u8 *i2c_Sendbulkbuffer) +{ + int status = 0, count = 0; + int remain_size, one_size; + int shift = 0; + + misp_info("%s - enter", __func__); + + if (i2c_Sendbulkbuffer != NULL) { + misp_info("%s start. Total size: %d. block_size: %d", __func__, total_size, block_size); + + if (total_size > I2C_TX_BULK_SIZE) + i2c_bulkbuffer = kzalloc(I2C_TX_BULK_SIZE, GFP_DMA); + /* Allocate boot code bulk buffer*/ + else + i2c_bulkbuffer = kzalloc(total_size, GFP_DMA); + + if (!i2c_bulkbuffer) { + status = -EINVAL; + goto T_EXIT; + } + + for (remain_size = total_size; remain_size > 0; remain_size -= one_size) { + one_size = (remain_size > block_size) ? block_size : remain_size; + + misp_info("remain size: %d one_size: %d.", remain_size, one_size); + + memcpy(i2c_bulkbuffer, i2c_Sendbulkbuffer + shift, one_size); + shift += one_size; + + /*send the data*/ + status = mini_isp_intf_i2c_write(devdata, + i2c_bulkbuffer, NULL, one_size); + + if (status != 0) { + misp_err("%s failed! block:%d status:%d", __func__, count, status); + break; + } + misp_info("%s write block %d success", __func__, count); + count++; + } + } + +T_EXIT: + + if (i2c_bulkbuffer != NULL) { + kfree(i2c_bulkbuffer); + i2c_bulkbuffer = NULL; + } + + if (status != ERR_SUCCESS) + misp_err("%s error: %d", __func__, status); + else + misp_info("%s success", __func__); + + return status; +} + +struct misp_intf_fn_t intf_i2c_fn = { + .send = mini_isp_intf_i2c_send, + .recv = mini_isp_intf_i2c_recv, + .read = mini_isp_intf_i2c_read, + .write = mini_isp_intf_i2c_write, + .send_bulk = mini_isp_intf_i2c_send_bulk, +}; +#endif + +static int mini_isp_intf_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status = 0; + struct misp_data *drv_data = NULL; + + misp_info("%s - start, addr[0x%x].", __func__, client->addr); + + /* step 0: Check if the adapter supports the needed features */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + misp_err("%s - i2c_check_functionality err.", __func__); + return -EIO; + } + /*step 1: alloc driver data struct*/ + drv_data = kmalloc(sizeof(struct misp_data), GFP_KERNEL); + if (!drv_data) { + status = -ENOMEM; + goto alloc_misp_data_fail; + } + misp_info("%s - step1 done.", __func__); + + /*step 2: init driver data*/ + drv_data->cfg.i2c = client; + drv_data->intf_fn = &intf_i2c_fn; + drv_data->bulk_cmd_blocksize = I2C_TX_BULK_SIZE; + misp_info("%s - step2 done.", __func__); + + /*step 3: setup recource : gpio, sem*/ + if (id->driver_data == MINIISP_I2C_SLAVE) { + misp_intf_i2c_slave_data = drv_data; + i2c_set_clientdata(client, misp_intf_i2c_slave_data); + misp_info("%s - misp_intf_i2c_slave_data set done.", __func__); + } else if (id->driver_data == MINIISP_I2C_TOP) { + misp_intf_i2c_top_data = drv_data; + i2c_set_clientdata(client, misp_intf_i2c_top_data); + status = mini_isp_setup_resource(&client->dev, drv_data); + if (status < 0) { + misp_err("%s step3. probe - setup resource error", __func__); + goto setup_i2c_error; + } + misp_info("%s - misp_intf_i2c_top_data set done.", __func__); + } else { + misp_err("%s - probe fail.", __func__); + kfree(drv_data); + return -ENODEV; + } + + set_mini_isp_data(drv_data, INTF_I2C_READY); + goto done; + +setup_i2c_error: + kfree(misp_intf_i2c_top_data); + misp_intf_i2c_top_data = NULL; + +alloc_misp_data_fail: + +done: + return status; + +} +static int mini_isp_intf_i2c_remove(struct i2c_client *client) +{ + struct misp_data *misp_intf_i2c = i2c_get_clientdata(client); + + if (!misp_intf_i2c) { + misp_err("%s: i2c data is NULL\n", __func__); + return 0; + } + + kfree(misp_intf_i2c); + + return 0; +} +static const struct of_device_id mini_isp_dt_i2c_slave_match[] = { + { .compatible = "altek,i2c_slave",}, + /*Compatible node must match dts*/ + { }, + }; + +MODULE_DEVICE_TABLE(of, mini_isp_dt_i2c_slave_match); + +static const struct of_device_id mini_isp_dt_i2c_top_match[] = { + { .compatible = "altek,i2c_top",}, + /*Compatible node must match dts*/ + { }, + }; + +MODULE_DEVICE_TABLE(of, mini_isp_dt_i2c_top_match); + +struct i2c_driver mini_isp_intf_i2c_slave = { + .driver = { + .name = "altek_i2c_slave", + .owner = THIS_MODULE, + .of_match_table = mini_isp_dt_i2c_slave_match, + }, + .probe = mini_isp_intf_i2c_probe, + .remove = mini_isp_intf_i2c_remove, + .id_table = mini_isp_intf_i2c_id, +}; + +struct i2c_driver mini_isp_intf_i2c_top = { + .driver = { + .name = "altek_i2c_top", + .owner = THIS_MODULE, + .of_match_table = mini_isp_dt_i2c_top_match, + }, + .probe = mini_isp_intf_i2c_probe, + .remove = mini_isp_intf_i2c_remove, + .id_table = mini_isp_intf_i2c_id, +}; diff --git a/drivers/media/platform/altek/miniisp_intf_spi.c b/drivers/media/platform/altek/miniisp_intf_spi.c new file mode 100755 index 000000000000..5eac2ca934d0 --- /dev/null +++ b/drivers/media/platform/altek/miniisp_intf_spi.c @@ -0,0 +1,727 @@ +/* + * File: miniisp_spi.c + * Description: Mini ISP sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2017/04/11; LouisWang; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/******Include File******/ +/* Linux headers*/ +#include +#include +#include +#include +#include + + +#include "include/miniisp.h" +#include "include/miniisp_ctrl.h" +#include "include/miniisp_customer_define.h" +#include "include/miniisp_chip_base_define.h" + +#include "include/error/miniisp_err.h" + +#ifdef ALTEK_TEST +#include "include/altek_test.h" +#endif + +/******Private Constant Definition******/ +#define DEBUG_NODE 0 + +/*#define DEBUG_ALERT*/ +#define MINI_ISP_LOG_TAG "[miniisp_intf_spi]" + +/*drv debug defination*/ +#define _SPI_DEBUG + + +/**************************************************************************** +* Private Global Variable * +****************************************************************************/ +static struct misp_data *misp_intf_spi_data; +struct file *filp[4]; +static u8 *spi_bulkbuffer; +/**************************************************************************** +* Private Function Prototype * +****************************************************************************/ + +#if DEBUG_NODE +static ssize_t +mini_isp_config_show(struct device *dev, struct device_attribute *attr, + char *buf); +static ssize_t +mini_isp_config_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); +static DEVICE_ATTR(mini_isp_config, S_IRUGO|S_IWUSR, mini_isp_config_show, + mini_isp_config_store); +#endif + +/********************************************************************** +* Public Function * +**********************************************************************/ + + +/******Public Function******/ +struct misp_data *get_mini_isp_intf_spi(void) +{ + if (!misp_intf_spi_data) { + misp_err("%s - get pdata error", __func__); + return NULL; + } else { + return misp_intf_spi_data; + } +} + +#ifdef _SPI_DEBUG +void spi_data_debug(const void *buf, int data_len, int dbg_len) +{ + int len = 0, pos = 0; + unsigned char *char_buf = (unsigned char *)buf; + unsigned char string[100], temp[4]; + + memset(string, 0, sizeof(string)); + + len = (dbg_len > data_len) ? data_len : dbg_len; + + pos = 0; + while (len > 0) { + if (len > 7) { + misp_info("%02x %02x %02x %02x %02x %02x %02x %02x", + char_buf[pos], char_buf[pos+1], char_buf[pos+2], + char_buf[pos+3], char_buf[pos+4], char_buf[pos+5], + char_buf[pos+6], char_buf[pos+7]); + + len -= 8; + pos += 8; + } else { + for ( ; len > 0; len--) { + snprintf(temp, 4, "%02x ", char_buf[pos++]); + strlcat(string, temp, 24); + } + misp_info("%s", string); + } + } +} +#else +#define spi_data_debug(buf, data_len, dbg_len) +#endif + +int mini_isp_dma_write(struct spi_device *spi, u8 *tx_buf, u32 len) +{ + int state; + dma_addr_t bus_addr; + + struct spi_transfer t = { + .tx_buf = tx_buf, + .len = len, + }; + struct spi_message m; + + misp_info("%s - entering ", __func__); + + spi_message_init(&m); + + bus_addr = dma_map_single(&spi->dev, tx_buf, len, DMA_TO_DEVICE); + + if (!bus_addr) { + misp_err("%s dma mapping failed.", __func__); + state = -ENOMEM; + goto mini_isp_dma_write_end; + } + + t.tx_dma = bus_addr; + m.is_dma_mapped = 1; + + spi_message_add_tail(&t, &m); + + state = spi_sync(spi, &m); + + dma_unmap_single(&spi->dev, bus_addr, len, DMA_TO_DEVICE); + + misp_info("%s - leave ", __func__); + +mini_isp_dma_write_end: + + return state; +} + +/**************************************************************************** +* Private Function * +****************************************************************************/ + +/*read command from device ,this function will block. + *return 0 successful + *others fail + */ +static int mini_isp_intf_spi_read(void *dev, u8 *tx_buf, + u32 tx_len, u8 *rx_buf, u32 rx_len) +{ + struct spi_transfer t = { + .tx_buf = tx_buf, + .rx_buf = rx_buf, + .len = tx_len + rx_len, + .delay_usecs = 1, + .speed_hz = SPI_BUS_SPEED, + }; + struct spi_message m; + struct misp_global_variable *misp_drv_global; + struct misp_data *devdata = (struct misp_data *)dev; + int status; + + misp_drv_global = get_mini_isp_global_variable(); + + if (!devdata) { + misp_err("%s - invalid arg devdata = %p, len = %d", + __func__, devdata, tx_len + rx_len); + return -EINVAL; + } + + if (misp_drv_global->before_booting) { + devdata->cfg.spi->max_speed_hz = SPI_BUS_SPEED_BOOT; + t.speed_hz = SPI_BUS_SPEED_BOOT; + } else if (misp_drv_global->spi_low_speed_mode) { + devdata->cfg.spi->max_speed_hz = SPI_BUS_SPEED_LOW; + t.speed_hz = SPI_BUS_SPEED_LOW; + } else { + /* Set to SPI high speed after booting */ + devdata->cfg.spi->max_speed_hz = SPI_BUS_SPEED; + } + + status = spi_setup(devdata->cfg.spi); + if (status < 0) + misp_err("%s : setup spi error", __func__); + + if (tx_len + rx_len <= 32) + return spi_write_then_read(devdata->cfg.spi, + tx_buf, tx_len, rx_buf, rx_len); + + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + + return spi_sync(devdata->cfg.spi, &m); +} + + +/*write commadn to device ,this fucntion will block. + *return 0 successful + *others fail + */ +static int mini_isp_intf_spi_write(void *dev, u8 *tx_buf, + u8 *rx_buf, u32 len) +{ + struct spi_transfer t = { + .tx_buf = tx_buf, + .rx_buf = rx_buf, + .len = len, + .delay_usecs = 1, + .speed_hz = SPI_BUS_SPEED, + }; + struct spi_message m; + struct misp_global_variable *misp_drv_global; + struct misp_data *devdata = (struct misp_data *)dev; + + misp_drv_global = get_mini_isp_global_variable(); + if (!devdata) { + misp_err("%s - invalid arg devdata = %p, len = %d", + __func__, devdata, len); + return -EINVAL; + } + + if (misp_drv_global->before_booting) + t.speed_hz = SPI_BUS_SPEED_BOOT; + else if (misp_drv_global->spi_low_speed_mode) + t.speed_hz = SPI_BUS_SPEED_LOW; + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + + return spi_sync(devdata->cfg.spi, &m); +} + +/* + *write command data to spi + *return 0 successful + *others fail + */ +static int mini_isp_intf_spi_send(void *dev, u32 len) +{ + int status; + u8 check = USPICTRL_MS_CB_ORG; + u8 spi_databuffer[TX_BUF_SIZE + 1] = {0}; + struct misp_data *devdata = (struct misp_data *)dev; + + if ((!devdata) || (len > TX_BUF_SIZE)) { + misp_err("%s - invalid arg devdata = %p, len = %d", __func__, + devdata, len); + return -EINVAL; + } + + /*put the ctrl byte in the first byte, then put the following data.*/ + spi_databuffer[0] = check; + + memcpy(spi_databuffer + 1, devdata->tx_buf, len); + + status = mini_isp_intf_spi_write(devdata, spi_databuffer, + NULL, len + 1); + if (status) { + misp_err("%s - sync error: status = %d", __func__, status); + return status; + } + + return status; +} + +/* read miniISP using spi ,this fucntion will block. + *return 0 successful + *others fail + */ +static int mini_isp_intf_spi_recv(void *dev, u32 len, bool waitINT) +{ + int status; + u8 ctrlbyte = USPICTRL_MS_CB_RSP; + int i = 0; + int original_altek_spi_mode; + u32 altek_event_state; + u8 spi_databuffer[TX_BUF_SIZE + 1] = {0}; + u8 *spi_txbuf = NULL; + u8 *spi_rxbuf = NULL; + struct misp_global_variable *dev_global_variable; + struct misp_data *devdata = (struct misp_data *)dev; + + misp_err("%s - enter", __func__); + + dev_global_variable = get_mini_isp_global_variable(); + original_altek_spi_mode = dev_global_variable->altek_spi_mode; + if ((!devdata) || (len > RX_BUF_SIZE)) { + misp_err("%s - invalid arg devdata = %p, len = %d", + __func__, devdata, len); + status = -EINVAL; + goto mini_isp_intf_spi_recv_end; + } + spi_txbuf = &spi_databuffer[0]; + spi_rxbuf = &spi_databuffer[1]; + + memset(spi_databuffer, 0, RX_BUF_SIZE + 1); + + if (waitINT) { + /*wait for the interrupt*/ + status = mini_isp_wait_for_event(MINI_ISP_RCV_CMD_READY); + } else { + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (original_altek_spi_mode == ALTEK_SPI_MODE_A)) + mini_isp_a_to_e(); + for (i = 0; i < 200; i++) { + status = mini_isp_get_altek_status(devdata, + &altek_event_state); + if (altek_event_state & COMMAND_COMPLETE) { + altek_event_state = (altek_event_state & + ~((~0) << 1)); + mini_isp_register_write( + INTERRUPT_STATUS_REGISTER_ADDR, + altek_event_state); + break; + } + msleep(20); /* mdelay(5); */ + } + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (original_altek_spi_mode != + dev_global_variable->altek_spi_mode)) + mini_isp_e_to_a(); + if (i >= 200) { + misp_err("%s time out.", __func__); + status = ERR_MINIISP_GETDATA_TIMEOUT; + goto mini_isp_intf_spi_recv_end; + } + } + + if (status) { + misp_err("%s - irq error: status = %d", __func__, status); + goto mini_isp_intf_spi_recv_end; + } + + /*send the ctrl byte and get the data in full duplex mode*/ + /*the data is stored from the 2nd byte*/ + *spi_txbuf = ctrlbyte; + status = mini_isp_intf_spi_read(devdata, spi_txbuf, 1, spi_rxbuf, len); + if (status) { + misp_err("%s - sync error: status = %d", __func__, status); + goto mini_isp_intf_spi_recv_end; + } + + /* full duplex mode, skip tx_len */ + if (len+1 > 32) { + if (len > RX_BUF_SIZE - 1) + misp_err("%s - invalid len = %d", + __func__, len); + else + memcpy(devdata->rx_buf, spi_rxbuf + 1, len); + } else { + /* half duplex mode, no need skip tx_len */ + memcpy(devdata->rx_buf, spi_rxbuf, len); + } + + misp_info("%s - recv buf len = %d:", __func__, len); + spi_data_debug(devdata->rx_buf, RX_BUF_SIZE, len); + +mini_isp_intf_spi_recv_end: + return status; +} + +#if ENABLE_LINUX_FW_LOADER +/*used to send the firmware*/ +static int mini_isp_intf_spi_send_bulk(void *dev, + u32 total_size, u32 block_size, bool is_raw, + const u8 *spi_Sendbulkbuffer) +{ + int status = 0, count = 0; + int remain_size, one_size; + u8 ctrlbyte = USPICTRL_MS_CB_DIS, ack[2]; + int shift = 0; + struct misp_data *devdata = (struct misp_data *)dev; + + misp_info("%s - entering", __func__); + + if (spi_Sendbulkbuffer != NULL) { + misp_info("%s start. Total size: %d.", __func__, total_size); + if (!is_raw) { + /*send the ctrl byte*/ + status = mini_isp_intf_spi_read(devdata, &ctrlbyte, + 1, ack, 2); + if (status) { + misp_err("%s send ctrlbyte fail status: %d", + __func__, status); + status = -EINVAL; + goto T_EXIT; + } + } + + /* Allocate basic code bulk buffer*/ + if (total_size > SPI_TX_BULK_SIZE) + spi_bulkbuffer = kzalloc(SPI_TX_BULK_SIZE, GFP_DMA); + /* Allocate boot code bulk buffer*/ + else + spi_bulkbuffer = kzalloc(total_size, GFP_DMA); + + if (!spi_bulkbuffer) { + status = -EINVAL; + misp_err("%s - Can not alloc SPI bulk buffer", + __func__); + goto T_EXIT; + } + + for (remain_size = total_size; remain_size > 0; + remain_size -= one_size) { + + one_size = (remain_size > block_size) ? + block_size : remain_size; + + misp_info("remain size: %d one_size: %d.", + remain_size, one_size); + + memcpy(spi_bulkbuffer, (spi_Sendbulkbuffer + shift), + one_size); + shift += one_size; + + /*send the data*/ + status = mini_isp_intf_spi_write(devdata, + spi_bulkbuffer, NULL, one_size); + + if (status != 0) { + misp_err( + "%s failed! block:%d status:%d", + __func__, count, status); + break; + } + + count++; + } + + } +T_EXIT: + + /* Free SPI bulk buffer*/ + if (spi_bulkbuffer != NULL) { + kfree(spi_bulkbuffer); + spi_bulkbuffer = NULL; + } + + if (status != ERR_SUCCESS) + misp_err("%s error: %d", __func__, status); + else + misp_info("%s success", __func__); + + return status; +} + +#else +/*used to send the firmware*/ +static int mini_isp_intf_spi_send_bulk(void *dev, struct file *filp, + u32 total_size, u32 block_size, bool is_raw, u8 *spi_Sendbulkbuffer) +{ + int status = 0, count = 0; + int remain_size, one_size; + u8 ctrlbyte = USPICTRL_MS_CB_DIS, ack[2]; + mm_segment_t oldfs; + loff_t offset; + int shift = 0; + struct misp_data *devdata = (struct misp_data *)dev; + + misp_info("%s - entering", __func__); + + if (spi_Sendbulkbuffer != NULL) { + misp_info("%s start. Total size: %d.", __func__, total_size); + if (!is_raw) { + /*send the ctrl byte*/ + status = mini_isp_intf_spi_read(devdata, &ctrlbyte, + 1, ack, 2); + if (status) { + misp_err("%s send ctrlbyte fail status: %d", + __func__, status); + status = -EINVAL; + goto T_EXIT; + } + } + + /* Allocate basic code bulk buffer*/ + if (total_size > SPI_TX_BULK_SIZE) + spi_bulkbuffer = kzalloc(SPI_TX_BULK_SIZE, GFP_DMA); + /* Allocate boot code bulk buffer*/ + else + spi_bulkbuffer = kzalloc(total_size, GFP_DMA); + + if (!spi_bulkbuffer) { + status = -EINVAL; + misp_err("%s - Can not alloc SPI bulk buffer", + __func__); + goto T_EXIT; + } + + for (remain_size = total_size; remain_size > 0; + remain_size -= one_size) { + one_size = (remain_size > block_size) ? + block_size : remain_size; + + + /* misp_info("remain size: %d one_size: %d.", */ + /* remain_size, one_size); */ + + memcpy(spi_bulkbuffer, (spi_Sendbulkbuffer + shift), + one_size); + shift += one_size; + + /*send the data*/ + status = mini_isp_intf_spi_write(devdata, + spi_bulkbuffer, NULL, one_size); + + if (status != 0) { + misp_err( + "%s failed! block:%d status:%d", + __func__, count, status); + break; + } + + /* misp_info("%s write block %d success", */ + /* __func__, count); */ + + count++; + } + + } else { + oldfs = get_fs(); + + set_fs(get_ds()); + + misp_info("%s start. Total size: %d", __func__, total_size); + + if (!is_raw) { + /*send the ctrl byte*/ + status = mini_isp_intf_spi_read(devdata, &ctrlbyte, + 1, ack, 2); + misp_info("%s is not raw", __func__); + if (status) { + misp_err("%s ctrl byte fail status: %d", + __func__, status); + status = -EINVAL; + goto T_EXIT; + } + } + + /* Allocate basic code bulk buffer*/ + if (total_size > SPI_TX_BULK_SIZE_BOOT) + spi_bulkbuffer = kzalloc(SPI_TX_BULK_SIZE, GFP_DMA); + /* Allocate boot code bulk buffer*/ + else + spi_bulkbuffer = kzalloc(SPI_TX_BULK_SIZE_BOOT, + GFP_DMA); + + + if (!spi_bulkbuffer) { + misp_err("%s - Can not alloc SPI bulk buffer", + __func__); + status = -EINVAL; + goto T_EXIT; + } + + for (remain_size = total_size; remain_size > 0; + remain_size -= one_size) { + one_size = (remain_size > block_size) ? + block_size : remain_size; + + /* misp_info("remain size: %d one_size: %d", */ + /* remain_size, one_size); */ + + /*copy the firmware to the buffer*/ + offset = filp->f_pos; + status = vfs_read(filp, spi_bulkbuffer, one_size, + &offset); + + if (status == -1) { + misp_info("%s Read file failed.", __func__); + break; + } + + filp->f_pos = offset; + + /*send the data*/ + status = mini_isp_intf_spi_write(devdata, + spi_bulkbuffer, NULL, one_size); + if (status != 0) { + misp_err("%s send fail, block:%d status: %d", + __func__, count, status); + break; + } + + /* misp_info("%s write block %d success", */ + /* __func__, count); */ + + count++; + } + } +T_EXIT: + if (filp && (spi_Sendbulkbuffer == NULL)) + set_fs(oldfs); + /* Free SPI bulk buffer*/ + if (spi_bulkbuffer != NULL) { + kfree(spi_bulkbuffer); + spi_bulkbuffer = NULL; + } + + if (status != ERR_SUCCESS) + misp_err("%s error: %d", __func__, status); + else + misp_info("%s success", __func__); + + return status; +} +#endif + +static struct misp_intf_fn_t intf_spi_fn = { + .send = mini_isp_intf_spi_send, + .recv = mini_isp_intf_spi_recv, + .read = mini_isp_intf_spi_read, + .write = mini_isp_intf_spi_write, + .send_bulk = mini_isp_intf_spi_send_bulk, +}; + +static int mini_isp_intf_spi_probe(struct spi_device *spi) +{ + int status = 0; + + misp_info("%s - start", __func__); + + /*step 1: alloc driver data struct*/ + misp_intf_spi_data = kzalloc(sizeof(struct misp_data), GFP_KERNEL); + if (!misp_intf_spi_data) { + status = -EINVAL; + misp_err("%s step1. probe - alloc misp_intf_spi_data error", + __func__); + return -ENOMEM; + } + misp_info("%s - step1 done.", __func__); + + /*step 2: init driver data*/ + misp_intf_spi_data->cfg.spi = spi; + misp_intf_spi_data->intf_fn = &intf_spi_fn; + misp_intf_spi_data->bulk_cmd_blocksize = SPI_TX_BULK_SIZE; + + misp_info("%s - step2 done.", __func__); + + /*step 3: setup spi*/ + spi->mode = SPI_MODE; + spi->max_speed_hz = SPI_BUS_SPEED_BOOT; + spi->bits_per_word = 8; + status = spi_setup(spi); + if (status < 0) { + misp_err("%s step3. probe - setup spi error", __func__); + goto setup_spi_error; + } + misp_info("%s - step3 done.", __func__); + + /*step 3: setup recource : gpio, sem*/ + status = mini_isp_setup_resource(&spi->dev, misp_intf_spi_data); + if (status < 0) { + misp_err("%s step4. probe - setup resource error", __func__); + goto setup_spi_error; + } + misp_info("%s - step4 done.", __func__); + + /*setp last: set driver_data to device*/ + spi_set_drvdata(spi, misp_intf_spi_data); + set_mini_isp_data(misp_intf_spi_data, INTF_SPI_READY); + + misp_info("%s -success", __func__); + mini_isp_get_chip_id(); + goto probe_done; + +setup_spi_error: + kfree(misp_intf_spi_data); + misp_intf_spi_data = NULL; + +probe_done: + return status; +} + +static int mini_isp_intf_spi_remove(struct spi_device *spi) +{ + kfree(misp_intf_spi_data); + return 0; +} + +/*Compatible node must match dts*/ +static const struct of_device_id mini_isp_dt_spi_match[] = { + { .compatible = "altek,isp",}, + { }, +}; +MODULE_DEVICE_TABLE(of, mini_isp_dt_spi_match); + + +struct spi_driver mini_isp_intf_spi = { + .driver = { + .name = "altek_isp", + .owner = THIS_MODULE, + .of_match_table = mini_isp_dt_spi_match, + }, + .probe = mini_isp_intf_spi_probe, + .remove = mini_isp_intf_spi_remove, +}; diff --git a/drivers/media/platform/altek/miniisp_isp.c b/drivers/media/platform/altek/miniisp_isp.c new file mode 100644 index 000000000000..4e0226aa37ae --- /dev/null +++ b/drivers/media/platform/altek/miniisp_isp.c @@ -0,0 +1,2038 @@ +/* + * File: miniisp_spi.c + * Description: Mini ISP sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2017/04/11; LouisWang; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/************************************************************ +* Include File * +*************************************************************/ +/* Linux headers*/ +#include +#include +#include +#include +#include + + +#include "include/miniisp.h" +#include "include/miniisp_ctrl.h" +#include "include/miniisp_customer_define.h" +#include "include/miniisp_chip_base_define.h" +#include "include/ispctrl_if_master.h" +#include "include/isp_camera_cmd.h" +#include "include/error/miniisp_err.h" + +#if EN_605_IOCTRL_INTF +/* ALTEK_AL6100_ECHO >>> */ +#include "include/miniisp_ctrl_intf.h" +/* ALTEK_AL6100_ECHO <<< */ +#endif + +#ifdef ALTEK_TEST +#include "include/altek_test.h" +#endif + +/**************************************************************************** +* Private Constant Definition * +****************************************************************************/ +#define DEBUG_NODE 0 +/*#define DEBUG_ALERT*/ +#define MINI_ISP_LOG_TAG "[miniisp_isp]" +/*drv debug defination*/ +#define _SPI_DEBUG + +/**************************************************************************** +* Private Global Variable * +****************************************************************************/ +static struct misp_global_variable *misp_drv_global_variable; +static struct class *mini_isp_class; +static struct device *mini_isp_dev; + +#if EN_605_IOCTRL_INTF +/* ALTEK_AL6100_ECHO >>> */ +struct file *l_internal_file[ECHO_OTHER_MAX]; +/* ALTEK_AL6100_ECHO <<< */ +#endif + +extern u16 fw_version_before_point; +extern u16 fw_version_after_point; +extern char fw_build_by[]; +extern char fw_project_name[]; +extern u32 sc_build_date; +/************************************************************ + * Public Global Variable + *************************************************************/ + +/************************************************************ + * Private Macro Definition + *************************************************************/ + +/************************************************************ + * Public Function Prototype + *************************************************************/ + + +/************************************************************ + * Private Function + *************************************************************/ +#if EN_605_IOCTRL_INTF +void mini_isp_other_drv_open_l(char *file_name, u8 type) +{ + + /* Error Code*/ + errcode err = ERR_SUCCESS; + + misp_info("%s filepath : %s", __func__, file_name); + +#if ENABLE_FILP_OPEN_API + /* use file open */ +#else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + return; +#endif + if (IS_ERR(l_internal_file[type])) { + err = PTR_ERR(l_internal_file[type]); + misp_err("%s open file failed. err: %x", __func__, err); + } else { + misp_info("%s open file success!", __func__); + } + +} +#endif +static ssize_t mini_isp_mode_config_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + /*misp_info("%s - mini_isp_spi_send return %d", __func__, ret);*/ + return snprintf(buf, 32, "load fw:0 e_to_a:1 a_to_e:2\n"); +} + +static ssize_t mini_isp_mode_config_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + u8 buf_chip_id_use[4]; + + if ('0' == buf[0]) { + mini_isp_chip_init(); + mini_isp_e_to_a(); + mini_isp_drv_load_fw(); + } else if ('1' == buf[0]) { + mini_isp_chip_init(); + mini_isp_e_to_a(); + } else if ('2' == buf[0]) { + mini_isp_a_to_e(); + } else if ('4' == buf[0]) { + mini_isp_get_chip_id(); + } else if ('7' == buf[0]) { + buf_chip_id_use[0] = 0; + mini_isp_debug_dump_img(); + mini_isp_a_to_e(); + mini_isp_chip_base_dump_irp_and_depth_based_register(); + mini_isp_memory_write(0x10, buf_chip_id_use, 1); + mini_isp_e_to_a(); + } else { + mini_isp_poweron(); + mini_isp_drv_set_bypass_mode(1); + } + return size; +} + +static DEVICE_ATTR(mini_isp_mode_config, 0660, mini_isp_mode_config_show, + mini_isp_mode_config_store); + +static ssize_t mini_isp_reset_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = -EINVAL; + + ret = gpio_get_value(misp_drv_global_variable->reset_gpio); + misp_info("%s - reset_gpio is %d", __func__, ret); + + return snprintf(buf, 32, "%d", ret); +} + +static ssize_t mini_isp_reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + if ('0' == buf[0]) + gpio_set_value(misp_drv_global_variable->reset_gpio, 0); + else + gpio_set_value(misp_drv_global_variable->reset_gpio, 1); + + misp_info("%s - ", __func__); + + return size; +} + +static DEVICE_ATTR(mini_isp_reset, 0660, + mini_isp_reset_show, + mini_isp_reset_store); + + +static ssize_t mini_isp_rectab_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, 32, "Set rectab Param!!\n"); +} + +static ssize_t mini_isp_rectab_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + u8 trans_mode; + u32 block_size; + struct depth_rectab_invrect_param rect_param[3]; + + misp_info("Set rectab start!!"); + + /* fill test pattern */ + memset((u8 *)&rect_param[0], 0xa, + 3*sizeof(struct depth_rectab_invrect_param)); + + trans_mode = 0; + block_size = 64; + + mini_isp_drv_write_depth_rectab_invrect( + &rect_param[0], trans_mode, block_size); + + misp_info("Set rectab end!!"); + return size; +} + +static DEVICE_ATTR(mini_isp_rectab, 0660, + mini_isp_rectab_show, + mini_isp_rectab_store); + +ssize_t echo_mini_isp_drv_set_depth_3a_info(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + struct isp_cmd_depth_3a_info depth_3a_info; + + memset(&depth_3a_info, 0, sizeof(struct isp_cmd_depth_3a_info)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %hu %u %hu %hu %hu %hu %hu %hu %hd %hhu\ + %u %hu %hu %hu %hu %hu %hu %hd %hhu\ + %hu %hu %hd %hd %hu %hu %hhu", + cmd_name, + &depth_3a_info.hdr_ratio, + &depth_3a_info.main_cam_exp_time, + &depth_3a_info.main_cam_exp_gain, + &depth_3a_info.main_cam_amb_r_gain, + &depth_3a_info.main_cam_amb_g_gain, + &depth_3a_info.main_cam_amb_b_gain, + &depth_3a_info.main_cam_iso, + &depth_3a_info.main_cam_bv, + &depth_3a_info.main_cam_vcm_position, + &depth_3a_info.main_cam_vcm_status, + &depth_3a_info.sub_cam_exp_time, + &depth_3a_info.sub_cam_exp_gain, + &depth_3a_info.sub_cam_amb_r_gain, + &depth_3a_info.sub_cam_amb_g_gain, + &depth_3a_info.sub_cam_amb_b_gain, + &depth_3a_info.sub_cam_iso, + &depth_3a_info.sub_cam_bv, + &depth_3a_info.sub_cam_vcm_position, + &depth_3a_info.sub_cam_vcm_status, + &depth_3a_info.main_cam_isp_d_gain, + &depth_3a_info.sub_cam_isp_d_gain, + &depth_3a_info.hdr_long_exp_ev_x1000, + &depth_3a_info.hdr_short_exp_ev_x1000, + &depth_3a_info.ghost_prevent_low, + &depth_3a_info.ghost_prevent_high, + &depth_3a_info.depth_proc_mode); + + if (ret != 27) { + errcode = -EINVAL; + return errcode; + } + + misp_info("%hu %u %hu %hu %hu %hu %hu %hu %hd %hhu\ + %u %hu %hu %hu %hu %hu %hu %hd %hhu\ + %hu %hu %hd %hd %hu %hu %hhu", + depth_3a_info.hdr_ratio, + depth_3a_info.main_cam_exp_time, + depth_3a_info.main_cam_exp_gain, + depth_3a_info.main_cam_amb_r_gain, + depth_3a_info.main_cam_amb_g_gain, + depth_3a_info.main_cam_amb_b_gain, + depth_3a_info.main_cam_iso, + depth_3a_info.main_cam_bv, + depth_3a_info.main_cam_vcm_position, + depth_3a_info.main_cam_vcm_status, + depth_3a_info.sub_cam_exp_time, + depth_3a_info.sub_cam_exp_gain, + depth_3a_info.sub_cam_amb_r_gain, + depth_3a_info.sub_cam_amb_g_gain, + depth_3a_info.sub_cam_amb_b_gain, + depth_3a_info.sub_cam_iso, + depth_3a_info.sub_cam_bv, + depth_3a_info.sub_cam_vcm_position, + depth_3a_info.sub_cam_vcm_status, + depth_3a_info.main_cam_isp_d_gain, + depth_3a_info.sub_cam_isp_d_gain, + depth_3a_info.hdr_long_exp_ev_x1000, + depth_3a_info.hdr_short_exp_ev_x1000, + depth_3a_info.ghost_prevent_low, + depth_3a_info.ghost_prevent_high, + depth_3a_info.depth_proc_mode); + + mini_isp_drv_set_depth_3a_info(&depth_3a_info); + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_depth_auto_interleave_mode(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[4]; + struct isp_cmd_depth_auto_interleave_param depth_auto_interleave_param; + + memset(&depth_auto_interleave_param, 0, + sizeof(struct isp_cmd_depth_auto_interleave_param)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u %u", cmd_name, + ¶m[0], ¶m[1], ¶m[2], ¶m[3]); + depth_auto_interleave_param.depth_interleave_mode_on_off = (u8) param[0]; + depth_auto_interleave_param.skip_frame_num_after_illuminator_pulse = (u8) param[1]; + depth_auto_interleave_param.projector_power_level = (u8) param[2]; + depth_auto_interleave_param.illuminator_power_level = (u8) param[3]; + + if (ret != 5) { + errcode = -EINVAL; + return errcode; + } + + misp_info("%d, %d, %d, %d", + depth_auto_interleave_param.depth_interleave_mode_on_off, + depth_auto_interleave_param.skip_frame_num_after_illuminator_pulse, + depth_auto_interleave_param.projector_power_level, + depth_auto_interleave_param.illuminator_power_level); + + mini_isp_drv_set_depth_auto_interleave_mode(&depth_auto_interleave_param); + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_exposure_param(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[3]; + + struct isp_cmd_exposure_param set_exposure_param; + + memset(&set_exposure_param, 0, sizeof(struct isp_cmd_exposure_param)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u", cmd_name, ¶m[0], ¶m[1], ¶m[2]); + if (ret != 4) { + errcode = -EINVAL; + return errcode; + } + + set_exposure_param.udExpTime = (u32)param[0]; + set_exposure_param.uwISO = (u16)param[1]; + set_exposure_param.ucActiveDevice = (u8)param[2]; + + misp_info("menu exposure param: %d %d %d", + set_exposure_param.udExpTime, + set_exposure_param.uwISO, + set_exposure_param.ucActiveDevice); + + mini_isp_drv_set_exposure_param(&set_exposure_param); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_depth_stream_size(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[1]; + + struct isp_cmd_depth_stream_size depth_stream_size_param; + + memset(&depth_stream_size_param, 0, sizeof(struct isp_cmd_depth_stream_size)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u", cmd_name, ¶m[0]); + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + depth_stream_size_param.depth_stream_size = (u8)param[0]; + + misp_info("depth stream size: %d", + depth_stream_size_param.depth_stream_size); + + mini_isp_drv_set_depth_stream_size(&depth_stream_size_param); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_sensor_mode(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u8 sensor_on_off = 0; + u8 scenario_id = 0; + u8 mipi_tx_skew_enable = 0; + u8 ae_weighting_table_index = 0; + u8 merge_mode_enable = 0; + + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %hhu %hhu %hhu %hhu %hhu", + cmd_name, &sensor_on_off, &scenario_id, &mipi_tx_skew_enable, + &ae_weighting_table_index, &merge_mode_enable); + + if (ret != 6) { + errcode = -EINVAL; + return errcode; + } + + misp_info("0x%x, 0x%x, 0x%x, 0x%x, 0x%x", sensor_on_off, scenario_id, mipi_tx_skew_enable, + ae_weighting_table_index, merge_mode_enable); + + mini_isp_drv_set_sensor_mode(sensor_on_off, scenario_id, + mipi_tx_skew_enable, ae_weighting_table_index, merge_mode_enable); + misp_info("%s E!!", __func__); + return errcode; +} + + +ssize_t echo_mini_isp_drv_set_output_format(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[3]; + struct isp_cmd_set_output_format output_format_param; + + memset(&output_format_param, 0, sizeof(struct isp_cmd_set_output_format)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u", cmd_name, ¶m[0], ¶m[1], ¶m[2]); + if (ret != 4) { + errcode = -EINVAL; + return errcode; + } + + misp_info("0x%x, 0x%x, 0x%x", param[0], param[1], param[2]); + output_format_param.depth_size = (u8)param[0]; + output_format_param.reserve[0] = (u8)param[1]; + output_format_param.reserve[1] = (u8)param[2]; + + errcode = mini_isp_drv_set_output_format(&output_format_param); + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_cp_mode(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S!!", __func__); + errcode = mini_isp_drv_set_cp_mode(); + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_leave_cp_mode(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u8 param[5]; + + misp_info("%s S!!", __func__); + ret = sscanf(cmd_buf, "%19s %hhu %hhu %hhu %hhu %hhu", + cmd_name, ¶m[0], ¶m[1], + ¶m[2], ¶m[3], ¶m[4]); + if (ret != 6) { + errcode = -EINVAL; + return errcode; + } + + + misp_info("0x%x, 0x%x, 0x%x, 0x%x, 0x%x", + param[0], param[1], param[2], param[3], param[4]); + + errcode = mini_isp_drv_leave_cp_mode(param[0], param[1], param[2], param[3], param[4]); + misp_info("%s E!!", __func__); + return errcode; +} +ssize_t echo_mini_isp_drv_preview_stream_on_off(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u8 tx0_stream_on_off; + u8 tx1_stream_on_off; + + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %hhu %hhu", cmd_name, + &tx0_stream_on_off, &tx1_stream_on_off); + + if (ret != 3) { + errcode = -EINVAL; + return errcode; + } + + misp_info("0x%x, 0x%x", + tx0_stream_on_off, tx1_stream_on_off); + errcode = mini_isp_drv_preview_stream_on_off( + tx0_stream_on_off, tx1_stream_on_off); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_led_power_control(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[8]; + struct isp_cmd_led_power_control projector_control_param; + + memset(&projector_control_param, 0, sizeof(struct isp_cmd_led_power_control)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u %u %u %u %u %u", + cmd_name, ¶m[0], ¶m[1], ¶m[2], + ¶m[3], ¶m[4], ¶m[5], + ¶m[6], ¶m[7]); + + if (ret != 9) { + errcode = -EINVAL; + return errcode; + } + + projector_control_param.led_on_off = (u8)param[0]; + projector_control_param.led_power_level = (u8)param[1]; + projector_control_param.control_projector_id = (u8)param[2]; + projector_control_param.delay_after_sof = param[3]; + projector_control_param.pulse_time = param[4]; + projector_control_param.control_mode = (u8)param[5]; + projector_control_param.reserved = (u8)param[6]; + projector_control_param.rolling_shutter = (u8)param[7]; + + misp_info("%d, %d, %d, %d, %d, %d, %d, %d", + projector_control_param.led_on_off, + projector_control_param.led_power_level, + projector_control_param.control_projector_id, + projector_control_param.delay_after_sof, + projector_control_param.pulse_time, + projector_control_param.control_mode, + projector_control_param.reserved, + projector_control_param.rolling_shutter); + + errcode = mini_isp_drv_led_power_control(&projector_control_param); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_active_ae(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[2]; + struct isp_cmd_active_ae active_ae_param; + + memset(&active_ae_param, 0, + sizeof(struct isp_cmd_active_ae)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u", + cmd_name, ¶m[0], ¶m[1]); + + if (ret != 3) { + errcode = -EINVAL; + return errcode; + } + + + active_ae_param.active_ae = (u8)param[0]; + active_ae_param.f_number_x1000 = param[1]; + + misp_info("%d, %d", + active_ae_param.active_ae, + active_ae_param.f_number_x1000); + + errcode = mini_isp_drv_active_ae(&active_ae_param); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_isp_ae_control_mode_on_off(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param; + + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u", cmd_name, ¶m); + + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + misp_info("%d", param); + + errcode = mini_isp_drv_isp_ae_control_mode_on_off(param); + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_frame_rate_limits(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[4]; + struct isp_cmd_frame_rate_limits frame_rate_param; + + memset(&frame_rate_param, 0, + sizeof(struct isp_cmd_frame_rate_limits)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u %u", cmd_name, + ¶m[0], ¶m[1], ¶m[2], ¶m[3]); + + if (ret != 5) { + errcode = -EINVAL; + return errcode; + } + + frame_rate_param.main_min_framerate_x100 = param[0]; + frame_rate_param.main_max_framerate_x100 = param[1]; + frame_rate_param.sub_min_framerate_x100 = param[2]; + frame_rate_param.sub_max_framerate_x100 = param[3]; + + misp_info("%d %d %d %d", + frame_rate_param.main_min_framerate_x100, + frame_rate_param.main_max_framerate_x100, + frame_rate_param.sub_min_framerate_x100, + frame_rate_param.sub_max_framerate_x100); + + errcode = mini_isp_drv_set_frame_rate_limits(&frame_rate_param); + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_max_exposure(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[3]; + + struct isp_cmd_exposure_param set_max_exposure; + + memset(&set_max_exposure, 0, sizeof(struct isp_cmd_exposure_param)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u", + cmd_name, ¶m[0], ¶m[1], ¶m[2]); + + if (ret != 4) { + errcode = -EINVAL; + return errcode; + } + + set_max_exposure.udExpTime = (u32)param[0]; + set_max_exposure.uwISO = (u16)param[1]; + set_max_exposure.ucActiveDevice = (u8)param[2]; + + misp_info("max exposure param: %d %d %d", + set_max_exposure.udExpTime, + set_max_exposure.uwISO, + set_max_exposure.ucActiveDevice); + + mini_isp_drv_set_max_exposure(&set_max_exposure); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_frame_sync_control(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[5]; + struct isp_cmd_frame_sync_control frame_sync_control_param; + + memset(&frame_sync_control_param, 0, sizeof(struct isp_cmd_frame_sync_control)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u %u %u", cmd_name, + ¶m[0], ¶m[1], ¶m[2], ¶m[3], ¶m[4]); + + if (ret != 6) { + errcode = -EINVAL; + return errcode; + } + + frame_sync_control_param.control_deviceID = (u8) param[0]; + frame_sync_control_param.delay_framephase = (u8) param[1]; + frame_sync_control_param.active_framephase = (u8) param[2]; + frame_sync_control_param.deactive_framephase = (u8)param[3]; + frame_sync_control_param.active_timelevel = (u8) param[4]; + + misp_info("%d %d %d %d %d", + frame_sync_control_param.control_deviceID, + frame_sync_control_param.delay_framephase, + frame_sync_control_param.active_framephase, + frame_sync_control_param.deactive_framephase, + frame_sync_control_param.active_timelevel); + + errcode = mini_isp_drv_frame_sync_control(&frame_sync_control_param); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_shot_mode(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[2]; + struct isp_cmd_set_shot_mode set_shot_mode_param; + + memset(&set_shot_mode_param, 0, sizeof(struct isp_cmd_set_shot_mode)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u", cmd_name, ¶m[0], ¶m[1]); + + if (ret != 3) { + errcode = -EINVAL; + return errcode; + } + + set_shot_mode_param.shot_mode = (u8) param[0]; + set_shot_mode_param.frame_rate = (u16) param[1]; + + misp_info("%d %d", + set_shot_mode_param.shot_mode, + set_shot_mode_param.frame_rate); + + errcode = mini_isp_drv_set_shot_mode(&set_shot_mode_param); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_lighting_ctrl(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u8 i = 0; + u32 param[25]; + struct isp_cmd_lighting_ctrl lighting_ctrl; + + memset(&lighting_ctrl, 0, sizeof(struct isp_cmd_lighting_ctrl)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u\ + %u %u %u %u %u", + cmd_name, ¶m[0], ¶m[1], ¶m[2], + ¶m[3], ¶m[4], ¶m[5], ¶m[6], + ¶m[7], ¶m[8], ¶m[9], ¶m[10], + ¶m[11], ¶m[12], ¶m[13], ¶m[14], + ¶m[15], ¶m[16], ¶m[17], ¶m[18], + ¶m[19], ¶m[20], ¶m[21], ¶m[22], + ¶m[23], ¶m[24]); + + if (ret != 26) { + errcode = -EINVAL; + return errcode; + } + + lighting_ctrl.cycle_len = param[0]; + for (i = 0; i < lighting_ctrl.cycle_len; i++) { + lighting_ctrl.cycle[i].source = (u8)param[i*3+1]; + lighting_ctrl.cycle[i].TxDrop = (u8)param[i*3+2]; + lighting_ctrl.cycle[i].co_frame_rate = (u16)param[i*3+3]; + } + + misp_info("cycle_len: %d", lighting_ctrl.cycle_len); + for (i = 0; i < lighting_ctrl.cycle_len; i++) { + misp_info("cycle[%d]: %d, %d, %d", i, + lighting_ctrl.cycle[i].source, + lighting_ctrl.cycle[i].TxDrop, + lighting_ctrl.cycle[i].co_frame_rate); + } + + errcode = mini_isp_drv_lighting_ctrl(&lighting_ctrl); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_depth_compensation(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[4]; + u8 en_update = 0; + struct isp_cmd_depth_compensation_param depth_compensation_param; + + memset(&depth_compensation_param, 0, + sizeof(struct isp_cmd_depth_compensation_param)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u %u", cmd_name, + ¶m[0], ¶m[1], ¶m[2], ¶m[3]); + + if (ret != 5) { + errcode = -EINVAL; + return errcode; + } + + en_update = (param[0] << 4) | param[1]; + depth_compensation_param.en_updated = (u8)en_update; + depth_compensation_param.short_distance_value = (u16)param[2]; + depth_compensation_param.compensation = (s8)param[3]; + + misp_info("0x%x %d %d", + depth_compensation_param.en_updated, + depth_compensation_param.short_distance_value, + depth_compensation_param.compensation); + + mini_isp_drv_depth_compensation(&depth_compensation_param); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_cycle_trigger_depth_process(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[3]; + + struct isp_cmd_cycle_trigger_depth_process depth_cycle_param; + + memset(&depth_cycle_param, 0, + sizeof(struct isp_cmd_cycle_trigger_depth_process)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u", cmd_name, + ¶m[0], ¶m[1], ¶m[2]); + + if (ret != 4) { + errcode = -EINVAL; + return errcode; + } + + depth_cycle_param.cycleLen = (u8)param[0]; + depth_cycle_param.depth_triggerBitField = (u16)param[1]; + depth_cycle_param.depthoutput_triggerBitField = (u16)param[2]; + + misp_info("depth cycle len: 0%d %d %d", + depth_cycle_param.cycleLen, + depth_cycle_param.depth_triggerBitField, + depth_cycle_param.depthoutput_triggerBitField); + + mini_isp_drv_cycle_trigger_depth_process(&depth_cycle_param); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_min_exposure(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[3]; + + struct isp_cmd_exposure_param set_min_exposure; + + memset(&set_min_exposure, 0, + sizeof(struct isp_cmd_exposure_param)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u %u", cmd_name, + ¶m[0], ¶m[1], ¶m[2]); + + if (ret != 4) { + errcode = -EINVAL; + return errcode; + } + + set_min_exposure.udExpTime = (u32)param[0]; + set_min_exposure.uwISO = (u16)param[1]; + set_min_exposure.ucActiveDevice = (u8)param[2]; + + misp_info("min exposure param: %d %d %d", + set_min_exposure.udExpTime, + set_min_exposure.uwISO, + set_min_exposure.ucActiveDevice); + + mini_isp_drv_set_min_exposure(&set_min_exposure); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_max_exposure_slope(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[2]; + + struct isp_cmd_max_exposure_slope max_exposure_slope; + + memset(&max_exposure_slope, 0, + sizeof(struct isp_cmd_max_exposure_slope)); + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u %u", cmd_name, + ¶m[0], ¶m[1]); + + if (ret != 3) { + errcode = -EINVAL; + return errcode; + } + + max_exposure_slope.max_exposure_slope = (u32)param[0]; + max_exposure_slope.ucActiveDevice = (u8)param[1]; + + misp_info("max exposure slope: %d %d", + max_exposure_slope.max_exposure_slope, + max_exposure_slope.ucActiveDevice); + + mini_isp_drv_set_max_exposure_slope(&max_exposure_slope); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_led_active_delay(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 delay_ms = 0; + + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u", cmd_name, &delay_ms); + + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + misp_info("[delay]: %d", delay_ms); + + mini_isp_drv_led_active_delay(delay_ms); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_isp_control_led_level(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 on = 0; + + misp_info("%s S!!", __func__); + + ret = sscanf(cmd_buf, "%19s %u", cmd_name, &on); + + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + misp_info("[isp control led level]: %d", on); + + mini_isp_drv_isp_control_led_level((u8)on); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_get_chip_thermal(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + u16 thermal_val; + + misp_info("%s S!!", __func__); + + mini_isp_drv_get_chip_thermal(&thermal_val); + misp_info("0x%x", thermal_val); + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_poweron(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S!!", __func__); + mini_isp_poweron(); + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_poweroff(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S!!", __func__); + mini_isp_poweroff(); + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_load_fw(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S!!", __func__); + misp_info("%s no FSM", __func__); + /*check bypass mode be set or not*/ + /*if yes, leave bypass mode*/ + mini_isp_check_and_leave_bypass_mode(); + /*normal case load FW*/ + errcode = mini_isp_drv_load_fw(); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_write_calibration_data(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param; + + misp_info("%s S!!", __func__); + ret = sscanf(cmd_buf, "%19s %u", cmd_name, ¶m); + + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + misp_info("%d", param); + if (param == 0 || param == 1) { + misp_info("Currently echo mode not support" + " IQ calibration and packdata!"); + goto ERR; + } + errcode = mini_isp_drv_write_calibration_data(param, NULL, 0); +ERR: + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_write_spinor_data(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param; + + misp_info("%s S!!", __func__); + ret = sscanf(cmd_buf, "%19s %u", cmd_name, ¶m); + + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + misp_info("%d", param); + if (param > 1) + goto ERR; + + errcode = mini_isp_drv_write_spinor_data(param); +ERR: + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_mini_isp_get_chip_id(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S!!", __func__); + errcode = mini_isp_get_chip_id(); + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_get_comlog(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + struct common_log_hdr_info info; + + memset(&info, 0, sizeof(struct common_log_hdr_info)); + misp_info("%s S!!", __func__); + + info.block_size = SPI_TX_BULK_SIZE; + info.total_size = LEVEL_LOG_BUFFER_SIZE; + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_set_register(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param[2]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + misp_info("%s S", __func__); + /* switch to E mode */ + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + ret = sscanf(cmd_buf, "%19s 0x%x 0x%x", cmd_name, ¶m[0], ¶m[1]); + if (ret != 3) { + errcode = -EINVAL; + return errcode; + } + + mini_isp_register_write(param[0], param[1]); + misp_info("set register 0x%x, 0x%x", param[0], param[1]); + + /* switch to A mode */ + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_get_register(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + u32 param; + u32 reg_val; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + misp_info("%s S", __func__); + /* switch to E mode */ + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + ret = sscanf(cmd_buf, "%19s 0x%x", cmd_name, ¶m); + + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + mini_isp_register_read(param, ®_val); + misp_info("get register 0x%x, 0x%x", param, reg_val); + + /* switch to A mode */ + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_memdump(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + char cmd_name[20]; + char filename[80]; + u32 param[2]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + misp_info("%s S", __func__); + /* switch to E mode */ + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + ret = sscanf(cmd_buf, "%19s 0x%x %u", cmd_name, ¶m[0], ¶m[1]); + + if (ret != 3) { + errcode = -EINVAL; + return errcode; + } + + misp_info("Get mem 0x%x, %d\n", param[0], param[1]); + + snprintf(filename, 80, "memdump_0x%x_%d", param[0], param[1]); + mini_isp_memory_read_then_write_file(param[0], param[1], + MINIISP_INFO_DUMPLOCATION, filename); + + /* switch to A mode */ + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_show_version(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + misp_info("MINIISP_DRIVER_VERSION: %s", MINIISP_DRIVER_VERSION); + misp_info("AL6100 project: %s, fw ver: %05d.%05d, build by %s", + fw_project_name, fw_version_before_point, fw_version_after_point, fw_build_by); + misp_info("SC table build data: %d", sc_build_date); + misp_info("set fsm status: %d", dev_global_variable->now_state); + return errcode; +} + +ssize_t echo_set_fsm_status(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + u32 param; + char cmd_name[20]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + ret = sscanf(cmd_buf, "%19s %u", cmd_name, ¶m); + + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + dev_global_variable->now_state = param; + misp_info("set fsm status: %d", dev_global_variable->now_state); + return errcode; +} + +ssize_t echo_cfg_cmd_send(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + u32 param; + char cmd_name[20]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + ret = sscanf(cmd_buf, "%19s %u", cmd_name, ¶m); + + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + dev_global_variable->en_cmd_send = param; + misp_info("set en_cmd_send: %d", dev_global_variable->en_cmd_send); + return errcode; +} + +ssize_t echo_mini_isp_a_to_e(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s, S", __func__); + mini_isp_a_to_e(); + misp_info("%s, E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_e_to_a(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s, S", __func__); + mini_isp_e_to_a(); + misp_info("%s, E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_chip_init(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s, S", __func__); + mini_isp_chip_init(); + misp_info("%s, E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_debug_dump_img(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s, S", __func__); + errcode = mini_isp_debug_dump_img(); + misp_info("%s, E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_drv_set_bypass_mode(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + u16 param; + char cmd_name[20]; + + misp_info("%s S", __func__); + ret = sscanf(cmd_buf, "%19s %hu", cmd_name, ¶m); + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + if (param == 0) + param = 1; +/* errcode = mini_isp_drv_set_bypass_mode(param); */ + errcode = mini_isp_pure_bypass(param); + + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_utility_read_reg_e_mode_for_bypass_use(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S", __func__); + errcode = mini_isp_utility_read_reg_e_mode_for_bypass_use(); + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_utility_read_reg_e_mode(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S", __func__); + errcode = mini_isp_utility_read_reg_e_mode(); + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_debug_packdata_dump(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S", __func__); + errcode = mini_isp_debug_packdata_dump(); + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_debug_IQCalib_dump(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S", __func__); + errcode = mini_isp_debug_IQCalib_dump(); + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_debug_metadata_dump(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S", __func__); + errcode = mini_isp_debug_metadata_dump(); + misp_info("%s E", __func__); + return errcode; +} + + + +ssize_t echo_mini_isp_debug_rect_combo_dump(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + u8 param; + char cmd_name[20]; + + misp_info("%s S", __func__); + ret = sscanf(cmd_buf, "%19s %hhu", cmd_name, ¶m); + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + misp_info("dump mode %hhu", param); + errcode = mini_isp_debug_depth_rect_combo_dump(param); + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_debug_depth_info(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S", __func__); + errcode = mini_isp_debug_depth_info(); + misp_info("%s E", __func__); + return errcode; +} + + +ssize_t echo_mini_isp_debug_metadata_info(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S", __func__); + errcode = mini_isp_debug_metadata_info(); + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_debug_sensor_info(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + u8 param; + char cmd_name[20]; + + misp_info("%s S", __func__); + ret = sscanf(cmd_buf, "%19s %hhu", cmd_name, ¶m); + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + errcode = mini_isp_debug_sensor_info(param); + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_debug_led_info(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + u8 param; + char cmd_name[20]; + + misp_info("%s S", __func__); + ret = sscanf(cmd_buf, "%19s %hhu", cmd_name, ¶m); + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + errcode = mini_isp_debug_led_info(param); + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_debug_rx_fps_info(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + u8 param[2]; + char cmd_name[20]; + + misp_info("%s S", __func__); + ret = sscanf(cmd_buf, "%19s %hhu %hhu", cmd_name, ¶m[0], ¶m[1]); + if (ret != 3) { + errcode = -EINVAL; + return errcode; + } + + if (param[0] == 0) { + misp_info("rx_fps_info initial!"); + errcode = mini_isp_debug_mipi_rx_fps_start(param[1]); + } else if (param[0] == 1) { + misp_info("rx_fps_info exit!"); + mini_isp_debug_mipi_rx_fps_stop(); + } + + misp_info("%s E", __func__); + return errcode; +} +ssize_t echo_mini_isp_debug_GPIO_Status(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + u8 param; + char cmd_name[20]; + + misp_info("%s S", __func__); + ret = sscanf(cmd_buf, "%19s %hhu", cmd_name, ¶m); + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + errcode = mini_isp_debug_GPIO_Status(param); + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_eeprom_wp(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + int ret; + struct misp_global_variable *dev_global_variable; + u8 param; + char cmd_name[20]; + + misp_info("%s S", __func__); + ret = sscanf(cmd_buf, "%19s %hhu", cmd_name, ¶m); + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + if (WP_GPIO != NULL) { + dev_global_variable = get_mini_isp_global_variable(); + if (param) + gpio_set_value(dev_global_variable->wp_gpio, 1); + else + gpio_set_value(dev_global_variable->wp_gpio, 0); + } + misp_info("%s E", __func__); + return errcode; +} + +ssize_t echo_mini_isp_eeprom_op(const char *cmd_buf) +{ + errcode errcode = ERR_SUCCESS; + int ret; + struct misp_global_variable *dev_global_variable; + u8 filename[80]; + struct file *filp = NULL; + mm_segment_t oldfs; + off_t currpos; + u8 *data_buf_addr; + u32 total_size; + u8 param; + char cmd_name[20]; + + misp_info("%s S", __func__); + ret = sscanf(cmd_buf, "%19s %hhu", cmd_name, ¶m); + if (ret != 2) { + errcode = -EINVAL; + return errcode; + } + + if (param == 1) { + dev_global_variable = get_mini_isp_global_variable(); + + snprintf(filename, 80, "%s/WRITE_OTP_DATA.bin", + MINIISP_INFO_DUMPLOCATION); + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + /*open the file*/ + #if ENABLE_FILP_OPEN_API + /* use file open */ + #else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + goto code_end; + #endif + /*get the file size*/ + currpos = vfs_llseek(filp, 0L, SEEK_END); + if (currpos == -1) { + misp_err("%s llseek failed", __func__); + errcode = ~ERR_SUCCESS; + goto code_end; + } + total_size = (u32)currpos; + misp_info("%s filesize : %d", __func__, total_size); + vfs_llseek(filp, 0L, SEEK_SET); + + if (total_size) { + data_buf_addr = kzalloc(total_size, GFP_KERNEL); + if (data_buf_addr == NULL) { + misp_err("%s - Kzalloc data buf fail ", __func__); + goto code_end; + } + errcode = vfs_read(filp, data_buf_addr, total_size, + &filp->f_pos); + + if (errcode == -1) { + misp_err("%s - Read file failed.", __func__); + } else { + if (WP_GPIO != NULL) + gpio_set_value(dev_global_variable->wp_gpio, 0); + + errcode = mini_isp_drv_write_calibration_data(9, + data_buf_addr, total_size); + misp_info("%s write otp data = %x", __func__, errcode); + + if (WP_GPIO != NULL) + gpio_set_value(dev_global_variable->wp_gpio, 1); + } + kfree(data_buf_addr); + } +code_end: + set_fs(oldfs); + /*close the file*/ + filp_close(filp, NULL); + } else if (param == 2) + errcode = mini_isp_drv_read_calibration_data(); + else + misp_err("%s - Not Support ", __func__); + + misp_info("%s E!!", __func__); + return errcode; +} + +ssize_t echo_test(const char *cmd_buf) +{ + size_t errcode = ERR_SUCCESS; + + misp_info("%s S", __func__); + + misp_info("%s, E", __func__); + return errcode; +} + +struct echo_cmd_format { + u32 opcode; + char cmd_name[30]; + ssize_t (*pfunc)(const char *cmd_buf); +}; + +struct echo_cmd_format echo_cmd_list[] = { + {.opcode = 0x10B9, .cmd_name = "depth_3a_info", + .pfunc = echo_mini_isp_drv_set_depth_3a_info}, + {.opcode = 0x10BC, .cmd_name = "interleave", + .pfunc = echo_mini_isp_drv_set_depth_auto_interleave_mode}, + {.opcode = 0x10BF, .cmd_name = "set_menu_exposure", + .pfunc = echo_mini_isp_drv_set_exposure_param}, + {.opcode = 0x10C0, .cmd_name = "set_depth_stream_size", + .pfunc = echo_mini_isp_drv_set_depth_stream_size}, + {.opcode = 0x300A, .cmd_name = "set_sensor", + .pfunc = echo_mini_isp_drv_set_sensor_mode}, + {.opcode = 0x300D, .cmd_name = "output_format", + .pfunc = echo_mini_isp_drv_set_output_format}, + {.opcode = 0x300E, .cmd_name = "enter_cp", + .pfunc = echo_mini_isp_drv_set_cp_mode}, + {.opcode = 0x3010, .cmd_name = "streamon", + .pfunc = echo_mini_isp_drv_preview_stream_on_off}, + {.opcode = 0x3012, .cmd_name = "led_power", + .pfunc = echo_mini_isp_drv_led_power_control}, + {.opcode = 0x3013, .cmd_name = "active_ae", + .pfunc = echo_mini_isp_drv_active_ae}, + {.opcode = 0x3014, .cmd_name = "ae_onoff", + .pfunc = echo_mini_isp_drv_isp_ae_control_mode_on_off}, + {.opcode = 0x3015, .cmd_name = "framerate", + .pfunc = echo_mini_isp_drv_set_frame_rate_limits}, + {.opcode = 0x3017, .cmd_name = "set_max_exposure", + .pfunc = echo_mini_isp_drv_set_max_exposure}, + {.opcode = 0x3019, .cmd_name = "frame_sync", + .pfunc = echo_mini_isp_drv_frame_sync_control}, + {.opcode = 0x301A, .cmd_name = "shot_mode", + .pfunc = echo_mini_isp_drv_set_shot_mode}, + {.opcode = 0x301B, .cmd_name = "lighting_ctrl", + .pfunc = echo_mini_isp_drv_lighting_ctrl}, + {.opcode = 0x301C, .cmd_name = "depth_compensation", + .pfunc = echo_mini_isp_drv_depth_compensation}, + {.opcode = 0x301D, .cmd_name = "cycle_trigger_depth", + .pfunc = echo_mini_isp_drv_cycle_trigger_depth_process}, + {.opcode = 0x301E, .cmd_name = "set_min_exposure", + .pfunc = echo_mini_isp_drv_set_min_exposure}, + {.opcode = 0x301F, .cmd_name = "set_max_exposure_slop", + .pfunc = echo_mini_isp_drv_set_max_exposure_slope}, + {.opcode = 0x3020, .cmd_name = "led_active_delay", + .pfunc = echo_mini_isp_drv_led_active_delay}, + {.opcode = 0x3021, .cmd_name = "isp_control_led_level", + .pfunc = echo_mini_isp_drv_isp_control_led_level}, + {.opcode = 0x3022, .cmd_name = "get_chip_thermal", + .pfunc = echo_mini_isp_drv_get_chip_thermal}, + {.opcode = 0xFFFF, .cmd_name = "power_on", + .pfunc = echo_mini_isp_poweron}, + {.opcode = 0xFFFF, .cmd_name = "power_off", + .pfunc = echo_mini_isp_poweroff}, + {.opcode = 0xFFFF, .cmd_name = "load_fw", + .pfunc = echo_mini_isp_drv_load_fw}, + {.opcode = 0xFFFF, .cmd_name = "load_cali", + .pfunc = echo_mini_isp_drv_write_calibration_data}, + {.opcode = 0xFFFF, .cmd_name = "load_spinor", + .pfunc = echo_mini_isp_drv_write_spinor_data}, + {.opcode = 0xFFFF, .cmd_name = "get_chip_id", + .pfunc = echo_mini_isp_get_chip_id}, + {.opcode = 0xFFFF, .cmd_name = "leave_cp", + .pfunc = echo_mini_isp_drv_leave_cp_mode}, + {.opcode = 0xFFFF, .cmd_name = "comlog", + .pfunc = echo_get_comlog}, + {.opcode = 0xFFFF, .cmd_name = "setreg", + .pfunc = echo_set_register}, + {.opcode = 0xFFFF, .cmd_name = "getreg", + .pfunc = echo_get_register}, + {.opcode = 0xFFFF, .cmd_name = "memdump", + .pfunc = echo_memdump}, + {.opcode = 0xFFFF, .cmd_name = "version", + .pfunc = echo_show_version}, + {.opcode = 0xFFFF, .cmd_name = "set_fsm_status", + .pfunc = echo_set_fsm_status}, + {.opcode = 0xFFFF, .cmd_name = "cfg_cmd_send", + .pfunc = echo_cfg_cmd_send}, + {.opcode = 0xFFFF, .cmd_name = "a2e", + .pfunc = echo_mini_isp_a_to_e}, + {.opcode = 0xFFFF, .cmd_name = "e2a", + .pfunc = echo_mini_isp_e_to_a}, + {.opcode = 0xFFFF, .cmd_name = "chip_init", + .pfunc = echo_mini_isp_chip_init}, + {.opcode = 0xFFFF, .cmd_name = "pure_bypass", + .pfunc = echo_mini_isp_drv_set_bypass_mode}, + {.opcode = 0xFFFF, .cmd_name = "dump_bypass_reg", + .pfunc = echo_mini_isp_utility_read_reg_e_mode_for_bypass_use}, + {.opcode = 0xFFFF, .cmd_name = "dump_normal_reg", + .pfunc = echo_mini_isp_utility_read_reg_e_mode}, + {.opcode = 0xFFFF, .cmd_name = "dump_packdata", + .pfunc = echo_mini_isp_debug_packdata_dump}, + {.opcode = 0xFFFF, .cmd_name = "dump_IQCalib", + .pfunc = echo_mini_isp_debug_IQCalib_dump}, + {.opcode = 0xFFFF, .cmd_name = "dump_Meta", + .pfunc = echo_mini_isp_debug_metadata_dump}, + {.opcode = 0xFFFF, .cmd_name = "dump_irp_img", + .pfunc = echo_mini_isp_debug_dump_img}, + {.opcode = 0xFFFF, .cmd_name = "dump_depth_reg", + .pfunc = echo_mini_isp_debug_rect_combo_dump}, + {.opcode = 0xFFFF, .cmd_name = "debug_depth_info", + .pfunc = echo_mini_isp_debug_depth_info}, + {.opcode = 0xFFFF, .cmd_name = "debug_metadata_info", + .pfunc = echo_mini_isp_debug_metadata_info}, + {.opcode = 0xFFFF, .cmd_name = "debug_sensor_info", + .pfunc = echo_mini_isp_debug_sensor_info}, + {.opcode = 0xFFFF, .cmd_name = "debug_led_info", + .pfunc = echo_mini_isp_debug_led_info}, + {.opcode = 0xFFFF, .cmd_name = "debug_rx_fps_info", + .pfunc = echo_mini_isp_debug_rx_fps_info}, + {.opcode = 0xFFFF, .cmd_name = "debug_GPIO_status", + .pfunc = echo_mini_isp_debug_GPIO_Status}, + {.opcode = 0xFFFF, .cmd_name = "eeprom_wp", + .pfunc = echo_mini_isp_eeprom_wp}, + {.opcode = 0xFFFF, .cmd_name = "eeprom_op", + .pfunc = echo_mini_isp_eeprom_op}, + {.opcode = 0xFFFF, .cmd_name = "test", + .pfunc = echo_test}, +}; + +#define echo_cmd_list_len \ + (sizeof(echo_cmd_list) / sizeof(struct echo_cmd_format)) + +static ssize_t mini_isp_cmd_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + /* print cmd list */ + u32 total_len = 0, count = 0; + u32 i = 0; + + for (i = 0; i < echo_cmd_list_len; i++) { + count = snprintf(buf, 70, "%s\n", echo_cmd_list[i].cmd_name); + buf += count; /* move buffer pointer */ + total_len += count; + } + + return total_len; +} + +static ssize_t mini_isp_cmd_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + char cmd_name[20]; + size_t errcode = ERR_SUCCESS; + int ret; + u32 opcode = 0x0; + u32 err = ERR_SUCCESS; + u32 loopidx = 0; + + ret = sscanf(buf, "%19s", cmd_name); + if (ret != 1) { + errcode = -EINVAL; + return errcode; + } + /* check first input is opcode or cmd_name */ + if (cmd_name[0] == '0' && cmd_name[1] == 'x') { + ret = sscanf(cmd_name, "0x%x", &opcode); + + if (ret != 1) { + errcode = -EINVAL; + return errcode; + } + } + + for (loopidx = 0; loopidx < echo_cmd_list_len; loopidx++) { + if (echo_cmd_list[loopidx].opcode == opcode || + strcmp(echo_cmd_list[loopidx].cmd_name, + cmd_name) == 0){ + + err = echo_cmd_list[loopidx].pfunc(buf); + if (err) + misp_info("%s, err: 0x%x", __func__, err); + + return size; + } + } + + misp_info("command not find!"); + return size; +} + +static +DEVICE_ATTR(mini_isp_cmd, 0660, mini_isp_cmd_show, mini_isp_cmd_store); + +/************************************************************ +* Public Function * +*************************************************************/ + +struct misp_data *get_mini_isp_intf(int i2c_type) +{ + if (misp_drv_global_variable->intf_status & INTF_SPI_READY) { + return get_mini_isp_intf_spi(); + } else if (misp_drv_global_variable->intf_status & INTF_I2C_READY) { + return get_mini_isp_intf_i2c(i2c_type); + /*} else if (misp_drv_global_variable->intf_status & INTF_CCI_READY) { + return get_mini_isp_intf_cci(i2c_type);*/ + } else { + misp_err("%s - error i2c type %d", __func__, i2c_type); + return NULL; + } +} +void set_mini_isp_data(struct misp_data *data, int intf_type) +{ + if (!misp_drv_global_variable) + misp_err("%s - set global_variable error", __func__); + else + misp_drv_global_variable->intf_status |= intf_type; +} + +struct misp_global_variable *get_mini_isp_global_variable(void) +{ + if (!misp_drv_global_variable) { + misp_err("%s - get global_variable error", __func__); + return NULL; + } else { + return misp_drv_global_variable; + } +} + +int mini_isp_setup_resource(struct device *dev, struct misp_data *drv_data) +{ + int status = 0; + + misp_info("%s - start", __func__); + if (misp_drv_global_variable != NULL) { + misp_err("%s - resource already been setupped", __func__); + goto setup_done; + } + + /*step 1: alloc misp_drv_global_variable*/ + misp_drv_global_variable = + kzalloc(sizeof(*misp_drv_global_variable), GFP_KERNEL); + + if (!misp_drv_global_variable) { + misp_info("%s - Out of memory", __func__); + status = -ENOMEM; + goto alloc_fail; + } + misp_info("%s - step1 done.", __func__); + + /*step 2: init mutex and gpio resource*/ + mutex_init(&misp_drv_global_variable->busy_lock); + status = mini_isp_gpio_init(dev, drv_data, misp_drv_global_variable); + if (status < 0) { + misp_info("%s - gpio init fail", __func__); + goto setup_fail; + } + misp_info("%s - step2 done.", __func__); + + misp_drv_global_variable->before_booting = 1; + misp_drv_global_variable->en_cmd_send = 1; + + /*step 3: register to VFS as character device*/ + mini_isp_class = class_create(THIS_MODULE, "mini_isp"); + if (IS_ERR(mini_isp_class)) + misp_err("Failed to create class(mini_isp_class)!"); + mini_isp_dev = miniisp_chdev_create(mini_isp_class); + + if (IS_ERR(mini_isp_dev)) + misp_err("Failed to create device(mini_isp_dev)!"); + + status = device_create_file(mini_isp_dev, + &dev_attr_mini_isp_mode_config); + + if (status < 0) + misp_err("Failed to create device file(%s)!", + dev_attr_mini_isp_mode_config.attr.name); + + if (RESET_GPIO != NULL) { + status = device_create_file(mini_isp_dev, + &dev_attr_mini_isp_reset); + + if (status < 0) + misp_err("Failed to create device file(%s)!", + dev_attr_mini_isp_reset.attr.name); + } + + status = device_create_file(mini_isp_dev, + &dev_attr_mini_isp_rectab); + if (status < 0) + misp_err("Failed to create device file(%s)!", + dev_attr_mini_isp_rectab.attr.name); + + status = device_create_file(mini_isp_dev, + &dev_attr_mini_isp_cmd); + if (status < 0) + misp_err("Failed to create device file(%s)!", + dev_attr_mini_isp_cmd.attr.name); + + misp_info("%s - step3 done.", __func__); + + misp_info("%s - success.", __func__); + goto setup_done; + +setup_fail: + mutex_destroy(&misp_drv_global_variable->busy_lock); + kfree(misp_drv_global_variable); + +alloc_fail: + misp_drv_global_variable = NULL; + +setup_done: + return status; +} + +struct device *mini_isp_getdev(void) +{ + return mini_isp_dev; +} + +static int __init mini_isp_init(void) +{ + int ret = 0; + extern struct spi_driver mini_isp_intf_spi; + extern struct i2c_driver mini_isp_intf_i2c_slave; + extern struct i2c_driver mini_isp_intf_i2c_top; + + misp_info("%s - start", __func__); + isp_mast_camera_profile_para_init(); + + /* register SPI driver */ + ret = spi_register_driver(&mini_isp_intf_spi); + if (ret) { + misp_err("%s - regsiter failed. Errorcode:%d", + __func__, ret); + } + + /* register I2C driver */ + ret = i2c_add_driver(&mini_isp_intf_i2c_slave); + if (ret) + misp_info("%s - failed. Error:%d", __func__, ret); + + ret = i2c_add_driver(&mini_isp_intf_i2c_top); + if (ret) + misp_info("%s - failed. Error:%d", __func__, ret); + + misp_info("MINIISP_DRIVER_VERSION: %s", MINIISP_DRIVER_VERSION); + misp_info("%s - success", __func__); + + return ret; +} + +static void __exit mini_isp_exit(void) +{ + extern struct spi_driver mini_isp_intf_spi; + extern struct i2c_driver mini_isp_intf_i2c_slave; + extern struct i2c_driver mini_isp_intf_i2c_top; + + misp_info("%s", __func__); + + if (misp_drv_global_variable->irq_gpio) + gpio_free(misp_drv_global_variable->irq_gpio); + + /*if (misp_drv_global_variable)*/ + kfree(misp_drv_global_variable); + + /* unregister all driver */ + spi_unregister_driver(&mini_isp_intf_spi); + i2c_del_driver(&mini_isp_intf_i2c_slave); + i2c_del_driver(&mini_isp_intf_i2c_top); +} + +module_init(mini_isp_init); +module_exit(mini_isp_exit); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/media/platform/altek/miniisp_top.c b/drivers/media/platform/altek/miniisp_top.c new file mode 100644 index 000000000000..82f1961eee20 --- /dev/null +++ b/drivers/media/platform/altek/miniisp_top.c @@ -0,0 +1,1934 @@ +/* + * File: miniisp_top.c + * Description: Mini ISP sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2017/04/11; LouisWang; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + + /******Include File******/ + /* Linux headers*/ +#include +#include +#include +#include +#include +#include "include/miniisp.h" +#include "include/miniisp_ctrl.h" +#include "include/miniisp_customer_define.h" +#include "include/miniisp_chip_base_define.h" + +#include "include/error/miniisp_err.h" + +/**************************************************************************** +* Private Constant Definition * +****************************************************************************/ +#define EN_SPIE_DEBUG 0 +#define MINI_ISP_LOG_TAG "[miniisp_top]" +#define ALIGN_CEIL(x, N) (((x) + ((N) - 1)) / (N) * (N)) +static bool irqflag; +static u32 event = MINI_ISP_RCV_WAITING; +static u32 current_event = MINI_ISP_RCV_WAITING; +static DECLARE_WAIT_QUEUE_HEAD(WAITQ); +/********************************************************************** +* Public Function * +**********************************************************************/ +int mini_isp_get_chip_id(void) +{ + int status = ERR_SUCCESS; + u32 buff_id = 0; + + misp_info("%s - enter", __func__); + + mini_isp_register_read(CHIP_ID_ADDR, &buff_id); + + misp_err("[miniISP]Get Chip ID 0x%x", buff_id); + + return status; +} + + +void mini_isp_register_write(u32 reg_addr, u32 reg_new_value) +{ + u8 *send_buffer; + u8 ctrlbyte = CTRL_BYTE_REGWR; + u32 address = reg_addr, value = reg_new_value; + struct misp_data *devdata; + struct misp_global_variable *dev_global_variable; + + /* misp_info("%s - enter, reg_addr[%#08x], write_value[%#08x]", + __func__, reg_addr, reg_new_value); */ + + dev_global_variable = get_mini_isp_global_variable(); + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + + send_buffer = devdata->tx_buf; + + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &address, 4); + memcpy(send_buffer + 5, &value, 4); + /* dev_global_variable->before_booting = 1; */ + devdata->intf_fn->write(devdata, devdata->tx_buf, devdata->rx_buf, 9); + /* dev_global_variable->before_booting = 0; */ +} + +void mini_isp_register_write_one_bit(u32 reg_addr, + u8 bit_offset, u8 bit_value) +{ + u8 *send_buffer; + u32 reg_value; + u8 ctrlbyte = CTRL_BYTE_REGWR; + u32 address = reg_addr; + struct misp_data *devdata; + struct misp_global_variable *dev_global_variable; + + misp_info("%s - enter", __func__); + + dev_global_variable = get_mini_isp_global_variable(); + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + send_buffer = devdata->tx_buf; + + mini_isp_register_read(reg_addr, ®_value); + + if (bit_value) + reg_value |= 1UL << bit_offset; + else + reg_value &= ~(1UL << bit_offset); + + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &address, 4); + memcpy(send_buffer + 5, ®_value, 4); + /* dev_global_variable->before_booting = 1; */ + devdata->intf_fn->write(devdata, devdata->tx_buf, devdata->rx_buf, 9); + /* dev_global_variable->before_booting = 0; */ +} + + +void mini_isp_register_write_bit_field(u32 reg_addr, u32 mask, u32 mask_value) +{ + u8 *send_buffer; + u32 reg_value; + u8 ctrlbyte = CTRL_BYTE_REGWR; + u32 address = reg_addr, value; + struct misp_data *devdata; + struct misp_global_variable *dev_global_variable; + + misp_info("%s - enter", __func__); + + dev_global_variable = get_mini_isp_global_variable(); + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + send_buffer = devdata->tx_buf; + + mini_isp_register_read(reg_addr, ®_value); + value = (reg_value & ~mask) | mask_value; + + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &address, 4); + memcpy(send_buffer + 5, &value, 4); + /* dev_global_variable->before_booting = 1; */ + devdata->intf_fn->write(devdata, devdata->tx_buf, devdata->rx_buf, 9); + /* dev_global_variable->before_booting = 0; */ +} + +void mini_isp_e_to_a(void) +{ + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + misp_info("mini_isp_drv_setting(1) mini_isp_e_to_a"); + mini_isp_register_write(0xffef0240, 0x0); + /*mdelay(1);*/ + msleep(20); + dev_global_variable->altek_spi_mode = ALTEK_SPI_MODE_A; +} + + +void mini_isp_a_to_e(void) +{ + u8 *send_buffer; + u8 ctrlbyte = CTRL_BYTE_A2E; + struct misp_data *devdata; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + send_buffer = devdata->tx_buf; + + memcpy(send_buffer, &ctrlbyte, 1); + devdata->intf_fn->write(devdata, devdata->tx_buf, devdata->rx_buf, 1); + dev_global_variable->altek_spi_mode = ALTEK_SPI_MODE_E; + misp_info("mini_isp_drv_setting(2) mini_isp_a_to_e"); +} + +void mini_isp_chip_init(void) +{ + misp_info("%s - enter", __func__); + mini_isp_register_write(0xffe40050, 0x1); + mini_isp_register_write(0xffef00a4, 0xe); + udelay(70); + mini_isp_register_write(0xffef00a0, 0xe); + mini_isp_register_write(0xffe81080, 0x8); + mini_isp_register_write(0xffef0090, 0x30079241); + mini_isp_register_write(0xffe800c4, 0x0); + udelay(100); + misp_info("%s - leave", __func__); +} + +void mini_isp_cp_mode_suspend_flow(void) +{ + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + misp_info("%s - enter", __func__); + + /*# AP disable OCRAM0*/ + mini_isp_register_write_one_bit(0xffe609f4, 0, 1);/* # ocr0_disable*/ + + /*# 2.AP reset ARC5*/ + mini_isp_register_write_one_bit(0xffe800c4, 1, 1);/* # base_ck_in*/ + + /*# 3.AP reset modules(including arbiter bus)*/ + mini_isp_register_write_one_bit(0xffe801a4, 1, 1);/* # standby_top*/ + mini_isp_register_write_one_bit(0xffe80104, 1, 1);/* # arb_bus_stdby_0*/ + + /*# 4.AP stop clock of modules(including arbiter bus, OCRAM0) and ARC5*/ + mini_isp_register_write_one_bit(0xffe800c4, 0, 1);/* # base_ck_in*/ + mini_isp_register_write_one_bit(0xffe801a4, 0, 1);/* # standby_top*/ + mini_isp_register_write_one_bit(0xffe80104, 0, 1);/* # arb_bus_stdby_0*/ + mini_isp_register_write_one_bit(0xffe80104, 2, 1);/* # ocram_0*/ + + /*# 5.AP isolate standby power domain*/ + mini_isp_register_write_one_bit(0xffef00a0, 0, 1);/* # iso_pd_standby*/ + + /*# 6.AP power down standby power domain*/ + mini_isp_register_write_one_bit(0xffef00a4, 0, 1);/* # psw_pd_standby*/ + + /*# AP issue global reset of standby power domain*/ + /* # pd_rstn_standby_top*/ + mini_isp_register_write_one_bit(0xffe81080, 3, 0); + /*# 7.AP keep PLL factor then disable PLLs (Keep PLL_fix) + *# ClkGen have kept PLL factor so don't keep here + *#pll_var_ext_dat = [] + *# address of PLL factor + *#pll_var_ext_addr = [0xffe81120, 0xffe81124, 0xffe81128, + *# 0xffe8112c, 0xffe81130, 0xffe81134, + *# 0xffe81140, 0xffe81144, 0xffe81148, + *# 0xffe8114c, 0xffe81150, 0xffe81154 ] + *#for addr in pll_var_ext_addr: + *# (retsts, retdat) = altek_get_register(interface, + *# handle, I2C_SLAVE_ID, addr) + *# pll_var_ext_dat.append(retdat) + *# bit 11: reset_pll_ext, + *# bit 10: reset_pll_var, + *# bit 3: disable_pll_ext, + *# bit 2: disable_pll_var + */ + /*# 7.AP keep PLL factor then disable PLLs + *(disable PLL_fix, PLL_ext and PLL_var) + */ + mini_isp_register_write_bit_field(0xffe81004, 0x0e0e, 0x0e0e); + /*# AP do something*/ + /*mdelay(10);*/ + msleep(20); + misp_info("%s - leave", __func__); +} + +void mini_isp_cp_mode_resume_flow(void) +{ + u32 magic_number; + struct misp_global_variable *dev_global_variable; + errcode status = ERR_SUCCESS; + + misp_info("%s - enter", __func__); + dev_global_variable = get_mini_isp_global_variable(); + /*# 1.AP check magic number*/ + mini_isp_register_read(0xffef0008, &magic_number);/* # magic_number*/ + + /* + *# 2.AP check if magic number is equal to RESUME (0x19961224) + *then jump to step 4 + */ + if (magic_number != 0x19961224) { + /* + *# 3.Else exit resume flow + *(Note: AP can decide what to do. + *Ex: Toggle system reset of SK1 to reboot SK1) + */ + misp_err("%s-resume fail!,magic number not equal!", __func__); + return; + } + + /*# 4.AP power up standby power domain*/ + mini_isp_register_write_one_bit(0xffef00a4, 0, 0);/* # psw_pd_standby*/ + udelay(70);/* # 70us, TO-DO: depend on backend spec*/ + + /*# 5.AP release isolation of standby power domain*/ + mini_isp_register_write_one_bit(0xffef00a0, 0, 0);/* # iso_pd_standby*/ + + /*# AP release global reset of standby power domain*/ + /*# pd_rstn_standby_top*/ + mini_isp_register_write_one_bit(0xffe81080, 3, 1); + + /*# AP power up SRAM of ARC5*/ + mini_isp_register_write_one_bit(0xffef0090, 22, 0);/*# srampd_base_arc*/ + + /* + *# 6.AP enable clock of modules(including arbiter bus, OCRAM0) + *and ARC5 + */ + mini_isp_register_write_one_bit(0xffe800c4, 0, 0);/* # base_ck_in*/ + mini_isp_register_write_one_bit(0xffe801a4, 0, 0);/* # standby_top*/ + mini_isp_register_write_one_bit(0xffe80104, 0, 0);/* # arb_bus_stdby_0*/ + mini_isp_register_write_one_bit(0xffe80104, 2, 0);/* # ocram_0*/ + + /*# 7.AP release reset of modules(including arbiter bus)*/ + mini_isp_register_write_one_bit(0xffe801a4, 1, 0);/* # standby_top*/ + mini_isp_register_write_one_bit(0xffe80104, 1, 0);/* # arb_bus_stdby_0*/ + + /*# AP restore OCRAM0 setting*/ + mini_isp_register_write(0xffe609f8, 0xdbfc0); + mini_isp_register_write(0xffe609f4, 0); + mini_isp_register_write(0xffe60800, 0); + mini_isp_register_write(0xffe60900, 0); + + /*# 8. AP release reset of ARC5*/ + mini_isp_register_write_one_bit(0xffe800c4, 1, 0);/* # base_ck_in*/ + + /*# 9. AP wait interrupt then clean interrupt status*/ + status = mini_isp_wait_for_event(MINI_ISP_RCV_CPCHANGE); + misp_info("%s - leave", __func__); +} + +void mini_isp_check_and_leave_bypass_mode(void) +{ + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + if (dev_global_variable->be_set_to_bypass) { + /*Add code here*/ + mini_isp_register_write(0xffe80b04, 0x2a2a);/*mipidphy exc*/ + mini_isp_register_write(0xffe80944, 0x2);/*mipi tx phy 1*/ + mini_isp_register_write(0xffe80884, 0x2);/*mipi tx phy 0*/ + mini_isp_register_write(0xffe804e4, 0x2);/*ppibridge 1 exc*/ + mini_isp_register_write(0xffe804c4, 0x2);/*ppibridge 1*/ + mini_isp_register_write(0xffe804a4, 0x2);/*ppibridge 0 exc*/ + mini_isp_register_write(0xffe80484, 0x2);/*ppibridge 0*/ + mini_isp_register_write(0xffe80444, 0xa);/*mipi rx phy 1*/ + mini_isp_register_write(0xffe80404, 0xa);/*mipi rx phy 0*/ + + dev_global_variable->be_set_to_bypass = 0; + } else { + /*do nothing*/ + misp_info("not running bypass mode yet"); + } +} + + +#if ENABLE_LINUX_FW_LOADER +int mini_isp_pure_bypass(u16 mini_isp_mode) +{ + struct misp_global_variable *dev_global_variable; + errcode err = ERR_SUCCESS; + u32 idx = 0; + u32 CurBufPos = 0; + u32 reg_addr; + u32 reg_new_value; + u32 sleepTime; + u32 file_total_size; + u8 byass_setting_file_location[80]; + u8 linebuf[64]; + u32 copylens; + const struct firmware *fw = NULL; + const u8 *fw_data; + struct device *mini_isp_device; + char *file_name = NULL; + + dev_global_variable = get_mini_isp_global_variable(); + snprintf(byass_setting_file_location, 64, + "altek_bypass_setting_%d.log", mini_isp_mode); + misp_info("altek bypass mode %d", mini_isp_mode); + + /* load boot fw file */ + mini_isp_device = mini_isp_getdev(); + if (mini_isp_device != NULL && byass_setting_file_location != NULL) { + file_name = byass_setting_file_location; + misp_info("%s, fw name: %s", __func__, file_name); + + err = request_firmware(&fw, + file_name, mini_isp_device); + + if (err) { + misp_info("%s, L: %d, err: %d", + __func__, __LINE__, err); + goto EXIT; + } + } + + if (fw == NULL) { + misp_info("%s, fw:%s is NULL.", __func__, file_name); + return -EINVAL; + } + + file_total_size = fw->size; + fw_data = fw->data; + +#ifndef AL6100_SPI_NOR + mini_isp_chip_init(); +#endif + misp_info("%s file_total_size = %d", __func__, file_total_size); + CurBufPos = idx = 0; + while (CurBufPos < file_total_size) { + /* Get line form fw_data */ + for (idx = CurBufPos; idx < file_total_size; idx++) { + if (fw_data[idx] == '\n') { + copylens = (idx-CurBufPos > 64) ? + 64 : (idx-CurBufPos); + memcpy(linebuf, &(fw_data[CurBufPos]), + copylens); + break; + } else if (idx == file_total_size - 1) { + /* buf tail */ + copylens = (idx-CurBufPos > 64) ? + 64 : (idx-CurBufPos); + memcpy(linebuf, &(fw_data[CurBufPos]), + copylens); + break; + } + } + + /* analyze line buffer */ + if (sscanf(linebuf, "ml 0x%x 0x%x", + ®_addr, ®_new_value) == 2) { + + misp_info("ml 0x%x 0x%x", reg_addr, reg_new_value); + mini_isp_register_write(reg_addr, reg_new_value); + } else if (sscanf(linebuf, "sl %u", &sleepTime) == 1) { + misp_info("sl %d", sleepTime); + msleep(sleepTime); + } else { + misp_info("file format error! CurPos:%d", CurBufPos); + break; + } + + /* skip '\n' char */ + CurBufPos = idx + 1; + } + + /*Restore segment descriptor*/ + misp_info("miniisp bypass setting send finish"); + dev_global_variable->be_set_to_bypass = 1; +EXIT: + if (fw != NULL) + release_firmware(fw); + + return err; +} + +#else +int mini_isp_pure_bypass(u16 mini_isp_mode) +{ + struct misp_global_variable *dev_global_variable; + errcode err = ERR_SUCCESS; + mm_segment_t oldfs; + struct file *file_filp; + off_t currpos; + loff_t offset; + char *allocated_memmory; + u8 *keep_allocated_memmory; + char allocated_memmory_buf[64]; + u32 reg_addr; + u32 reg_new_value; + u32 file_total_size; + u8 byass_setting_file_location[80]; + u8 buf[8]; + int i; + + dev_global_variable = get_mini_isp_global_variable(); + snprintf(byass_setting_file_location, 64, + "%saltek_bypass_setting_%d.log", + MINIISP_BYPASS_SETTING_FILE_PATH, mini_isp_mode); + misp_info("altek bypass mode %d", mini_isp_mode); + misp_info("%s setting filepath : %s", __func__, + byass_setting_file_location); + + allocated_memmory = allocated_memmory_buf; + keep_allocated_memmory = allocated_memmory; + oldfs = get_fs(); + set_fs(KERNEL_DS); +#if ENABLE_FILP_OPEN_API + /* use file open */ +#else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + set_fs(oldfs); + return 0; +#endif + if (IS_ERR(file_filp)) { + err = PTR_ERR(file_filp); + misp_err("%s open file failed. err: %d", __func__, err); + set_fs(oldfs); + return err; + } + misp_info("%s open file success!", __func__); + +#ifndef AL6100_SPI_NOR + mini_isp_chip_init(); +#endif + /*get bin filie size*/ + currpos = vfs_llseek(file_filp, 0L, SEEK_END); + file_total_size = currpos; + currpos = vfs_llseek(file_filp, 0L, SEEK_SET); + + misp_info("%s file_total_size = %d", __func__, file_total_size); + offset = file_filp->f_pos; + while (file_total_size > 0) { + + vfs_read(file_filp, (char *)allocated_memmory_buf, + 1, &offset); + + file_filp->f_pos = offset; + file_total_size--; + if (allocated_memmory_buf[0] == '0') { + vfs_read(file_filp, (char *)allocated_memmory, + 1, &offset); + file_filp->f_pos = offset; + file_total_size--; + if (allocated_memmory_buf[0] == 'x') { + vfs_read(file_filp, (char *)allocated_memmory, + 8, &offset); + file_filp->f_pos = offset; + file_total_size = file_total_size - 8; + + for (i = 0; i < 4; i++) + err = hex2bin(buf+3-i, + allocated_memmory+2*i, 1); + + while (1) { + vfs_read(file_filp, + (char *)allocated_memmory, + 1, &offset); + file_filp->f_pos = offset; + file_total_size = file_total_size - 1; + + if (allocated_memmory[0] == '0') + break; + } + + if (file_total_size < 0) + break; + + vfs_read(file_filp, (char *)allocated_memmory, + 1, &offset); + file_filp->f_pos = offset; + file_total_size = file_total_size - 1; + if ((allocated_memmory[0] == 'x')) { + vfs_read(file_filp, + (char *)allocated_memmory, + 8, &offset); + file_filp->f_pos = offset; + file_total_size = file_total_size - 8; + + for (i = 0; i < 4; i++) + err = hex2bin(buf+4+3-i, + allocated_memmory+2*i, + 1); + + memcpy(®_addr, buf, 4); + memcpy(®_new_value, buf+4, 4); + + mini_isp_register_write( + reg_addr, + reg_new_value); + + } + } + } else if (allocated_memmory_buf[0] == 's') { + while (1) { + vfs_read(file_filp, (char *)allocated_memmory, + 1, &offset); + file_filp->f_pos = offset; + file_total_size = file_total_size - 1; + + if (allocated_memmory[0] == 13) { + udelay(350); + break; + } + } + } + } + /*Restore segment descriptor*/ + misp_info("miniisp bypass setting send finish"); + + dev_global_variable->be_set_to_bypass = 1; + set_fs(oldfs); + filp_close(file_filp, NULL); + + return err; +} +#endif + +void mini_isp_pure_bypass_debug(u16 mini_isp_mode) +{ + mini_isp_chip_init(); + misp_info("mini_isp_pure_bypass_debug(%d) set bypass mode", + mini_isp_mode); + switch (mini_isp_mode) { + case 1: + mini_isp_register_write(0xffe40000, 0x00000008); + mini_isp_register_write(0xffe40004, 0x00006621); + mini_isp_register_write(0xffe40008, 0x00006621); + mini_isp_register_write(0xffe4000c, 0x00006621); + mini_isp_register_write(0xffe40010, 0x00006621); + mini_isp_register_write(0xffe40050, 0x00000001); + mini_isp_register_write(0xffe81004, 0x00000200); + udelay(0x00000005); + mini_isp_register_write(0xffe81100, 0x00000000); + mini_isp_register_write(0xffe81104, 0x00000000); + mini_isp_register_write(0xffe81108, 0x000000dc); + mini_isp_register_write(0xffe8110c, 0x00000000); + mini_isp_register_write(0xffe81110, 0x00000001); + mini_isp_register_write(0xffe81114, 0x00000000); + mini_isp_register_write(0xffe81004, 0x00000000); + udelay(0x0000015e); + mini_isp_register_write(0xffe800c0, 0x0000000a); + mini_isp_register_write(0xffe800e0, 0x0000000a); + mini_isp_register_write(0xffe80100, 0x0000000a); + mini_isp_register_write(0xffe80120, 0x0000000a); + mini_isp_register_write(0xffe81004, 0x00000800); + udelay(0x00000005); + mini_isp_register_write(0xffe81120, 0x00000000); + mini_isp_register_write(0xffe81124, 0x00000000); + mini_isp_register_write(0xffe81128, 0x0000017a); + mini_isp_register_write(0xffe8112c, 0x00000000); + mini_isp_register_write(0xffe81130, 0x00000001); + mini_isp_register_write(0xffe81134, 0x00000001); + mini_isp_register_write(0xffe81004, 0x00000000); + udelay(0x0000015e); + mini_isp_register_write(0xffe81004, 0x00000400); + udelay(0x00000005); + mini_isp_register_write(0xffe81140, 0x00000000); + mini_isp_register_write(0xffe81144, 0x00000000); + mini_isp_register_write(0xffe81148, 0x0000017a); + mini_isp_register_write(0xffe8114c, 0x00000000); + mini_isp_register_write(0xffe81150, 0x00000001); + mini_isp_register_write(0xffe81154, 0x00000001); + mini_isp_register_write(0xffe81004, 0x00000000); + udelay(0x0000015e); + mini_isp_register_write(0xffe80b00, 0x00000819); + mini_isp_register_write(0xffe80880, 0x00000400); + mini_isp_register_write(0xffe80380, 0x00000004); + mini_isp_register_write(0xffe80400, 0x00000802); + mini_isp_register_write(0xffed1008, 0x0000aab0); + mini_isp_register_write(0xffed100c, 0x00000306); + mini_isp_register_write(0xffed1010, 0x00000147); + mini_isp_register_write(0xffed1014, 0x0000aa73); + mini_isp_register_write(0xffed1018, 0x00000eaa); + mini_isp_register_write(0xffed101c, 0x00008e1a); + mini_isp_register_write(0xffed1044, 0x000000b8); + mini_isp_register_write(0xffed1044, 0x00000098); + udelay(0x00000028); + mini_isp_register_write(0xffed1044, 0x00000088); + udelay(0x00000028); + mini_isp_register_write(0xffed1030, 0x00080000); + mini_isp_register_write(0xffed1034, 0x00080000); + mini_isp_register_write(0xffed1038, 0x00080000); + mini_isp_register_write(0xffed103c, 0x00080000); + mini_isp_register_write(0xffed1040, 0x00080000); + udelay(0x00000006); + mini_isp_register_write(0xffed1030, 0x00080002); + mini_isp_register_write(0xffed1034, 0x00080002); + mini_isp_register_write(0xffed1038, 0x00080002); + mini_isp_register_write(0xffed103c, 0x00080002); + mini_isp_register_write(0xffed1040, 0x00080002); + mini_isp_register_write(0xffed1000, 0x00000000); + mini_isp_register_write(0xfff97000, 0x00000001); + mini_isp_register_write(0xfff97004, 0x00003210); + mini_isp_register_write(0xfff97008, 0x00003210); + mini_isp_register_write(0xfff9700c, 0x145000b4); + mini_isp_register_write(0xfff97010, 0x00000000); + mini_isp_register_write(0xfff97014, 0x00000000); + mini_isp_register_write(0xfff97018, 0x00000000); + mini_isp_register_write(0xfff9701c, 0x00000000); + mini_isp_register_write(0xfff97020, 0x00000000); + mini_isp_register_write(0xfff97024, 0x00000010); + mini_isp_register_write(0xfff97028, 0x0000001e); + mini_isp_register_write(0xfff9702c, 0x0000000b); + mini_isp_register_write(0xfff97030, 0x0f0f0f0f); + mini_isp_register_write(0xfff97000, 0x00000000); + mini_isp_register_write(0xfff91000, 0x1000000b); + mini_isp_register_write(0xfff91024, 0x0000000f); + mini_isp_register_write(0xfff91028, 0x00001010); + mini_isp_register_write(0xfff9106c, 0x00000c0c); + mini_isp_register_write(0xfff91040, 0x00003c02); + udelay(0x00000028); + mini_isp_register_write(0xfff91004, 0x00000000); + mini_isp_register_write(0xfff91008, 0x00003033); + mini_isp_register_write(0xfff91010, 0x00003c02); + mini_isp_register_write(0xfff91014, 0x00003c02); + mini_isp_register_write(0xfff9103c, 0x00000000); + mini_isp_register_write(0xfff91098, 0x00444404); + mini_isp_register_write(0xfff9104c, 0x000d0011); + mini_isp_register_write(0xfff91000, 0x1000000b); + mini_isp_register_write(0xfff91024, 0x0000000f); + mini_isp_register_write(0xfff91028, 0x0000013f); + mini_isp_register_write(0xfff9106c, 0x00000e0e); + mini_isp_register_write(0xfff9104c, 0x000d0011); + mini_isp_register_write(0xfff91070, 0x01000005); + mini_isp_register_write(0xfff910a8, 0x00000000); + mini_isp_register_write(0xfff91094, 0x00001021); + mini_isp_register_write(0xfff91000, 0x1000000a); + break; + case 2: + mini_isp_register_write(0xffe40000, 0x00000008); + mini_isp_register_write(0xffe40004, 0x00006621); + mini_isp_register_write(0xffe40008, 0x00006621); + mini_isp_register_write(0xffe4000c, 0x00006621); + mini_isp_register_write(0xffe40010, 0x00006621); + mini_isp_register_write(0xffe40050, 0x00000001); + mini_isp_register_write(0xffe81004, 0x00000200); + udelay(0x00000005); + mini_isp_register_write(0xffe81100, 0x00000000); + mini_isp_register_write(0xffe81104, 0x00000000); + mini_isp_register_write(0xffe81108, 0x000000dc); + mini_isp_register_write(0xffe8110c, 0x00000000); + mini_isp_register_write(0xffe81110, 0x00000001); + mini_isp_register_write(0xffe81114, 0x00000000); + mini_isp_register_write(0xffe81004, 0x00000000); + udelay(0x0000015e); + mini_isp_register_write(0xffe800c0, 0x0000000a); + mini_isp_register_write(0xffe800e0, 0x0000000a); + mini_isp_register_write(0xffe80100, 0x0000000a); + mini_isp_register_write(0xffe80120, 0x0000000a); + mini_isp_register_write(0xffe81004, 0x00000800); + udelay(0x00000005); + mini_isp_register_write(0xffe81120, 0x00000000); + mini_isp_register_write(0xffe81124, 0x00000000); + mini_isp_register_write(0xffe81128, 0x0000017a); + mini_isp_register_write(0xffe8112c, 0x00000000); + mini_isp_register_write(0xffe81130, 0x00000001); + mini_isp_register_write(0xffe81134, 0x00000001); + mini_isp_register_write(0xffe81004, 0x00000000); + udelay(0x0000015e); + mini_isp_register_write(0xffe81004, 0x00000400); + udelay(0x00000005); + mini_isp_register_write(0xffe81140, 0x00000000); + mini_isp_register_write(0xffe81144, 0x00000000); + mini_isp_register_write(0xffe81148, 0x0000017a); + mini_isp_register_write(0xffe8114c, 0x00000000); + mini_isp_register_write(0xffe81150, 0x00000001); + mini_isp_register_write(0xffe81154, 0x00000001); + mini_isp_register_write(0xffe81004, 0x00000000); + udelay(0x0000015e); + mini_isp_register_write(0xffe80b00, 0x00000819); + mini_isp_register_write(0xffe80940, 0x00000800); + mini_isp_register_write(0xffe80440, 0x00000004); + mini_isp_register_write(0xffe80460, 0x00000802); + mini_isp_register_write(0xffed6008, 0x0000aab0); + mini_isp_register_write(0xffed600c, 0x00000306); + mini_isp_register_write(0xffed6010, 0x00000147); + mini_isp_register_write(0xffed6014, 0x0000aa73); + mini_isp_register_write(0xffed6018, 0x00000eaa); + mini_isp_register_write(0xffed601c, 0x00008e1a); + mini_isp_register_write(0xffed6044, 0x000000b8); + mini_isp_register_write(0xffed6044, 0x00000098); + udelay(0x00000028); + mini_isp_register_write(0xffed6044, 0x00000088); + udelay(0x00000028); + mini_isp_register_write(0xffed6030, 0x00080000); + mini_isp_register_write(0xffed6034, 0x00080000); + mini_isp_register_write(0xffed6038, 0x00080000); + mini_isp_register_write(0xffed603c, 0x00080000); + mini_isp_register_write(0xffed6040, 0x00080000); + udelay(0x00000006); + mini_isp_register_write(0xffed6030, 0x00080002); + mini_isp_register_write(0xffed6034, 0x00080002); + mini_isp_register_write(0xffed6038, 0x00080002); + mini_isp_register_write(0xffed603c, 0x00080002); + mini_isp_register_write(0xffed6040, 0x00080002); + mini_isp_register_write(0xffed6000, 0x00000000); + mini_isp_register_write(0xfff98000, 0x00000001); + mini_isp_register_write(0xfff98004, 0x00003210); + mini_isp_register_write(0xfff98008, 0x00003210); + mini_isp_register_write(0xfff9800c, 0x14500344); + mini_isp_register_write(0xfff98010, 0x00000000); + mini_isp_register_write(0xfff98014, 0x00000000); + mini_isp_register_write(0xfff98018, 0x00000000); + mini_isp_register_write(0xfff9801c, 0x00000000); + mini_isp_register_write(0xfff98020, 0x00000000); + mini_isp_register_write(0xfff98024, 0x000000ec); + mini_isp_register_write(0xfff98028, 0x0000001e); + mini_isp_register_write(0xfff9802c, 0x000000c3); + mini_isp_register_write(0xfff98030, 0x56565656); + mini_isp_register_write(0xfff98000, 0x00000000); + mini_isp_register_write(0xfff94000, 0x1000000b); + mini_isp_register_write(0xfff94024, 0x0000000f); + mini_isp_register_write(0xfff94028, 0x00001010); + mini_isp_register_write(0xfff9406c, 0x00000c0c); + mini_isp_register_write(0xfff94040, 0x00003c02); + udelay(0x00000028); + mini_isp_register_write(0xfff94004, 0x00000000); + mini_isp_register_write(0xfff94008, 0x00003033); + mini_isp_register_write(0xfff94010, 0x00003c02); + mini_isp_register_write(0xfff94014, 0x00003c02); + mini_isp_register_write(0xfff9403c, 0x00000000); + mini_isp_register_write(0xfff94098, 0x00444404); + mini_isp_register_write(0xfff9404c, 0x000d0011); + mini_isp_register_write(0xfff94000, 0x1000000b); + mini_isp_register_write(0xfff94024, 0x0000000f); + mini_isp_register_write(0xfff94028, 0x00003f01); + mini_isp_register_write(0xfff9406c, 0x00000e0e); + mini_isp_register_write(0xfff9404c, 0x000d0011); + mini_isp_register_write(0xfff94070, 0x01000005); + mini_isp_register_write(0xfff940a8, 0x00000000); + mini_isp_register_write(0xfff94094, 0x00001021); + mini_isp_register_write(0xfff94000, 0x1000000a); + break; + case 3: + mini_isp_register_write(0xffe40000, 0x00000008); + mini_isp_register_write(0xffe40004, 0x00006621); + mini_isp_register_write(0xffe40008, 0x00006621); + mini_isp_register_write(0xffe4000c, 0x00006621); + mini_isp_register_write(0xffe40010, 0x00006621); + mini_isp_register_write(0xffe40050, 0x00000001); + mini_isp_register_write(0xffe81004, 0x00000200); + udelay(0x00000005); + mini_isp_register_write(0xffe81100, 0x00000000); + mini_isp_register_write(0xffe81104, 0x00000000); + mini_isp_register_write(0xffe81108, 0x000000dc); + mini_isp_register_write(0xffe8110c, 0x00000000); + mini_isp_register_write(0xffe81110, 0x00000001); + mini_isp_register_write(0xffe81114, 0x00000000); + mini_isp_register_write(0xffe81004, 0x00000000); + udelay(0x0000015e); + mini_isp_register_write(0xffe800c0, 0x0000000a); + mini_isp_register_write(0xffe800e0, 0x0000000a); + mini_isp_register_write(0xffe80100, 0x0000000a); + mini_isp_register_write(0xffe80120, 0x0000000a); + mini_isp_register_write(0xffe81004, 0x00000800); + udelay(0x00000005); + mini_isp_register_write(0xffe81120, 0x00000000); + mini_isp_register_write(0xffe81124, 0x00000000); + mini_isp_register_write(0xffe81128, 0x0000017a); + mini_isp_register_write(0xffe8112c, 0x00000000); + mini_isp_register_write(0xffe81130, 0x00000001); + mini_isp_register_write(0xffe81134, 0x00000001); + mini_isp_register_write(0xffe81004, 0x00000000); + udelay(0x0000015e); + mini_isp_register_write(0xffe81004, 0x00000400); + udelay(0x00000005); + mini_isp_register_write(0xffe81140, 0x00000000); + mini_isp_register_write(0xffe81144, 0x00000000); + mini_isp_register_write(0xffe81148, 0x0000017a); + mini_isp_register_write(0xffe8114c, 0x00000000); + mini_isp_register_write(0xffe81150, 0x00000001); + mini_isp_register_write(0xffe81154, 0x00000001); + mini_isp_register_write(0xffe81004, 0x00000000); + udelay(0x0000015e); + mini_isp_register_write(0xffe80b00, 0x00000819); + mini_isp_register_write(0xffe80880, 0x00000400); + mini_isp_register_write(0xffe80380, 0x00000004); + mini_isp_register_write(0xffe80400, 0x00000802); + mini_isp_register_write(0xffe80940, 0x00000800); + mini_isp_register_write(0xffe80440, 0x00000004); + mini_isp_register_write(0xffe80460, 0x00000802); + mini_isp_register_write(0xffed1008, 0x0000aab0); + mini_isp_register_write(0xffed100c, 0x00000306); + mini_isp_register_write(0xffed1010, 0x00000147); + mini_isp_register_write(0xffed1014, 0x0000aa73); + mini_isp_register_write(0xffed1018, 0x00000eaa); + mini_isp_register_write(0xffed101c, 0x00008e1a); + mini_isp_register_write(0xffed1044, 0x000000b8); + mini_isp_register_write(0xffed1044, 0x00000098); + udelay(0x00000028); + mini_isp_register_write(0xffed1044, 0x00000088); + udelay(0x00000028); + mini_isp_register_write(0xffed1030, 0x00080000); + mini_isp_register_write(0xffed1034, 0x00080000); + mini_isp_register_write(0xffed1038, 0x00080000); + mini_isp_register_write(0xffed103c, 0x00080000); + mini_isp_register_write(0xffed1040, 0x00080000); + udelay(0x00000006); + mini_isp_register_write(0xffed1030, 0x00080002); + mini_isp_register_write(0xffed1034, 0x00080002); + mini_isp_register_write(0xffed1038, 0x00080002); + mini_isp_register_write(0xffed103c, 0x00080002); + mini_isp_register_write(0xffed1040, 0x00080002); + mini_isp_register_write(0xffed1000, 0x00000000); + mini_isp_register_write(0xfff97000, 0x00000001); + mini_isp_register_write(0xfff97004, 0x00003210); + mini_isp_register_write(0xfff97008, 0x00003210); + mini_isp_register_write(0xfff9700c, 0x145000b4); + mini_isp_register_write(0xfff97010, 0x00000000); + mini_isp_register_write(0xfff97014, 0x00000000); + mini_isp_register_write(0xfff97018, 0x00000000); + mini_isp_register_write(0xfff9701c, 0x00000000); + mini_isp_register_write(0xfff97020, 0x00000000); + mini_isp_register_write(0xfff97024, 0x00000010); + mini_isp_register_write(0xfff97028, 0x0000001e); + mini_isp_register_write(0xfff9702c, 0x0000000b); + mini_isp_register_write(0xfff97030, 0x0f0f0f0f); + mini_isp_register_write(0xfff97000, 0x00000000); + mini_isp_register_write(0xfff91000, 0x1000000b); + mini_isp_register_write(0xfff91024, 0x0000000f); + mini_isp_register_write(0xfff91028, 0x00001010); + mini_isp_register_write(0xfff9106c, 0x00000c0c); + mini_isp_register_write(0xfff91040, 0x00003c02); + udelay(0x00000028); + mini_isp_register_write(0xfff91004, 0x00000000); + mini_isp_register_write(0xfff91008, 0x00003033); + mini_isp_register_write(0xfff91010, 0x00003c02); + mini_isp_register_write(0xfff91014, 0x00003c02); + mini_isp_register_write(0xfff9103c, 0x00000000); + mini_isp_register_write(0xfff91098, 0x00444404); + mini_isp_register_write(0xfff9104c, 0x000d0011); + mini_isp_register_write(0xfff91000, 0x1000000b); + mini_isp_register_write(0xfff91024, 0x0000000f); + mini_isp_register_write(0xfff91028, 0x0000013f); + mini_isp_register_write(0xfff9106c, 0x00000e0e); + mini_isp_register_write(0xfff9104c, 0x000d0011); + mini_isp_register_write(0xfff91070, 0x01000005); + mini_isp_register_write(0xfff910a8, 0x00000000); + mini_isp_register_write(0xfff91094, 0x00001021); + mini_isp_register_write(0xfff91000, 0x1000000a); + mini_isp_register_write(0xffed6008, 0x0000aab0); + mini_isp_register_write(0xffed600c, 0x00000306); + mini_isp_register_write(0xffed6010, 0x00000147); + mini_isp_register_write(0xffed6014, 0x0000aa73); + mini_isp_register_write(0xffed6018, 0x00000eaa); + mini_isp_register_write(0xffed601c, 0x00008e1a); + mini_isp_register_write(0xffed6044, 0x000000b8); + mini_isp_register_write(0xffed6044, 0x00000098); + udelay(0x00000028); + mini_isp_register_write(0xffed6044, 0x00000088); + udelay(0x00000028); + mini_isp_register_write(0xffed6030, 0x00080000); + mini_isp_register_write(0xffed6034, 0x00080000); + mini_isp_register_write(0xffed6038, 0x00080000); + mini_isp_register_write(0xffed603c, 0x00080000); + mini_isp_register_write(0xffed6040, 0x00080000); + udelay(0x00000006); + mini_isp_register_write(0xffed6030, 0x00080002); + mini_isp_register_write(0xffed6034, 0x00080002); + mini_isp_register_write(0xffed6038, 0x00080002); + mini_isp_register_write(0xffed603c, 0x00080002); + mini_isp_register_write(0xffed6040, 0x00080002); + mini_isp_register_write(0xffed6000, 0x00000000); + mini_isp_register_write(0xfff98000, 0x00000001); + mini_isp_register_write(0xfff98004, 0x00003210); + mini_isp_register_write(0xfff98008, 0x00003210); + mini_isp_register_write(0xfff9800c, 0x14500344); + mini_isp_register_write(0xfff98010, 0x00000000); + mini_isp_register_write(0xfff98014, 0x00000000); + mini_isp_register_write(0xfff98018, 0x00000000); + mini_isp_register_write(0xfff9801c, 0x00000000); + mini_isp_register_write(0xfff98020, 0x00000000); + mini_isp_register_write(0xfff98024, 0x000000ec); + mini_isp_register_write(0xfff98028, 0x0000001e); + mini_isp_register_write(0xfff9802c, 0x000000c3); + mini_isp_register_write(0xfff98030, 0x56565656); + mini_isp_register_write(0xfff98000, 0x00000000); + mini_isp_register_write(0xfff94000, 0x1000000b); + mini_isp_register_write(0xfff94024, 0x0000000f); + mini_isp_register_write(0xfff94028, 0x00001010); + mini_isp_register_write(0xfff9406c, 0x00000c0c); + mini_isp_register_write(0xfff94040, 0x00003c02); + udelay(0x00000028); + mini_isp_register_write(0xfff94004, 0x00000000); + mini_isp_register_write(0xfff94008, 0x00003033); + mini_isp_register_write(0xfff94010, 0x00003c02); + mini_isp_register_write(0xfff94014, 0x00003c02); + mini_isp_register_write(0xfff9403c, 0x00000000); + mini_isp_register_write(0xfff94098, 0x00444404); + mini_isp_register_write(0xfff9404c, 0x000d0011); + mini_isp_register_write(0xfff94000, 0x1000000b); + mini_isp_register_write(0xfff94024, 0x0000000f); + mini_isp_register_write(0xfff94028, 0x00003f01); + mini_isp_register_write(0xfff9406c, 0x00000e0e); + mini_isp_register_write(0xfff9404c, 0x000d0011); + mini_isp_register_write(0xfff94070, 0x01000005); + mini_isp_register_write(0xfff940a8, 0x00000000); + mini_isp_register_write(0xfff94094, 0x00001021); + mini_isp_register_write(0xfff94000, 0x1000000a); + break; + default: + break; + } +} +EXPORT_SYMBOL(mini_isp_pure_bypass_debug); + + +u32 mini_isp_register_read_then_write_file( + u32 start_reg_addr, u32 end_reg_addr, + char *dest_path, char *module_name) +{ + u32 retval = ERR_SUCCESS; + u32 count; + u8 *dump_memory = NULL; + u8 *keep_dump_memory = NULL; + u32 ouput_size; + u8 filename[128]; + struct file *f; + mm_segment_t fs; + + /* how many registers(4 bytes) do you want to read? */ + count = ((end_reg_addr - start_reg_addr) / 4) + 1; + /* read 4 bytes register value */ + ouput_size = (count + 2) * 4; + + dump_memory = kzalloc(ouput_size, GFP_KERNEL); + if (!dump_memory) { + retval = -ENOMEM; + misp_err("%s Allocate memory failed.", __func__); + goto allocate_memory_fail; + } + keep_dump_memory = dump_memory; + + + memcpy(dump_memory, &start_reg_addr, 4); + dump_memory = dump_memory + 4; + memcpy(dump_memory, &count, 4); + dump_memory = dump_memory + 4; + + while (start_reg_addr <= end_reg_addr) { + + mini_isp_register_read(start_reg_addr, (u32 *)dump_memory); + + start_reg_addr = start_reg_addr + 4; + dump_memory = dump_memory + 4; + } + + + + snprintf(filename, 128, "%s/%s_%x.regx", + dest_path, module_name, start_reg_addr); +#if ENABLE_FILP_OPEN_API + /* use file open */ +#else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + goto file_open_fail; +#endif + /*Get current segment descriptor*/ + fs = get_fs(); + /*Set segment descriptor associated*/ + set_fs(get_ds()); + + if (IS_ERR(f)) { + retval = PTR_ERR(f); + set_fs(fs); + misp_err("%s open file failed. err: %d", __func__, retval); + goto file_open_fail; + } + + /*write the file*/ + vfs_write(f, (char *)keep_dump_memory, ouput_size, &f->f_pos); + + /*Restore segment descriptor*/ + set_fs(fs); + filp_close(f, NULL); + +file_open_fail: +allocate_memory_fail: + kfree(keep_dump_memory); + + return retval; +} + +u32 mini_isp_register_read(u32 reg_addr, u32 *reg_value) +{ + int status = ERR_SUCCESS; + u8 *send_buffer; + u8 *recv_buffer; + u8 ctrlbyte = 0; + u32 address = reg_addr; + struct misp_data *devdata; + struct misp_global_variable *dev_global_variable; + + u8 send_buffer_value[64] = {0}; + u8 recv_buffer_value[64] = {0}; + u32 rx_dummy_len; + + dev_global_variable = get_mini_isp_global_variable(); + + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + send_buffer = send_buffer_value; + recv_buffer = recv_buffer_value; + if (SPI_SHORT_LEN_MODE && SPI_SHORT_LEN_MODE_READ_ENABLE) { + /* Setp1, Send address: { ctrlbyte[1byte] + addr[4byte] } */ + ctrlbyte = CTRL_BYTE_REGRD_W; + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &address, 4); + + /* read 4 bytes register value */ + status = devdata->intf_fn->read(devdata, + send_buffer_value, + EMODE_TXCMD_LEN, + recv_buffer_value, + 0); + + if (status) { + misp_err("%s - sync error: status = %d", + __func__, status); + goto mini_isp_register_read_end; + } + + + udelay(50); + + /* Setp2, wait a moment and + * get data{ dummy[1byte] + data[4byte] } + */ + ctrlbyte = CTRL_BYTE_GETDATA_W; + memcpy(send_buffer, &ctrlbyte, 1); + + status = devdata->intf_fn->read(devdata, + send_buffer_value, + 1, + recv_buffer_value, + 5); + + if (status) { + misp_err("%s - sync error: status = %d", + __func__, status); + goto mini_isp_register_read_end; + } + + recv_buffer = (u8 *)&recv_buffer_value[1]; + + } else { + ctrlbyte = CTRL_BYTE_REGRD; + rx_dummy_len = mini_isp_get_rx_dummy_byte(ctrlbyte); + #if EN_SPIE_REG_DUMMY_BYTE + mini_isp_set_spie_dummy_byte(rx_dummy_len-1); /* 0 base */ + #endif + + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &address, 4); + + /* read 4 bytes register value */ + status = devdata->intf_fn->read(devdata, + send_buffer_value, + EMODE_TXCMD_LEN, + recv_buffer_value, + rx_dummy_len + 4); + + if (status) { + misp_err("%s - sync error: status = %d", + __func__, status); + goto mini_isp_register_read_end; + } + + if (dev_global_variable->intf_status & INTF_SPI_READY) { + /* check if send len + recv len > 32. if yes then + * rx_dummy_len need + EMODE_TXCMD_LEN + */ + if (EMODE_TXCMD_LEN + rx_dummy_len + 4 > 32) + status = mini_isp_check_rx_dummy(&recv_buffer, + rx_dummy_len+EMODE_TXCMD_LEN); + else + status = mini_isp_check_rx_dummy(&recv_buffer, + rx_dummy_len); + + if (status) { + misp_err("[miniisp]Can't get reg"); + goto mini_isp_register_read_end; + } + } + + } + memcpy(reg_value, recv_buffer, 4); + +mini_isp_register_read_end: + + return status; +} + +void mini_isp_memory_write(u32 memory_addr, u8 *write_buffer, u32 write_len) +{ + u8 *send_buffer; + u8 ctrlbyte = CTRL_BYTE_MEMWR; + u32 address = memory_addr; + u32 start_mem_addr = memory_addr; + u32 end_mem_addr = memory_addr + write_len; + struct misp_data *devdata; + u8 send_buffer_value[EMODE_TXCMD_LEN + write_len]; + struct misp_global_variable *dev_global_variable; + u32 wt_len = write_len; + u8 *wt_buffer; + + dev_global_variable = get_mini_isp_global_variable(); + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + send_buffer = send_buffer_value; + + /* dev_global_variable->before_booting = 1; */ + + + if (SPI_SHORT_LEN_MODE && SPI_SHORT_LEN_MODE_WRITE_ENABLE) { + wt_buffer = write_buffer; + + while (start_mem_addr < end_mem_addr) { + + wt_len = end_mem_addr - start_mem_addr; + + if (wt_len >= 4) { + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &start_mem_addr, 4); + memcpy(send_buffer + 5, wt_buffer, 4); + devdata->intf_fn->write( + devdata, + send_buffer, + NULL, + EMODE_TXCMD_LEN + 4); + } else { + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &start_mem_addr, 4); + memcpy(send_buffer + 5, wt_buffer, wt_len); + devdata->intf_fn->write( + devdata, + send_buffer, + NULL, + EMODE_TXCMD_LEN + wt_len); + } + + wt_buffer = wt_buffer + 4; + start_mem_addr = start_mem_addr + 4; + } + } else { + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &address, 4); + memcpy(send_buffer + 5, write_buffer, write_len); + devdata->intf_fn->write( + devdata, + send_buffer, + NULL, + EMODE_TXCMD_LEN + write_len); + } + /* dev_global_variable->before_booting = 0; */ +} + +u32 mini_isp_memory_read_then_write_file(u32 start_addr, u32 len, + char *dest_path, char *file_name) +{ + u32 retval = ERR_SUCCESS; + u8 *dump_memory = NULL; + u8 filename[128]; + struct file *f; + mm_segment_t fs; + + /* misp_err("%s - entering", __func__); */ + + dump_memory = kzalloc(len, GFP_KERNEL); + if (!dump_memory) { + retval = -ENOMEM; + misp_err("%s Allocate memory failed.", __func__); + goto allocate_memory_fail; + } + + mini_isp_memory_read(start_addr, dump_memory, len); + + + snprintf(filename, 128, "%s/%s.raw", dest_path, file_name); +#if ENABLE_FILP_OPEN_API + /* use file open */ +#else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + goto file_open_fail; +#endif + /*Get current segment descriptor*/ + fs = get_fs(); + /*Set segment descriptor associated*/ + set_fs(get_ds()); + + if (IS_ERR(f)) { + retval = PTR_ERR(f); + set_fs(fs); + misp_err("%s open file failed. err: %d", __func__, retval); + goto file_open_fail; + } + /*write the file*/ + vfs_write(f, (char *)dump_memory, len, &f->f_pos); + + /*Restore segment descriptor*/ + set_fs(fs); + filp_close(f, NULL); +file_open_fail: +allocate_memory_fail: + kfree(dump_memory); + + return retval; +} +EXPORT_SYMBOL(mini_isp_memory_read_then_write_file); +/** + *\brief Get woi image and save as file. + *\param start_addr [In], start address + *\param lineoffset [In], line offset (byte) + *\param width [In], image width (byte), it can't exceed 60000bytes. + *\param height [In], image height(byte) + *\param dest_path [In], save path + *\param file_name [In], save file name + *\return + */ +u32 mini_isp_woi_memory_read_then_write_file(u32 start_addr, + u32 lineoffset, u32 width, u32 height, + char *dest_path, char *file_name) +{ + u32 retval = ERR_SUCCESS; + u8 *dump_memory = NULL; + u8 *keep_dump_memory = NULL; + u32 dump_addr = start_addr; + u32 ouput_size; + u32 one_size; + u32 loopidx = 0; + s32 remain_size; + u8 filename[128]; + struct file *f; + mm_segment_t fs; + + misp_info("%s, lineoffset: %d, width: %d, height: %d, filename: %s", + __func__, lineoffset, width, height, file_name); + + ouput_size = width * height; + dump_memory = kzalloc(ouput_size, GFP_KERNEL); + if (!dump_memory) { + misp_err("%s Allocate memory failed.", __func__); + goto allocate_dump_memory_fail; + } + keep_dump_memory = dump_memory; + + + /* memory read */ + for (loopidx = 0, remain_size = ouput_size; remain_size > 0; + remain_size -= width, loopidx++) { + /* update read memory size and address */ + one_size = (remain_size > width) ? width : remain_size; + dump_addr = start_addr + loopidx*lineoffset; + + retval = mini_isp_memory_read(dump_addr, dump_memory, one_size); + if (retval) { + misp_err("%s get failed.", __func__); + goto mini_isp_memory_read_get_fail; + } + + misp_info("%s dump_addr = 0x%x one_size = %d", + __func__, dump_addr, one_size); + + dump_memory += one_size; + dump_addr += one_size; + } + + misp_info("%s read_finish", __func__); + + snprintf(filename, 128, "%s/%s.raw", dest_path, file_name); +#if ENABLE_FILP_OPEN_API + /* use file open */ +#else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + goto file_open_fail; +#endif + /*Get current segment descriptor*/ + fs = get_fs(); + /*Set segment descriptor associated*/ + set_fs(get_ds()); + + if (IS_ERR(f)) { + retval = PTR_ERR(f); + set_fs(fs); + misp_err("%s open file failed. err: %d", __func__, retval); + goto file_open_fail; + } + /*write the file*/ + vfs_write(f, (char *)keep_dump_memory, ouput_size, &f->f_pos); + + /*Restore segment descriptor*/ + set_fs(fs); + filp_close(f, NULL); +file_open_fail: +mini_isp_memory_read_get_fail: +allocate_dump_memory_fail: + kfree(keep_dump_memory); + + return retval; +} +EXPORT_SYMBOL(mini_isp_woi_memory_read_then_write_file); +u32 mini_isp_memory_read_shortlen(u32 start_addr, u32 *read_buffer) +{ + int status = ERR_SUCCESS; + u8 *send_buffer; + u8 *recv_buffer; + u8 ctrlbyte = 0; + u32 address = start_addr; + struct misp_data *devdata; + u8 send_buffer_value[64] = {0}; + u8 recv_buffer_value[64] = {0}; + + + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + send_buffer = send_buffer_value; + recv_buffer = recv_buffer_value; + + + /* misp_err("%s - entering", __func__); */ + + /* Setp1, Send memory address: { ctrlbyte[1byte] + addr[4byte] } */ + ctrlbyte = CTRL_BYTE_MEMRD_W; + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &address, 4); + + /* read 4 bytes memory value */ + status = devdata->intf_fn->read( + devdata, + send_buffer_value, + EMODE_TXCMD_LEN, + recv_buffer_value, + 0); + + if (status) { + misp_err("%s - sync error: status = %d", __func__, status); + goto mini_isp_memory_read_shortlen_end; + } + + udelay(500); + + /* Setp2, wait a moment and get data{ dummy[1byte] + data[4byte] } */ + ctrlbyte = CTRL_BYTE_GETDATA_W; + memcpy(send_buffer, &ctrlbyte, 1); + + status = devdata->intf_fn->read(devdata, + send_buffer_value, + 1, + recv_buffer_value, + 5); + + if (status) { + misp_err("%s - sync error: status = %d", __func__, status); + goto mini_isp_memory_read_shortlen_end; + } + + recv_buffer = (u8 *)&recv_buffer_value[1]; + + + + memcpy(read_buffer, recv_buffer, 4); + +mini_isp_memory_read_shortlen_end: + + return status; + +} + + +u32 mini_isp_memory_read(u32 start_addr, u8 *read_buffer, u32 len) +{ + struct misp_data *devdata; + struct misp_global_variable *dev_global_variable; + u32 retval = ERR_SUCCESS; + u8 *io_buffer = NULL; + u8 *send_buffer; + u8 *recv_buffer; + u8 *dump_memory = NULL; + u8 *keep_dump_memory = NULL; + u32 dump_addr = start_addr; + u32 start_mem_addr = start_addr; + u32 ouput_size; + u32 io_size, remain_size, one_size, recv_buffer_size, send_buffer_size; + u32 rx_dummy_len; + u8 ctrlbyte = CTRL_BYTE_MEMRD; + u32 len_align; + + misp_err("%s - entering", __func__); + + /* 4byte alignment for 'mini_isp_memory_read_shortlen()' */ + len_align = ALIGN_CEIL(len, 4); + + dump_memory = kzalloc(len_align, GFP_KERNEL); + if (!dump_memory) { + retval = -ENOMEM; + misp_err("%s Allocate memory failed.", __func__); + goto allocate_memory_fail; + } + keep_dump_memory = dump_memory; + ouput_size = len; + + + if (SPI_SHORT_LEN_MODE && SPI_SHORT_LEN_MODE_READ_ENABLE) { + while (start_mem_addr < start_addr + len) { + mini_isp_memory_read_shortlen(start_mem_addr, + (u32 *)dump_memory); + + start_mem_addr = start_mem_addr + 4; + dump_memory = dump_memory + 4; + } + } else { + dev_global_variable = get_mini_isp_global_variable(); + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + + rx_dummy_len = mini_isp_get_rx_dummy_byte(ctrlbyte); + + #if EN_SPIE_REG_DUMMY_BYTE + mini_isp_set_spie_dummy_byte(rx_dummy_len-1); /* 0 base */ + #endif + + send_buffer_size = EMODE_TXCMD_LEN; + recv_buffer_size = EMODE_TXCMD_LEN + rx_dummy_len + 60000; + + /* read 60000 bytes at a time;*/ + io_size = send_buffer_size + recv_buffer_size; + io_buffer = kzalloc(io_size, GFP_KERNEL); + if (!io_buffer) { + misp_err("%s Allocate memory failed.", __func__); + goto allocate_memory_fail; + } + + /* memory read */ + for (remain_size = ouput_size; remain_size > 0; + remain_size -= one_size) { + + one_size = (remain_size > 60000) ? + 60000 : remain_size; + + memset(io_buffer, 0, io_size); + send_buffer = io_buffer; + recv_buffer = io_buffer + EMODE_TXCMD_LEN; + + memcpy(send_buffer, &ctrlbyte, 1); + memcpy(send_buffer + 1, &dump_addr, 4); + + retval = devdata->intf_fn->read((void *)devdata, + send_buffer, + EMODE_TXCMD_LEN, + recv_buffer, + one_size + rx_dummy_len); + if (retval) { + misp_err("%s get failed.", __func__); + goto mini_isp_memory_read_get_fail; + } + + if (dev_global_variable->intf_status & INTF_SPI_READY) { + /* check if send len + recv len > 32. if yes then + * rx_dummy_len need + EMODE_TXCMD_LEN + */ + if (EMODE_TXCMD_LEN + rx_dummy_len + one_size > 32) + retval = mini_isp_check_rx_dummy( + &recv_buffer, + rx_dummy_len+EMODE_TXCMD_LEN); + else + retval = mini_isp_check_rx_dummy( + &recv_buffer, + rx_dummy_len); + + if (retval) { + misp_err("%s get failed.", __func__); + goto mini_isp_memory_read_get_fail; + } + } + + memcpy(dump_memory, recv_buffer, one_size); + misp_info("%s dump_addr = 0x%x one_size = %d", + __func__, dump_addr, one_size); + dump_memory += one_size; + dump_addr += one_size; + } + + } + + misp_info("%s read_finish", __func__); + + memcpy(read_buffer, keep_dump_memory, ouput_size); + +mini_isp_memory_read_get_fail: +allocate_memory_fail: + kfree(keep_dump_memory); + kfree(io_buffer); + + return retval; +} +EXPORT_SYMBOL(mini_isp_memory_read); + + +int mini_isp_get_bulk(struct misp_data *devdata, u8 *response_buf, + u32 total_size, u32 block_size) +{ + int status = ERR_SUCCESS, count = 0; + int remain_size, one_size; + /* 1byte ctrlbyte, 2bytes recv */ + u8 io_buffer[3] = {0}; + u8 *send_buffer; + u8 *recv_buffer; + u8 ctrlbyte = USPICTRL_MS_CB_DIS; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + send_buffer = io_buffer; + send_buffer[0] = ctrlbyte; + recv_buffer = io_buffer + 1; + + misp_info("%s started.", __func__); + + status = devdata->intf_fn->read( + (void *)devdata, + send_buffer, + 1, + recv_buffer, + 2); + if (status) { + misp_err( + "mini_isp_send_bulk send ctrl byte failed. status:%d", + status); + status = -EINVAL; + goto G_EXIT; + } + + for (remain_size = total_size; + remain_size > 0; + remain_size -= one_size) { + + one_size = (remain_size > block_size) ? + block_size : remain_size; + /*get the data*/ + misp_info("%s dump start", __func__); + status = devdata->intf_fn->read( + (void *)devdata, + response_buf, + 0, + response_buf, + one_size); + + if (status != 0) { + misp_err("%s failed!! block:%d status: %d", __func__, + count, status); + break; + } + + response_buf += one_size; + count++; + } + +G_EXIT: + + if (status != ERR_SUCCESS) + misp_info("%s - error: %d", __func__, status); + else + misp_info("%s - success.", __func__); + + return status; +} +EXPORT_SYMBOL_GPL(mini_isp_get_bulk); + + + +int mini_isp_get_altek_status(void *devdata, u32 *altek_status) +{ + int status = ERR_SUCCESS; + + misp_info("%s - entering", __func__); + + mini_isp_register_read(INTERRUPT_STATUS_REGISTER_ADDR, altek_status); + + misp_info("%s - altek_status = %#x", __func__, *altek_status); + + return status; +} + +/*interrupt handler function */ +extern irqreturn_t mini_isp_irq(int irq, void *handle) +{ + struct misp_data *devdata = NULL; + struct misp_global_variable *dev_global_variable; + int errcode = ERR_SUCCESS; + int original_altek_spi_mode; + u32 altek_event_state = 0; + + misp_info("%s - enter", __func__); + + irqflag = true; + + dev_global_variable = get_mini_isp_global_variable(); + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + if (!devdata || !dev_global_variable) + return -IRQ_NONE; + + original_altek_spi_mode = dev_global_variable->altek_spi_mode; + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + mini_isp_a_to_e(); + } + errcode = mini_isp_get_altek_status(devdata, + &altek_event_state); + misp_info("%s - read spi register: %#x", + __func__, altek_event_state); + + event = MINI_ISP_RCV_WAITING; + + if (errcode == ERR_SUCCESS) { + /*error event*/ + if (altek_event_state & SYSTEM_ERROR_LEVEL1) { + event = event | MINI_ISP_RCV_ERROR; + if (dev_global_variable->intf_status & INTF_SPI_READY) + mini_isp_e_to_a(); + /* need to port out of this ISR */ + mini_isp_drv_get_err_code_cmd_in_irq(); + if (dev_global_variable->intf_status & INTF_SPI_READY) + mini_isp_a_to_e(); + } + if (altek_event_state & SYSTEM_ERROR_LEVEL2) { + event = event | MINI_ISP_RCV_ERROR2; + mini_isp_utility_read_reg_e_mode(); + } + /*set sensor mode event*/ + if (altek_event_state & SET_SENSOR_MODE_READY) + event = event | MINI_ISP_RCV_SETSENSORMODE; + /*change cp mode event*/ + if (altek_event_state & CP_STATUS_CHANGE_DONE) + event = event | MINI_ISP_RCV_CPCHANGE; + /*ready event*/ + /*CMD*/ + if (altek_event_state & COMMAND_COMPLETE) + event = event | MINI_ISP_RCV_CMD_READY; + /*Bulk Data*/ + if (altek_event_state & BULK_DATA_COMPLETE) + event = event | MINI_ISP_RCV_BULKDATA; + /* streamoff event*/ + if (altek_event_state & STRMOFF_READY) + event = event | MINI_ISP_RCV_STRMOFF; + + mini_isp_register_write( + INTERRUPT_STATUS_REGISTER_ADDR, + altek_event_state); + } else { + misp_err("%s - err: %d", __func__, errcode); + } + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + original_altek_spi_mode != + dev_global_variable->altek_spi_mode) + mini_isp_e_to_a(); + + wake_up_interruptible(&WAITQ); + + misp_info("%s - leave", __func__); + + return IRQ_HANDLED; +} + +int mini_isp_wait_for_event(u32 e) +{ + int state = 0; + +#if (ISR_MECHANISM == INTERRUPT_METHOD) + misp_info("%s - entering. event: %#x", __func__, e); + do { + state = wait_event_interruptible(WAITQ, event & e); + } while (state == (-ERESTARTSYS)); + + current_event = event; + + event = (~e) & event;/*MINI_ISP_RCV_WAITING;*/ + + if (state) + misp_err("%s - irq error. err: %d", __func__, state); + +#else /* ISR_MECHANISM == POLLING_METHOD */ + + struct misp_data *devdata = NULL; + struct misp_global_variable *dev_global_variable; + u32 altek_event_state = 0; + int original_altek_spi_mode; + + devdata = get_mini_isp_intf(MINIISP_I2C_SLAVE); + dev_global_variable = get_mini_isp_global_variable(); + original_altek_spi_mode = dev_global_variable->altek_spi_mode; + + msleep(100); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + mini_isp_a_to_e(); + } + + misp_info("%s - entering. event: %#x", __func__, e); + do { + misp_info("%s - polling...", __func__); + + mini_isp_get_altek_status(devdata, &altek_event_state); + + if (altek_event_state & SYSTEM_ERROR_LEVEL1) { + if (dev_global_variable->intf_status & INTF_SPI_READY) + mini_isp_e_to_a(); + /* need to port out of this ISR */ + mini_isp_drv_get_err_code_cmd_in_irq(); + if (dev_global_variable->intf_status & INTF_SPI_READY) + mini_isp_a_to_e(); + } else if (altek_event_state & SYSTEM_ERROR_LEVEL2) { + mini_isp_utility_read_reg_e_mode(); + } else if (altek_event_state & e) { + /* find target, clear status */ + mini_isp_register_write(0xffef00b4, e); + break; + } + msleep(50); + } while ((altek_event_state & e) == 0); + + current_event = e; + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (original_altek_spi_mode != + dev_global_variable->altek_spi_mode)) + mini_isp_e_to_a(); +#endif + misp_info("%s - leaving. event: %#x", __func__, e); + + return state; +} + +u32 mini_isp_get_currentevent(void) +{ + return current_event; +} + +u32 mini_isp_check_rx_dummy(u8 **recv_buffer, u32 rx_dummy_len) +{ + u32 ret = 0; +#if (EN_SPIE_REG_DUMMY_BYTE == 0) + u32 get_count = 0; +#endif + +#if EN_SPIE_DEBUG + /*u8 idx = 0;*/ + u8 col_idx = 0; + u8 row_idx = 0; + u8 *ptest = NULL; + + misp_info("%s, dummy byte: %d", __func__, rx_dummy_len); + ptest = *recv_buffer; + + misp_info(" 0 1 2 3 4 5 6 7 8 9 A B C D E F"); + for (col_idx = 0; col_idx < ((rx_dummy_len+1)/16); col_idx++) { + misp_info(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", + (u32)*(ptest), (u32)*(ptest+1), (u32)*(ptest+2), (u32)*(ptest+3), + (u32)*(ptest+4), (u32)*(ptest+5), (u32)*(ptest+6), (u32)*(ptest+7), + (u32)*(ptest+8), (u32)*(ptest+9), (u32)*(ptest+10), (u32)*(ptest+11), + (u32)*(ptest+12), (u32)*(ptest+13), (u32)*(ptest+14), (u32)*(ptest+15)); + + ptest = ptest + 16; + } + + /* remain less 16 byte data */ + col_idx -= 1; + for (row_idx = 0; row_idx < (rx_dummy_len+1)-(col_idx*16); row_idx++) { + misp_info(" %02X", (u32)*(ptest)); + ptest++; + } + #endif + +#if EN_SPIE_REG_DUMMY_BYTE + (*recv_buffer) = (*recv_buffer) + rx_dummy_len; +#else + /* find first 0xa5 */ + while (**recv_buffer != 0xa5) { + (*recv_buffer)++; + get_count++; + if (get_count >= rx_dummy_len) { + misp_info("%s, dummy byte excess 32!", __func__); + return -EIO; + } + } + + /* check last 0xa5*/ + while (*(*recv_buffer+1) == 0xa5) { + (*recv_buffer)++; + get_count++; + if (get_count >= rx_dummy_len) { + misp_info("%s, dummy byte excess 32!", __func__); + return -EIO; + } + } + + /* find available data */ + (*recv_buffer)++; +#endif + +#if EN_SPIE_DEBUG + misp_info("%s, available byte: 0x%x", __func__, (u32)(**recv_buffer)); +#endif + return ret; +} + + +errcode mini_isp_create_directory(char *dir_name) +{ + size_t errcode = ERR_SUCCESS; + struct dentry *dentry; + struct path path; + + dentry = kern_path_create(AT_FDCWD, dir_name, + &path, LOOKUP_DIRECTORY); + if (IS_ERR(dentry)) { + misp_info("%s, fail %d", __func__, IS_ERR(dentry)); + return PTR_ERR(dentry); + } + + errcode = vfs_mkdir(path.dentry->d_inode, dentry, 0777); + + done_path_create(&path, dentry); + + misp_info("%s, create directory %s", __func__, dir_name); + return errcode; +} + +/** + *\brief Get rx dummy byte. + *\param spie_rx_mode [In], spie rx mode. memory read or register read. + *\ If it's not spie mode, set 0 for default. + *\return dummy byte lens + */ + +u32 mini_isp_get_rx_dummy_byte(u8 spie_rx_mode) +{ + u32 rx_dummy_byte = 0; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + /* only spi-e need configure rx dummy byte */ + if (dev_global_variable->intf_status & INTF_SPI_READY) { +#if EN_SPIE_REG_DUMMY_BYTE + if (spie_rx_mode == CTRL_BYTE_REGRD) + rx_dummy_byte = SPIE_RX_REG_DUMMY_LEN; + else if (spie_rx_mode == CTRL_BYTE_MEMRD) + rx_dummy_byte = SPIE_RX_MEM_DUMMY_LEN; +#else + rx_dummy_byte = SPIE_RX_DUMMY_LEN; +#endif + } else if (dev_global_variable->intf_status & INTF_I2C_READY) + rx_dummy_byte = 0; + else + rx_dummy_byte = 0; + + return rx_dummy_byte; +} + +void mini_isp_set_spie_dummy_byte(u32 dummy_lens) +{ + mini_isp_register_write(SPIE_DUMMY_BYTE_ADDR, dummy_lens); +} diff --git a/drivers/media/platform/altek/miniisp_utility.c b/drivers/media/platform/altek/miniisp_utility.c new file mode 100644 index 000000000000..d28f0935a19b --- /dev/null +++ b/drivers/media/platform/altek/miniisp_utility.c @@ -0,0 +1,2376 @@ +/* + * File: miniisp_utility.c + * Description: Mini ISP Utility sample codes + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2017/03/29; Louis Wang; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + + /******Include File******/ +#include "linux/init.h" +#include "linux/module.h" +#include +#include +#include +#include +#include +#include +#include + +#ifdef NEW_CLOCK_HEADER +#include +#endif + +#include "include/miniisp.h" +#include "include/error.h" +#include "include/miniisp_chip_base_define.h" +#include "include/miniisp_customer_define.h" + + +#define MINI_ISP_LOG_TAG "[miniisp_utility]" + +#define DEBUG_INFO_DEPTH_FLOW_INFO_ADDR (0x28) +#define DEBUG_INFO_METADATA_ADDR (0x14) +#define DEBUG_INFO_FEC_DEBUG_MODE_ADDR (0x40) +#define DEBUG_INFO_SENSOR_REAL_INFO_ADDR (0x44) +#define DEBUG_INFO_LED_INFO_ADDR (0x48) + +#define ADV_LOG_LIGHTING_PROJECTOR (0x5) +#define ADV_LOG_LIGHTING_FLOOD (0x6) + +#define PACKDATA_SIZE (1824) +#define PACKDATA_OFFSET (0x4C) + +#define LOG_BUF_SIZE (200*1024) + +GPIO g_atGPIO[] = { + + { "GPIO0", 0xFFEA0200, "NoUse" }, + { "GPIO1", 0xFFEA0204, "NoUse" }, + { "GPIO2", 0xFFEA0208, "NoUse" }, + { "GPIO3", 0xFFEA020c, "NoUse" }, + { "GPIO4", 0xFFEA0210, "NoUse" }, + { "GPIO5", 0xFFEA0214, "NoUse" }, + { "GPIO6", 0xFFEA0218, "NoUse" }, + { "GPIO7", 0xFFEA021C, "NoUse" }, + { "GPIO8", 0xFFEA0220, "NoUse" }, + { "GPIO9", 0xFFEA0224, "NoUse" }, + { "GPIO10", 0xFFEA0228, "NoUse" } +}; +#define GPIO_NUMBER (sizeof(g_atGPIO)/sizeof(GPIO)) + + /******Private Global Variable******/ + + + /******Public Function******/ +/** + *\brief dump AL6100 register for debug bypass mode + *\return Error code +*/ +errcode mini_isp_utility_read_reg_e_mode_for_bypass_use(void) +{ + errcode err = ERR_SUCCESS; + u8 filepath[80]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + mutex_lock(&dev_global_variable->busy_lock); + + /* switch to E mode */ + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + snprintf(filepath, 80, "%s/dump_bypass_reg/", + MINIISP_INFO_DUMPLOCATION); + err = mini_isp_create_directory(filepath); + err = mini_isp_chip_base_dump_bypass_mode_register(filepath); + + /* switch to A mode */ + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return err; +} +EXPORT_SYMBOL(mini_isp_utility_read_reg_e_mode_for_bypass_use); + + +/** + *\brief dump AL6100 register for debug + *\return Error code +*/ +errcode mini_isp_utility_read_reg_e_mode(void) +{ + errcode err = ERR_SUCCESS; + u8 filepath[80]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + mutex_lock(&dev_global_variable->busy_lock); + + /* switch to E mode */ + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + snprintf(filepath, 80, "%s/dump_normal_reg/", + MINIISP_INFO_DUMPLOCATION); + err = mini_isp_create_directory(filepath); + err = mini_isp_chip_base_dump_normal_mode_register(filepath); + + /* switch to A mode */ + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return err; +} +EXPORT_SYMBOL(mini_isp_utility_read_reg_e_mode); + +/** + *\brief Read irp and depth image based information + *\return Error code +*/ +errcode mini_isp_utility_get_irp_and_depth_information( + struct irp_and_depth_information *info) +{ + errcode err = ERR_SUCCESS; + u32 rg_img_in_size; + u32 rg_depth_in_size; + u32 crop_src; + u8 fov_mode; + + mini_isp_register_read(0xfff8401c, &rg_img_in_size); + info->irp_width = ((rg_img_in_size & 0x00001fff)+1); + info->irp_height = (((rg_img_in_size & 0x1fff0000)>>16)+1); + + mini_isp_register_read(0xfffa7020, &crop_src); + + if (crop_src) + info->irp_format = 1; + else + info->irp_format = 0; + + mini_isp_register_read(0xfff5601c, &rg_depth_in_size); + info->depth_width = ((rg_depth_in_size & 0x00001fff)+1); + info->depth_height = (((rg_depth_in_size & 0x1fff0000)>>16)+1); + + info->depth_image_address = 0x20715400; + + mini_isp_memory_read(0x24, &fov_mode, 1); + + info->fov_mode = fov_mode; + if (fov_mode == 1) + info->irp_image_address = 0x20500000 + 288000 - + ((rg_img_in_size & 0x00001fff) + 1) * + (((rg_img_in_size & 0x1fff0000)>>16) + 1); + else + info->irp_image_address = 0x20500000; + misp_info("%s:depth_image_address:%u, depth_width:%u, depth_height:%u, \ + irp_format:%u, irp_image_address:%u, irp_width:%u, \ + irp_height:%u, fov_mode:%u\n", __func__, + info->depth_image_address, info->depth_width, + info->depth_height, info->irp_format, + info->irp_image_address, info->irp_width, + info->irp_height, info->fov_mode); + return err; +} +EXPORT_SYMBOL(mini_isp_utility_get_irp_and_depth_information); + +/** + *\brief dump compress irp img and rectify depth + *\return Error code + */ +int mini_isp_debug_dump_img(void) +{ + #define left_rotate_val 1 + #define right_rotate_val 2 + + int errcode = ERR_SUCCESS; + u8 write_buffer[4]; + u32 rg_img_in_size; + u32 rotate_mode = 0; + u32 img_width = 0, img_height = 0; + u32 HighDistRateFlag = 0; + u32 YUVFlag = 0; + u32 img_size_mul = 100, img_size_div = 100; + u32 img_addr = 0; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + mini_isp_register_read(0xfff8401c, &rg_img_in_size); + mini_isp_register_read(0xfff84014, &rotate_mode); + rotate_mode &= 0x3; + + /* Step 1 */ + write_buffer[0] = 1; + mini_isp_memory_write(0x10, write_buffer, 1); + + msleep(2000); /* delay 2 sec */ + /* IRP image rotate */ + if (rotate_mode == right_rotate_val || rotate_mode == left_rotate_val) { + img_height = (rg_img_in_size & 0x1fff) + 1; /* 0 base */ + img_width = ((rg_img_in_size >> 16) & 0x1fff) + 1; /* 0 base */ + } else { + img_width = (rg_img_in_size & 0x1fff) + 1; /* 0 base */ + img_height = ((rg_img_in_size >> 16) & 0x1fff) + 1; /* 0 base */ + } + + mini_isp_register_read(0xffe80064, &YUVFlag); + YUVFlag = !YUVFlag; + mini_isp_register_read(0x24, &HighDistRateFlag); + HighDistRateFlag &= 0xFF; + + if (HighDistRateFlag) { + img_addr = 0x20500000 + 288000 - (img_width * img_height); + img_size_mul = 100; + img_size_div = 100; + } else { + img_addr = 0x20500000; + img_size_mul = 125; + img_size_div = 100; + } + + misp_info("%s - [W,H]: [%d, %d], rotate_mode: %d, YUV: %d, HighDistRateFlag: %d", + __func__, img_width, img_height, + rotate_mode, YUVFlag, HighDistRateFlag); + + mini_isp_memory_read_then_write_file(img_addr, + (img_width * img_height * img_size_mul / img_size_div), + MINIISP_INFO_DUMPLOCATION, "compress_irp"); + + /* Step 2 */ + write_buffer[0] = 2; + mini_isp_memory_write(0x10, write_buffer, 1); + msleep(100); /* image will broken if no delay time */ + + mini_isp_register_read(0xfff5601C, &rg_img_in_size); + img_width = (rg_img_in_size & 0x1fff) + 1; + img_height = ((rg_img_in_size >> 16) & 0x1fff) + 1; + + mini_isp_memory_read_then_write_file(0x20715400, + (img_width * img_height * 10/8), + MINIISP_INFO_DUMPLOCATION, "rect_depth"); + + /* step 3, restore */ + write_buffer[0] = 0; + mini_isp_memory_write(0x10, write_buffer, 1); + msleep(100); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return errcode; +} +EXPORT_SYMBOL(mini_isp_debug_dump_img); + +/** + *\brief dump every phase of depth module info, and save as file + *\param is_ground_mode [in] 0: For depth normal mdoe. + *\ 1: For depth ground mode + *\return Error code + */ +int mini_isp_debug_depth_rect_combo_dump(u8 is_ground_mode) +{ + int errcode = ERR_SUCCESS; + u8 write_buffer[4]; + u8 filepath[80]; + u8 filename[80]; + u8 loopNum = 1, loopIdx = 0; + u32 rg_img_in_size; + u32 ref_img_width = 0, ref_img_height = 0; + u32 start_x = 0, start_y = 0; + u32 imgAddr, ref_imgLinePixelOffset; + u32 tmp; + + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + if (is_ground_mode) + loopNum = 2; + else + loopNum = 1; + + /* create base folder */ + snprintf(filepath, 80, "%s/depth_combo_dump/", + MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + + /* First loop for Normal, second loop for gound */ + for (loopIdx = 0; loopIdx < loopNum; loopIdx++) { + /* step 1 */ + write_buffer[0] = 1; + mini_isp_memory_write(0x10, write_buffer, 1); + msleep(100); + + /* step 2 */ + write_buffer[0] = 1; + mini_isp_memory_write(0x20, write_buffer, 1); + msleep(100); + + /* step 3 */ + write_buffer[0] = 2; + mini_isp_memory_write(0x10, write_buffer, 1); + msleep(100); + + /* dump reg */ + snprintf(filepath, 80, + "%s/depth_combo_dump/%s_step3_rectify_a_0/", + MINIISP_INFO_DUMPLOCATION, (loopIdx == 0)?"n":"g"); + errcode = mini_isp_create_directory(filepath); + mini_isp_chip_base_define_module_reg_dump(filepath, "rectify_a_0"); + + mini_isp_register_read(0xFFF8C104, &tmp); + start_x = (tmp & 0x00001fff)+1; + start_y = ((tmp & 0x1fff0000) >> 16)+1; + + mini_isp_register_read(0xFFF8C108, &tmp); + ref_img_width = (tmp & 0x00001fff)+1; + ref_img_height = ((tmp & 0x1fff0000) >> 16)+1; + + ref_img_width = ref_img_width - start_x + 1; + ref_img_height = ref_img_height - start_y + 1; + + misp_info("step3 m [ref_w,ref_h]: %d ,%d", ref_img_width, ref_img_height); + + mini_isp_register_read(0xFFF8C510, &imgAddr); + mini_isp_register_read(0xFFF8C518, &ref_imgLinePixelOffset); + ref_imgLinePixelOffset *= 8; + + /* step 4 */ + write_buffer[0] = 2; + mini_isp_memory_write(0x20, write_buffer, 1); + msleep(100); + + /* dump reg */ + snprintf(filepath, 80, + "%s/depth_combo_dump/%s_step4_rectify_a_0/", + MINIISP_INFO_DUMPLOCATION, (loopIdx == 0)?"n":"g"); + errcode = mini_isp_create_directory(filepath); + mini_isp_chip_base_define_module_reg_dump(filepath, "rectify_a_0"); + + /* dump img */ + misp_info("[Step4] %s Main W,H: %d, %d", (loopIdx == 0)?"n":"g", + ref_img_width, ref_img_height); + snprintf(filepath, 80, "%s/depth_combo_dump/", + MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + snprintf(filename, 80, "%s_%s", (loopIdx == 0)?"n":"g", "step4_mainRect_img_8bit.raw"); + errcode = mini_isp_woi_memory_read_then_write_file(imgAddr, + ref_imgLinePixelOffset, ref_img_width, ref_img_height, filepath, filename); + + mini_isp_register_read(0xFFF8C104, &tmp); + start_x = (tmp & 0x00001fff)+1; + start_y = ((tmp & 0x1fff0000) >> 16)+1; + + mini_isp_register_read(0xFFF8C108, &tmp); + ref_img_width = (tmp & 0x00001fff)+1; + ref_img_height = ((tmp & 0x1fff0000) >> 16)+1; + + ref_img_width = ref_img_width - start_x + 1; + ref_img_height = ref_img_height - start_y + 1; + + mini_isp_register_read(0xFFF8C510, &imgAddr); + mini_isp_register_read(0xFFF8C518, &ref_imgLinePixelOffset); + ref_imgLinePixelOffset *= 8; + + /* dump img */ + misp_info("[Step4] %s Sub W,H: %d, %d", + (loopIdx == 0)?"n":"g", + ref_img_width, ref_img_height); + snprintf(filepath, 80, "%s/depth_combo_dump/", + MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + snprintf(filename, 80, "%s_%s", (loopIdx == 0)?"n":"g", + "step4_subRect_img_8bit.raw"); + errcode = mini_isp_woi_memory_read_then_write_file(imgAddr, + ref_imgLinePixelOffset, ref_img_width, + ref_img_height, filepath, filename); + + /* step 5 */ + write_buffer[0] = 3; + mini_isp_memory_write(0x20, write_buffer, 1); + msleep(100); + + /* dump reg */ + snprintf(filepath, 80, + "%s/depth_combo_dump/%s_step5_rectify_a_0/", + MINIISP_INFO_DUMPLOCATION, (loopIdx == 0)?"n":"g"); + errcode = mini_isp_create_directory(filepath); + mini_isp_chip_base_define_module_reg_dump( + filepath, "rectify_a_0"); + + snprintf(filepath, 80, + "%s/depth_combo_dump/%s_step5_rectify_b_0/", + MINIISP_INFO_DUMPLOCATION, (loopIdx == 0)?"n":"g"); + errcode = mini_isp_create_directory(filepath); + mini_isp_chip_base_define_module_reg_dump( + filepath, "rectify_b_0"); + + snprintf(filepath, 80, + "%s/depth_combo_dump/%s_step5_dg_ca_a_0/", + MINIISP_INFO_DUMPLOCATION, (loopIdx == 0)?"n":"g"); + errcode = mini_isp_create_directory(filepath); + mini_isp_chip_base_define_module_reg_dump( + filepath, "dg_ca_a_0"); + + snprintf(filepath, 80, + "%s/depth_combo_dump/%s_step5_dg_mcc_a_0/", + MINIISP_INFO_DUMPLOCATION, (loopIdx == 0)?"n":"g"); + errcode = mini_isp_create_directory(filepath); + mini_isp_chip_base_define_module_reg_dump( + filepath, "dg_mcc_a_0"); + + /* dump img */ + misp_info("[Step5] %s dg W,H: %d, %d", + (loopIdx == 0)?"n":"g", 1024, + ref_img_height); + snprintf(filepath, 80, "%s/depth_combo_dump/", + MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + snprintf(filename, 80, "%s_%s", + (loopIdx == 0)?"n":"g", + "step5_dg_img_10unpack.raw"); + errcode = mini_isp_woi_memory_read_then_write_file(0x20100000, + 1024*2, ref_img_width*2, ref_img_height, filepath, filename); + + /* step 6 */ + write_buffer[0] = 4; + mini_isp_memory_write(0x20, write_buffer, 1); + msleep(100); + + /* dump reg */ + snprintf(filepath, 80, "%s/depth_combo_dump/%s_step6_dp_top_a_0/", + MINIISP_INFO_DUMPLOCATION, (loopIdx == 0)?"n":"g"); + errcode = mini_isp_create_directory(filepath); + mini_isp_chip_base_define_module_reg_dump(filepath, "dp_top_a_0"); + + /* dump img */ + misp_info("[Step6] %s dg_top W,H: %d, %d", + (loopIdx == 0)?"n":"g", 1024, + ref_img_height); + snprintf(filepath, 80, "%s/depth_combo_dump/", + MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + snprintf(filename, 80, "%s_%s", (loopIdx == 0)?"n":"g", + "step6_dp_img_10unpack.raw"); + errcode = mini_isp_woi_memory_read_then_write_file(0x20100000, + 1024*2, ref_img_width*2, + ref_img_height, filepath, filename); + + /* step 7 */ + write_buffer[0] = 5; + mini_isp_memory_write(0x20, write_buffer, 1); + msleep(100); + + /* dump reg */ + snprintf(filepath, 80, "%s/depth_combo_dump/%s_step7_rectify_b_0/", + MINIISP_INFO_DUMPLOCATION, (loopIdx == 0)?"n":"g"); + errcode = mini_isp_create_directory(filepath); + mini_isp_chip_base_define_module_reg_dump(filepath, "rectify_b_0"); + + /* dump img */ + if (is_ground_mode) { + mini_isp_register_read(0xFFF8C104, &tmp); + start_x = (tmp & 0x00001fff)+1; + start_y = ((tmp & 0x1fff0000) >> 16)+1; + + mini_isp_register_read(0xFFF8C108, &tmp); + ref_img_width = (tmp & 0x00001fff)+1; + ref_img_height = ((tmp & 0x1fff0000) >> 16)+1; + + ref_img_width = ref_img_width - start_x + 1; + ref_img_height = ref_img_height - start_y + 1; + } else { + mini_isp_register_read(0xfff5601c, &rg_img_in_size); + ref_img_width = (rg_img_in_size & 0x00001fff) + 1; + ref_img_height = ((rg_img_in_size & 0x1fff0000)>>16) + 1; + } + + misp_info("[Step7] %s InvRect W,H: %d, %d", + (loopIdx == 0)?"n":"g", + ref_img_width, ref_img_height); + snprintf(filepath, 80, "%s/depth_combo_dump/", + MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + + imgAddr = (loopIdx == 0) ? 0x20715400 : 0x20669AC0; + snprintf(filename, 80, "%s_%s", + (loopIdx == 0)?"n":"g", + "step7_InvRect_img_10pack.raw"); + + errcode = mini_isp_memory_read_then_write_file(imgAddr, + (ref_img_width * ref_img_height * 10 / 8), filepath, filename); + + } + + if (is_ground_mode) { + write_buffer[0] = 6; + mini_isp_memory_write(0x20, write_buffer, 1); + msleep(300); + + /* dump reg */ + snprintf(filepath, 80, "%s/depth_combo_dump/step9_rectify_b_0/", + MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + mini_isp_chip_base_define_module_reg_dump(filepath, "rectify_b_0"); + + /* dump img */ + misp_info("[Step9] blending W,H: %d, %d", 1024, ref_img_height); + snprintf(filepath, 80, "%s/depth_combo_dump/", MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + errcode = mini_isp_woi_memory_read_then_write_file(0x20100000, + 1024*2, ref_img_width*2, ref_img_height, filepath, "g_step9_blending_img_10unpack.raw"); + + misp_info("[Step9] InvRect W,H: %d, %d", ref_img_width, ref_img_height); + snprintf(filepath, 80, "%s/depth_combo_dump/", MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + + mini_isp_register_read(0xfff5601c, &rg_img_in_size); + ref_img_width = (rg_img_in_size & 0x00001fff) + 1; + ref_img_height = ((rg_img_in_size & 0x1fff0000)>>16) + 1; + errcode = mini_isp_memory_read_then_write_file(0x20715400, + (ref_img_width * ref_img_height * 10 / 8), filepath, "g_step9_InvRect_img_10pack.raw"); + } + + /* step final restore */ + write_buffer[0] = 0; + mini_isp_memory_write(0x20, write_buffer, 1); + msleep(300); + + write_buffer[0] = 0; + mini_isp_memory_write(0x10, write_buffer, 1); + msleep(300); + + if (dev_global_variable->intf_status & INTF_SPI_READY && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return errcode; +} +EXPORT_SYMBOL(mini_isp_debug_depth_rect_combo_dump); + +errcode mini_isp_debug_packdata_dump(void) +{ + errcode errcode = ERR_SUCCESS; + u32 packdebuginfo_addr = 0; + u32 packdata_addr = 0; + char filepath[80]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + mini_isp_memory_read(DEBUG_INFO_DEPTH_FLOW_INFO_ADDR, (u8 *)&packdebuginfo_addr, 4); + if (packdebuginfo_addr != 0) { + mini_isp_memory_read(packdebuginfo_addr+PACKDATA_OFFSET, (u8 *)&packdata_addr, 4); + } else{ + misp_info("%s, addr err", __func__); + goto EXIT; + } + + if (packdata_addr != 0) { + misp_info("%s dump 1824 bytes", __func__); + snprintf(filepath, 80, "%s", MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + errcode = mini_isp_memory_read_then_write_file(packdata_addr, + PACKDATA_SIZE, filepath, "Dump_packdata.bin"); + } else{ + misp_info("%s, addr err", __func__); + goto EXIT; + } + +EXIT: + if (dev_global_variable->intf_status & INTF_SPI_READY && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return errcode; +} +EXPORT_SYMBOL(mini_isp_debug_packdata_dump); + +/** + *\brief save IQCalibration data as a file + *\return Error code + */ +errcode mini_isp_debug_IQCalib_dump(void) +{ + errcode errcode = ERR_SUCCESS; + u32 IQCalib_addr = 0; + char filepath[80]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + mini_isp_memory_read(0x30, (u8 *)&IQCalib_addr, 4); + if (IQCalib_addr != 0) { + misp_info("%s dump", __func__); + snprintf(filepath, 80, "%s", MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + errcode = mini_isp_memory_read_then_write_file(IQCalib_addr, + 16556, filepath, "Dump_IQCalibration.bin"); + } else + misp_info("%s, addr err", __func__); + + if (dev_global_variable->intf_status & INTF_SPI_READY && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return errcode; +} +EXPORT_SYMBOL(mini_isp_debug_IQCalib_dump); + +/** + *\brief save metadata as a file + *\return Error code + */ +errcode mini_isp_debug_metadata_dump(void) +{ + errcode errcode = ERR_SUCCESS; + u32 metadata_addr = 0; + char filepath[80]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + mini_isp_memory_read(0x14, (u8 *)&metadata_addr, 4); + if (metadata_addr != 0) { + misp_info("%s dump", __func__); + snprintf(filepath, 80, "%s", MINIISP_INFO_DUMPLOCATION); + errcode = mini_isp_create_directory(filepath); + errcode = mini_isp_memory_read_then_write_file(metadata_addr, + 4*1024, filepath, "Dump_MetaData.bin"); + } else + misp_info("%s, addr err", __func__); + + if (dev_global_variable->intf_status & INTF_SPI_READY && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return errcode; +} +EXPORT_SYMBOL(mini_isp_debug_metadata_dump); + +static u32 CalculatePackdataCheckSum(u8 *PackdataBuf) +{ + u32 *PackdataBuf4B = (u32 *)PackdataBuf; + u32 CheckSum = 0; + u32 ii = 0; + + for (ii = 0; ii < PACKDATA_SIZE/4; ii++) { + CheckSum += *PackdataBuf4B; + PackdataBuf4B++; + } + + return CheckSum; +} + +static void mini_isp_debug_depth_info_parser(DEPTHFLOWMGR_DEBUG_INFO *ptDepthFlowInfo) +{ + u32 modeid; + u32 refImg1_w, refImg1_h, refImg2_w, refImg2_h, refImg3_w, refImg3_h; + u32 refImg1_Idx, refImg2_Idx, refImg3_Idx; + u32 KernelSizeRatio; + u32 DepthType; + u32 GroundMode; + u32 ValidPackdata; + u32 ValidDisparityToDistanceTable; + u32 HighDistortionRateFlag; + u32 PackdataIdxNormal, PackdataIdxGround, PackdataIdxRGB; + u32 GlobalCompensation; + u32 HwCoefficient; + u32 HighDistortionIdx; + u32 PackdataSrc; + u32 WOI_x, WOI_y, WOI_w, WOI_h, Full_w, Full_h; + u32 ValidBlendingTable; + u32 BlendingSrc; + u32 ValidQmerge; + u32 dist[] = { 0, 0, 0 }; + u32 tmp; + + const u32 modeid_min = 0; + const u32 modeid_max = 8; + const u32 KernelSizeRatio_min = 0; + const u32 KernelSizeRatio_max = 15; + const u32 GlobalCompensation_21 = 21; + const u32 GlobalCompensation_36 = 36; + const u32 HwCoefficient_16 = 16; + const u32 uwHighDistortionIdx_max = 5; + const char ResStr[4][64] = {"16:9", "16:10", "4:3", "@:@"}; + + if (ptDepthFlowInfo == NULL) { + misp_info("%s fail!", __func__); + return; + } + if (!ptDepthFlowInfo->ValidFlag) { + misp_info("depth info ValidFlag err! L:%d", __LINE__); + return; + } + + if (ptDepthFlowInfo->Ver != DEPTH_FLOWMGR_INFO_VER) { + misp_info("depth info version err! L:%d", __LINE__); + misp_info("Depth debug version: 0x%X", ptDepthFlowInfo->Ver); + misp_info("Linux depth debug ver: 0x%X", DEPTH_FLOWMGR_INFO_VER); + return; + } + + misp_info("====== Depth Debug Info ======"); + misp_info("=== Check Depth Debug Info Version ==="); + misp_info("Depth debug version: 0x%X", ptDepthFlowInfo->Ver); + misp_info("alDU ver: %d.%d", ptDepthFlowInfo->ALDU_MainVer, ptDepthFlowInfo->ALDU_SubVer); + misp_info("=== DepthFlowInfo: General ==="); + + + if (ptDepthFlowInfo->tDepthFlowDebugInfo.ValidDepthFlowDebugInfo == false) { + misp_info("General information all invalid."); + goto DepthFlowDebugInfoEnd; + } else{ + modeid = ptDepthFlowInfo->tDepthFlowDebugInfo.DepthFlowModeId; + if (modeid > modeid_max) { + misp_info("Depth Flow Mode ID: %d. (error! mode id out of range %d~%d)", + modeid, modeid_min, modeid_max); + goto DepthFlowDebugInfoEnd; + } else + misp_info("Depth Flow Mode ID: %d. (valid range %d~%d)", + modeid, modeid_min, modeid_max); + } + + /* ref img1 w/h */ + refImg1_w = ptDepthFlowInfo->tDepthFlowDebugInfo.refImg1_Width; + refImg1_h = ptDepthFlowInfo->tDepthFlowDebugInfo.refImg1_Height; + switch (16 * refImg1_h / refImg1_w) { + case 9: + refImg1_Idx = RESOLUTION_16_9; + break; + case 10: + refImg1_Idx = RESOLUTION_16_10; + break; + case 12: + refImg1_Idx = RESOLUTION_4_3; + break; + default: + refImg1_Idx = RESOLUTION_OTHER; + break; + } + + if (refImg1_Idx != RESOLUTION_OTHER) + misp_info("ref1 Img Resolution: %dx%d. (%s)", + refImg1_w, refImg1_h, ResStr[refImg1_Idx]); + else { + /* mutiple 100 for division */ + tmp = refImg1_h * 16 * 100 / refImg1_w; + misp_info("ref1 Img Resolution: %dx%d. (16:%d.%d)", + refImg1_w, refImg1_h, tmp/100, tmp%100); + } + + /* ref img2 w/h */ + refImg2_w = ptDepthFlowInfo->tDepthFlowDebugInfo.refImg2_Width; + refImg2_h = ptDepthFlowInfo->tDepthFlowDebugInfo.refImg2_Height; + + /* check resolution index */ + switch (16 * refImg2_h / refImg2_w) { + case 9: + refImg2_Idx = RESOLUTION_16_9; + break; + case 10: + refImg2_Idx = RESOLUTION_16_10; + break; + case 12: + refImg2_Idx = RESOLUTION_4_3; + break; + default: + refImg2_Idx = RESOLUTION_OTHER; + break; + } + + /* display solution */ + if (refImg2_Idx != RESOLUTION_OTHER) + misp_info("ref2 Img Resolution: %dx%d. (%s)", + refImg2_w, refImg2_h, ResStr[refImg2_Idx]); + else { + /* mutiple 100 for division */ + tmp = refImg2_h * 16 * 100 / refImg2_w; + misp_info("ref2 Img Resolution: %dx%d. (16:%d.%d)", + refImg2_w, refImg2_h, tmp/100, tmp%100); + } + /* display warning */ + if (refImg2_Idx != refImg1_Idx) + misp_info("(Warning!. ref1 Img resolution is %s, but ref2 Img resolution is %s.", ResStr[refImg1_Idx], ResStr[refImg2_Idx]); + + if (refImg2_w > refImg1_w) + misp_info("(Warning!. ref2 Img width %d > ref1 Img width %d.", refImg2_w, refImg1_w); + + if (refImg2_h > refImg1_h) + misp_info("(Warning!. ref2 Img height %d > ref1 Img height %d.", refImg2_h, refImg1_h); + + + /* ref img3 w/h */ + refImg3_w = ptDepthFlowInfo->tDepthFlowDebugInfo.refImg3_Width; + refImg3_h = ptDepthFlowInfo->tDepthFlowDebugInfo.refImg3_Height; + switch (16 * refImg3_h / refImg3_w) { + case 9: + refImg3_Idx = RESOLUTION_16_9; + break; + case 10: + refImg3_Idx = RESOLUTION_16_10; + break; + case 12: + refImg3_Idx = RESOLUTION_4_3; + break; + default: + refImg3_Idx = RESOLUTION_OTHER; + break; + } + + if (refImg3_Idx != RESOLUTION_OTHER) + misp_info("ref3 Img Resolution: %dx%d. (%s)", refImg3_w, refImg3_h, ResStr[refImg3_Idx]); + else { + tmp = refImg3_h * 16 * 100 / refImg3_w ; /* mutiple 100 for division */ + misp_info("ref3 Img Resolution: %dx%d. (16:%d.%d)", refImg3_w, refImg3_h, + tmp/100, tmp%100); + } + + /* kernel size ratio */ + KernelSizeRatio = ptDepthFlowInfo->tDepthFlowDebugInfo.DepthImgKernelSizeRatio; + if (KernelSizeRatio > KernelSizeRatio_max) + misp_info("Kernel Size Ratio: %d. (error! ration output of range %d~%d).", KernelSizeRatio, KernelSizeRatio_min, KernelSizeRatio_max); + else + misp_info("Kernel Size Ratio: %d. (valid range %d~%d).", KernelSizeRatio, KernelSizeRatio_min, KernelSizeRatio_max); + + /* Depth type */ + DepthType = ptDepthFlowInfo->tDepthFlowDebugInfo.DepthType; + misp_info("Depth Type: %d. (%s)", DepthType, (DepthType > 0) ? "Active" : "Passive"); + + /* Ground mode */ + GroundMode = ptDepthFlowInfo->tDepthFlowDebugInfo.DepthGroundType; + switch (GroundMode) { + case 0: + misp_info("Ground Type: 0 (Normal mode only)."); + break; + case 0x10: + misp_info("Ground Type: 0x%X. (Ground Enhance).", + GroundMode); + break; + case 0x30: + misp_info("Ground Type: 0x%X. (Ground Enhance + Advance Hold Fill).", GroundMode); + break; + case 0x50: + misp_info("Ground Type: 0x%X. (Ground Enhance + Anti-Cliff).", GroundMode); + break; + case 0x70: + misp_info("Ground Type: 0x%X. (Ground Enhance + Advance Hold Fill + Anti-Cliff).", GroundMode); + break; + default: + misp_info("Ground Type: 0x%X. (Unkown feature).", GroundMode); + break; + } + + /* Processing time */ + if (0 != ptDepthFlowInfo->tDepthFlowDebugInfo.DephtProcTime) { + tmp = ptDepthFlowInfo->tDepthFlowDebugInfo.DephtProcTime*100/1000; + misp_info("Processing Time: %d.%d ms.", tmp/100, tmp%100); + tmp = 1000000*100/ptDepthFlowInfo->tDepthFlowDebugInfo.DephtProcTime; + misp_info("Processing max fps: %d.%d", tmp/100, tmp%100); + } else + misp_info("Processing Time: 0."); + + /* Blending process time */ + tmp = ptDepthFlowInfo->tDepthFlowDebugInfo.BlendingProcTime*100 / 1000; + misp_info("Blending processing time: %d.%d ms.", tmp/100, tmp%100); + + /* Frame count */ + misp_info("Frame Count: %d.", ptDepthFlowInfo->tDepthFlowDebugInfo.DepthProcCnt); + + /* Feature flag: InvRec LDC bypass */ + misp_info("Feature flag: %d.", ptDepthFlowInfo->tDepthFlowDebugInfo.FeatureFlag); + + /* InvRECT_BypassLDC */ + misp_info("InvRect bypass LDC: %d.", ptDepthFlowInfo->tDepthFlowDebugInfo.InvRECT_BypassLDC); + + /* check feature flag */ + if ((ptDepthFlowInfo->tDepthFlowDebugInfo.FeatureFlag & 0x1) != + ptDepthFlowInfo->tDepthFlowDebugInfo.InvRECT_BypassLDC) + misp_info("InvRect bypass flag is not eqaual feature flag."); + + /* PerformanceFlag */ + /* [Debug] FALSE: DEPTH_PERFORMANCE_FLAG disable, TRUE: DEPTH_PERFORMANCE_FLAG enable */ + misp_info("Performance flag: %d.", ptDepthFlowInfo->tDepthFlowDebugInfo.PerformanceFlag); + + /* NormalKernalSizeMatch */ + /* [Debug] Valid when DEPTH_PERFORMANCE_FLAG enable, TRUE: Kernel size of normal mode can be extimated by clock and Frame rate */ + misp_info("Normal kernel size match flag: %d.", ptDepthFlowInfo->tDepthFlowDebugInfo.NormalKernalSizeMatch); + + /* GroundKernalSizeMatch */ + /* [Debug] Valid when DEPTH_PERFORMANCE_FLAG enable, TRUE: Kernel size of ground mode can be extimated by clock and Frame rate */ + misp_info("Ground kernel size match flag: %d.", ptDepthFlowInfo->tDepthFlowDebugInfo.GroundKernalSizeMatch); + + /* NormalKernelSizeIdx */ + /* [Debug] Kernel size idx of normal mode, if NormalKernalSizeMatch is False, + then it means the kernel size could not be extimated by clock and frame rate */ + misp_info("Normal kernel size index: %d. (0~15)", ptDepthFlowInfo->tDepthFlowDebugInfo.NormalKernelSizeIdx); + + /* GroundKernelSizeIdx */ + /* [Debug] Kernel size idx of ground mode, if GroundKernalSizeMatch is False, + then it means the kernel size could not be extimated by clock and frame rate */ + misp_info("Ground kernel size index: %d. (0~15)", ptDepthFlowInfo->tDepthFlowDebugInfo.GroundKernelSizeIdx); +DepthFlowDebugInfoEnd: + + misp_info("=== DepthFlowInfo: Utility ==="); + if (ptDepthFlowInfo->tDepthUtiDebugInfo.ValidDepthUtiDebugInfo == false) { + misp_info("Utility information all invalid."); + goto UtilityEnd; + } + + /* ValidBlendingTable */ + ValidBlendingTable = ptDepthFlowInfo->tDepthUtiDebugInfo.ValidBlendingTable; + if (ValidBlendingTable) { + /* Set blending table source */ + BlendingSrc = ptDepthFlowInfo->tDepthUtiDebugInfo.BlendingTableSource; + if (BlendingSrc == DEPTHBLENDING_SRC_CMD) + misp_info("Blending table is available: %d. (AP send to ISP).", BlendingSrc); + else if (BlendingSrc == DEPTHBLENDING_SRC_ISP) + misp_info("Blending table is available: %d. (ISP calculated done).", BlendingSrc); + else + misp_info("Warning!! Blending table source from nowhere: %d. (ground mode may fail).", BlendingSrc); + } + + + /* Distance */ + dist[0] = ptDepthFlowInfo->tDepthUtiDebugInfo.DistanceVal[0]; + dist[1] = ptDepthFlowInfo->tDepthUtiDebugInfo.DistanceVal[1]; + dist[2] = ptDepthFlowInfo->tDepthUtiDebugInfo.DistanceVal[2]; + + misp_info("Distance: (upper, middle, lower) = (%d, %d, %d)mm. (after v764 change cm to mm)", + dist[0], dist[1], dist[2]); + + /* Blending table source and size */ + misp_info("Blending table source: %d. (0:None 1:AP 2:ISP)", ptDepthFlowInfo->tDepthUtiDebugInfo.BlendingTableSource); + misp_info("Blending table size: %d.", ptDepthFlowInfo->tDepthUtiDebugInfo.BlendingTableSize); + + /* Blending start line */ + misp_info("Blending start line: %d.", ptDepthFlowInfo->tDepthUtiDebugInfo.BlendingStartLine); + + /* Valid QMerge */ + ValidQmerge = ptDepthFlowInfo->tDepthUtiDebugInfo.ValidQmerge; + if (ValidQmerge) + misp_info("QMerge table updated by AP: %d. (Received)", ValidQmerge); + else + misp_info("QMerge table updated by AP: %d. (No updated)", ValidQmerge); + + /* Dynamic warping */ + misp_info("Dynamic warping updated or not: %d.", + ptDepthFlowInfo->tDepthUtiDebugInfo.DWUpdated); +UtilityEnd: + + misp_info("=== DepthFlowInfo: Packdata ==="); + if (ptDepthFlowInfo->tDepthPackdataDebugInfo.ValidDepthPacadataDebugInfo == false) { + misp_info("Packdata information all invalid."); + goto PackdataDebugInfoEnd; + } + + /* check AP download packdata to ISP or not */ + ValidPackdata = ptDepthFlowInfo->tDepthPackdataDebugInfo.ValidPackdata; + if (ValidPackdata) + misp_info("Valid Packdata=%d. (Packdata download completed.).", ValidPackdata); + else{ + misp_info("Valid Packdata=%d.", ValidPackdata); + misp_info("(Packdata doesn't be downloaded, depth qulity and flow may fail.)"); + } + + /* Disparity to distance table convert. */ + ValidDisparityToDistanceTable = ptDepthFlowInfo->tDepthPackdataDebugInfo.ValidDisparityToDistanceTable; + if (ValidDisparityToDistanceTable) + misp_info("Valid Disparity to Distance Table = %d. (Valid.).", ValidDisparityToDistanceTable); + else + misp_info("Valid Disparity to Distance Table = %d. (Table not ready, convet may fail).", + ValidDisparityToDistanceTable); + + /* High distortion rate flag */ + HighDistortionRateFlag = ptDepthFlowInfo->tDepthPackdataDebugInfo.HighDistortionRate; + if (HighDistortionRateFlag) + misp_info("High distortion rate flag: %d. (High distortion)", HighDistortionRateFlag); + else { + misp_info("High distortion rate flag: %d. (Low distortion)", HighDistortionRateFlag); + misp_info("(Warning! in current lib, high distortion rate flag should be 1."); + } + + /* Packdata usage index */ + PackdataIdxNormal = ptDepthFlowInfo->tDepthPackdataDebugInfo.PackdataNormalIdx; + PackdataIdxGround = ptDepthFlowInfo->tDepthPackdataDebugInfo.PackdataGroundIdx; + PackdataIdxRGB = ptDepthFlowInfo->tDepthPackdataDebugInfo.PackdataRGBIdx; + if ((PackdataIdxNormal <= 2) && (PackdataIdxNormal <= 2) && (PackdataIdxNormal <= 2)) + misp_info("Packdata index:(normal, ground, RGB) = (%d, %d, %d). (generally, it is (0,0,2))", + PackdataIdxNormal, PackdataIdxGround, PackdataIdxRGB); + else + misp_info("Packdata index:(normal, ground, RGB) = (%d, %d, %d). (error! valid value should 0~2)", + PackdataIdxNormal, PackdataIdxGround, PackdataIdxRGB); + + /* Global compensation */ + GlobalCompensation = ptDepthFlowInfo->tDepthPackdataDebugInfo.AbsoluteGlobalVal; + if (GlobalCompensation == GlobalCompensation_21 || GlobalCompensation == GlobalCompensation_36) + misp_info("Global Compensation value: %d. (valid value is %d or %d)", + GlobalCompensation, GlobalCompensation_21, GlobalCompensation_36); + else + misp_info("Global Compensation value: %d. (error! it should be %d or %d)", + GlobalCompensation, GlobalCompensation_21, GlobalCompensation_36); + + /* HwCoefficient */ + HwCoefficient = ptDepthFlowInfo->tDepthPackdataDebugInfo.HwCoefficient; + if (HwCoefficient == HwCoefficient_16) + misp_info("HW coefficient: %d. (valid value is %d)", HwCoefficient, HwCoefficient_16); + else + misp_info("HW coefficient: %d. (error! it should be %d)", HwCoefficient, HwCoefficient_16); + + /* index of high distrotion rate */ + HighDistortionIdx = ptDepthFlowInfo->tDepthPackdataDebugInfo.HighDistortionIdx; + if (HighDistortionIdx <= uwHighDistortionIdx_max) + misp_info("High distortion index: %d. (valid range 0~5)", HighDistortionIdx); + else + misp_info("High distortion index: %d. (error! if should be 0~5)", HighDistortionIdx); + + /* Packdata source */ + PackdataSrc = ptDepthFlowInfo->tDepthPackdataDebugInfo.PackdataSource; + if (PackdataSrc == DEPTHPACKDATA_SRC_CMD) + misp_info("Packdata source from AP: %d. (Received)", PackdataSrc); + else if (PackdataSrc == DEPTHPACKDATA_SRC_OTP) + misp_info("Packdata source from ISP reading OTP: %d.", PackdataSrc); + else + misp_info("Warning! packdata source from nowhere: %d. (Depth may fail)", PackdataSrc); + + /* WOI */ + WOI_x = ptDepthFlowInfo->tDepthPackdataDebugInfo.WOIMainXBase; + WOI_y = ptDepthFlowInfo->tDepthPackdataDebugInfo.WOIMainYBase; + WOI_w = ptDepthFlowInfo->tDepthPackdataDebugInfo.WOIMainXLength; + WOI_h = ptDepthFlowInfo->tDepthPackdataDebugInfo.WOIMainYLength; + Full_w = WOI_w + (WOI_x) * 2; + Full_h = WOI_h + (WOI_y) * 2; + misp_info("Main Camera WOI (x,y,w,h) = (%d, %d, %d, %d). (FullSize WxH = %dx%d)", + WOI_x, WOI_y, WOI_w, WOI_h, Full_w, Full_h); + + WOI_x = ptDepthFlowInfo->tDepthPackdataDebugInfo.WOISubXBase; + WOI_y = ptDepthFlowInfo->tDepthPackdataDebugInfo.WOISubYBase; + WOI_w = ptDepthFlowInfo->tDepthPackdataDebugInfo.WOISubXLength; + WOI_h = ptDepthFlowInfo->tDepthPackdataDebugInfo.WOISubYLength; + Full_w = WOI_w + (WOI_x) * 2; + Full_h = WOI_h + (WOI_y) * 2; + misp_info("Sub Camera WOI (x,y,w,h) = (%d, %d, %d, %d). (FullSize WxH = %dx%d)", + WOI_x, WOI_y, WOI_w, WOI_h, Full_w, Full_h); + + /* Sub can rectify left shift */ + misp_info("Short distance(cm): %d. (For sub-cam retify left shift)", + ptDepthFlowInfo->tDepthPackdataDebugInfo.SubCamRectShift); + + misp_info("IntrinsicK_Main[9] = %d, %d, %d, %d, %d, %d, %d, %d, %d.", + ptDepthFlowInfo->tDepthPackdataDebugInfo.IntrinsicK_Main[0], ptDepthFlowInfo->tDepthPackdataDebugInfo.IntrinsicK_Main[1], + ptDepthFlowInfo->tDepthPackdataDebugInfo.IntrinsicK_Main[2], ptDepthFlowInfo->tDepthPackdataDebugInfo.IntrinsicK_Main[3], + ptDepthFlowInfo->tDepthPackdataDebugInfo.IntrinsicK_Main[4], ptDepthFlowInfo->tDepthPackdataDebugInfo.IntrinsicK_Main[5], + ptDepthFlowInfo->tDepthPackdataDebugInfo.IntrinsicK_Main[6], ptDepthFlowInfo->tDepthPackdataDebugInfo.IntrinsicK_Main[7], + ptDepthFlowInfo->tDepthPackdataDebugInfo.IntrinsicK_Main[8]); + + /* check ALDU errcode */ + if (0 == ptDepthFlowInfo->tDepthPackdataDebugInfo.AlDUErrCode) + misp_info("alDU operation error code: 0x%X. (success)", ptDepthFlowInfo->tDepthPackdataDebugInfo.AlDUErrCode); + else { + misp_info("alDU operation fail, error code: 0x%X.", ptDepthFlowInfo->tDepthPackdataDebugInfo.AlDUErrCode); + switch (ptDepthFlowInfo->tDepthPackdataDebugInfo.AlDUErrCode) { + case 0x9001: + misp_info("alDU Buffer size too small."); + break; + case 0x9002: + misp_info("alDU Buffer is null."); + break; + case 0x9003: + misp_info("alDU Rse size too small."); + break; + case 0x9004: + misp_info("alDU Rse packdata invalid."); + break; + default: + misp_info("alDU Unkown error code."); + break; + } + } + + if (0 == ptDepthFlowInfo->tDepthPackdataDebugInfo.ConvertMatch) + misp_info("Packdata convert task process time doen't match alDU convert process time: %d.", + ptDepthFlowInfo->tDepthPackdataDebugInfo.ConvertMatch); + else + misp_info("Packdata convert task process time match alDU convert process time: %d.", + ptDepthFlowInfo->tDepthPackdataDebugInfo.ConvertMatch); + + misp_info("Packdata convert count: %d.", ptDepthFlowInfo->tDepthPackdataDebugInfo.ConvertCount); + misp_info("Normal mode rectify QP pingpong index: %d.", ptDepthFlowInfo->tDepthPackdataDebugInfo.NormalRectQPReadPingPongIdx); + + if (0 == ptDepthFlowInfo->tDepthFlowDebugInfo.DepthGroundType) { + if (ptDepthFlowInfo->tDepthPackdataDebugInfo.NormalRectQPReadPingPongIdx != + ((ptDepthFlowInfo->tDepthPackdataDebugInfo.ConvertCount + 1) % 2)) + misp_info("Normal QP buffer index invalid."); + else + misp_info("Normal QP buffer index valid."); + } +PackdataDebugInfoEnd: + + return; +} + +/** + *\brief log depth module debug info + *\param a_IsLog2File [In] 0: print to dmesg. 1: log to file. + *\return Error code + */ +errcode mini_isp_debug_depth_info(void) +{ + errcode errcode = ERR_SUCCESS; + u32 depthinfo_addr = 0; + u32 packdata_addr = 0; + u32 PackdataCheckSum = 0; + u8 *packdata_buffer = NULL; + DEPTHFLOWMGR_DEBUG_INFO tDepthFlowInfo = {0}; + + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + /* 1. read depth flow info structure addr */ + mini_isp_memory_read(DEBUG_INFO_DEPTH_FLOW_INFO_ADDR, (u8 *)&depthinfo_addr, 4); + if (depthinfo_addr == 0) { + misp_info("read depth info addr fail! L:%d", __LINE__); + goto EXIT; + } + + /* 2. read depth flow info structure context */ + mini_isp_memory_read(depthinfo_addr, (u8 *)&tDepthFlowInfo, + sizeof(DEPTHFLOWMGR_DEBUG_INFO)); + + /* 3. show depth flow info */ + mini_isp_debug_depth_info_parser(&tDepthFlowInfo); + + /* 4. check packdata checksum */ + packdata_addr = tDepthFlowInfo.tDepthPackdataDebugInfo.PackdataAddr; + misp_info("Packdata address: 0x%X.", packdata_addr); + + packdata_buffer = kzalloc(PACKDATA_SIZE, GFP_KERNEL); + if (packdata_buffer != NULL) { + mini_isp_memory_read(packdata_addr, packdata_buffer, PACKDATA_SIZE); + PackdataCheckSum = CalculatePackdataCheckSum(packdata_buffer); + if (PackdataCheckSum == tDepthFlowInfo.tDepthPackdataDebugInfo.PackdataChkSum) + misp_info("Packdata check sum: 0x%X. (equal tool).", tDepthFlowInfo.tDepthPackdataDebugInfo.PackdataChkSum); + else + misp_info("Packdata check fail: ISP:0x%X. Tool:0x%X.", tDepthFlowInfo.tDepthPackdataDebugInfo.PackdataChkSum, PackdataCheckSum); + + kfree(packdata_buffer); + } else{ + misp_info("allocate packdata buffer fail!"); + } + +EXIT: + if (dev_global_variable->intf_status & INTF_SPI_READY && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return errcode; +} +EXPORT_SYMBOL(mini_isp_debug_depth_info); + +static void mini_isp_debug_metadata_parser(CAPFLOWMGR_METADATA *ptMetadata) +{ + u64 DualPathFrameSyncTimeDiff = 0; + + if (ptMetadata == NULL) { + misp_info("%s fail!", __func__); + return; + } + misp_info("=============== Metadata ==============="); + misp_info("---=== Metadata:Common ===----"); + misp_info("Metadata version: %d.", ptMetadata->tCommonInfo.MetaDataVer); + misp_info("SCID: %d.", ptMetadata->tCommonInfo.SCID); + misp_info("Swap(Rx,Tx): (%d,%d).", ptMetadata->tCommonInfo.RxSwap, ptMetadata->tCommonInfo.TxSwap); + misp_info("SensorType: %d.", ptMetadata->tCommonInfo.SensorType); + misp_info("HDR (PPIdx, LPPw, LPPh, RPPw, RPPh): (%d,%d,%d,%d,%d).", + ptMetadata->tCommonInfo.HDRPPPipeIdx, ptMetadata->tCommonInfo.LPPWidth, + ptMetadata->tCommonInfo.LPPHeight, ptMetadata->tCommonInfo.RPPWidth, + ptMetadata->tCommonInfo.RPPHeight); + + misp_info("---=== Metadata:PIPE0 Info ===----"); + + misp_info("Frame Index: %d.", ptMetadata->tPipe0Info.FrameIndex); + misp_info("SrcImg (width, height, ColorOrder): (%d, %d, %d).", + ptMetadata->tPipe0Info.SrcImgWidth, ptMetadata->tPipe0Info.SrcImgHeight, + ptMetadata->tPipe0Info.ColorOrder); + misp_info("(ExpTime, wBV): (%d, %d).", ptMetadata->tPipe0Info.ExpTime, ptMetadata->tPipe0Info.BV); + misp_info("(ISO, ADGain): (%d, %d).", ptMetadata->tPipe0Info.ISO, ptMetadata->tPipe0Info.AD_Gain); + misp_info("AWBGain(R,G,B): (%d, %d, %d).", ptMetadata->tPipe0Info.AWB_RGain, + ptMetadata->tPipe0Info.AWB_GGain, ptMetadata->tPipe0Info.AWB_BGain); + misp_info("BlkOst(R,G,B): (%d, %d, %d).", ptMetadata->tPipe0Info.BlackOffset_R, + ptMetadata->tPipe0Info.BlackOffset_G, ptMetadata->tPipe0Info.BlackOffset_B); + misp_info("Crop(x,y,w,h): (%d, %d, %d, %d).", ptMetadata->tPipe0Info.Crop_X, + ptMetadata->tPipe0Info.Crop_Y, ptMetadata->tPipe0Info.Crop_Width, + ptMetadata->tPipe0Info.Crop_Height); + misp_info("Scalar(w,h): (%d, %d).", ptMetadata->tPipe0Info.ScalarWidth, + ptMetadata->tPipe0Info.ScalarHeight); + misp_info("VCM(macro,infinity,curStep,status): (%d, %d, %d, %d).", + ptMetadata->tPipe0Info.VCM_macro, ptMetadata->tPipe0Info.VCM_infinity, + ptMetadata->tPipe0Info.VCM_CurStep, ptMetadata->tPipe0Info.Depth_VCMStatus); + + misp_info("---=== Metadata:PIPE1 Info ===----"); + misp_info("Frame Index: %d.", ptMetadata->tPipe1Info.FrameIndex); + misp_info("SrcImg (width, height, ColorOrder): (%d, %d, %d).", ptMetadata->tPipe1Info.SrcImgWidth, + ptMetadata->tPipe1Info.SrcImgHeight, ptMetadata->tPipe1Info.ColorOrder); + misp_info("(ExpTime, wBV): (%d, %d).", ptMetadata->tPipe1Info.ExpTime, ptMetadata->tPipe1Info.BV); + misp_info("(ISO, ADGain): (%d, %d).", ptMetadata->tPipe1Info.ISO, ptMetadata->tPipe1Info.AD_Gain); + misp_info("AWBGain(R,G,B): (%d, %d, %d).", ptMetadata->tPipe1Info.AWB_RGain, + ptMetadata->tPipe1Info.AWB_GGain, ptMetadata->tPipe1Info.AWB_BGain); + misp_info("BlkOst(R,G,B): (%d, %d, %d).", ptMetadata->tPipe1Info.BlackOffset_R, + ptMetadata->tPipe1Info.BlackOffset_G, ptMetadata->tPipe1Info.BlackOffset_B); + misp_info("Crop(x,y,w,h): (%d, %d, %d, %d).", ptMetadata->tPipe1Info.Crop_X, + ptMetadata->tPipe1Info.Crop_Y, ptMetadata->tPipe1Info.Crop_Width, + ptMetadata->tPipe1Info.Crop_Height); + misp_info("Scalar(w,h): (%d, %d).", ptMetadata->tPipe1Info.ScalarWidth, + ptMetadata->tPipe1Info.ScalarHeight); + misp_info("VCM(macro,infinity,curStep,status): (%d, %d, %d, %d).", + ptMetadata->tPipe1Info.VCM_macro, ptMetadata->tPipe1Info.VCM_infinity, + ptMetadata->tPipe1Info.VCM_CurStep, ptMetadata->tPipe1Info.Depth_VCMStatus); + + misp_info("---=== Metadata:Depth Info ===----"); + misp_info("Depth index: %d.", ptMetadata->tDpethInfo.DepthIndex); + misp_info("Reference Frame Index: %d.", ptMetadata->tDpethInfo.ReferenceFrameIndex); + misp_info("Depth(w,h,type) = (%d, %d, %d).", ptMetadata->tDpethInfo.DepthWidth, + ptMetadata->tDpethInfo.DepthHeight, ptMetadata->tDpethInfo.DepthType); + misp_info("VCM Step = (%d, %d).", ptMetadata->tDpethInfo.awDepth_VCMStep[0], + ptMetadata->tDpethInfo.awDepth_VCMStep[1]); + + misp_info("---=== Metadata:SWDebug ===----"); + misp_info("ModuleBypass[0~ 5]: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X.", + ptMetadata->tSWDebugInfo.aucModuleByPass[0], ptMetadata->tSWDebugInfo.aucModuleByPass[1], + ptMetadata->tSWDebugInfo.aucModuleByPass[2], ptMetadata->tSWDebugInfo.aucModuleByPass[3], + ptMetadata->tSWDebugInfo.aucModuleByPass[4], ptMetadata->tSWDebugInfo.aucModuleByPass[5]); + misp_info("ModuleBypass[6~12]: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X.", + ptMetadata->tSWDebugInfo.aucModuleByPass[6], ptMetadata->tSWDebugInfo.aucModuleByPass[7], + ptMetadata->tSWDebugInfo.aucModuleByPass[8], ptMetadata->tSWDebugInfo.aucModuleByPass[9], + ptMetadata->tSWDebugInfo.aucModuleByPass[10], ptMetadata->tSWDebugInfo.aucModuleByPass[11]); + misp_info("DepthInSize: %dx%d.", ptMetadata->tSWDebugInfo.DepthInWidth, + ptMetadata->tSWDebugInfo.DepthInHeight); + misp_info("Pipe0Shading (w,h,inw,inh,woix,woiy,woiw,woih): (%d, %d, %d, %d, %d, %d, %d, %d).", + ptMetadata->tSWDebugInfo.tPipeSHDInfo[0].SHDTableW, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[0].SHDTableH, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[0].SHDNoWOIOutWidth, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[0].SHDNoWOIOutHeight, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[0].SHD_WOI_X, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[0].SHD_WOI_Y, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[0].SHD_WOI_Width, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[0].SHD_WOI_Height); + misp_info("Pipe1Shading (w,h,inw,inh,woix,woiy,woiw,woih): (%d, %d, %d, %d, %d, %d, %d, %d).", + ptMetadata->tSWDebugInfo.tPipeSHDInfo[1].SHDTableW, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[1].SHDTableH, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[1].SHDNoWOIOutWidth, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[1].SHDNoWOIOutHeight, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[1].SHD_WOI_X, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[1].SHD_WOI_Y, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[1].SHD_WOI_Width, + ptMetadata->tSWDebugInfo.tPipeSHDInfo[1].SHD_WOI_Height); + misp_info("Pipe0DepthCalibWOI (x,y,w,h): (%d, %d, %d, %d).", + ptMetadata->tSWDebugInfo.tPipeDepthCaliWOI[0].XBase, + ptMetadata->tSWDebugInfo.tPipeDepthCaliWOI[0].YBase, + ptMetadata->tSWDebugInfo.tPipeDepthCaliWOI[0].XLength, + ptMetadata->tSWDebugInfo.tPipeDepthCaliWOI[0].YLength); + misp_info("Pipe1DepthCalibWOI (x,y,w,h): (%d, %d, %d, %d).", + ptMetadata->tSWDebugInfo.tPipeDepthCaliWOI[1].XBase, + ptMetadata->tSWDebugInfo.tPipeDepthCaliWOI[1].YBase, + ptMetadata->tSWDebugInfo.tPipeDepthCaliWOI[1].XLength, + ptMetadata->tSWDebugInfo.tPipeDepthCaliWOI[1].YLength); + misp_info("SysTime(us): %llu us.", ptMetadata->tSWDebugInfo.SysTimeus); + misp_info("ProjectorStatus[0] (on/off, level): (%d, %d).", + ptMetadata->tSWDebugInfo.tProjectorStatus[0].TurnOn, + ptMetadata->tSWDebugInfo.tProjectorStatus[0].Level); + misp_info("ProjectorStatus[1] (on/off, level): (%d, %d).", + ptMetadata->tSWDebugInfo.tProjectorStatus[1].TurnOn, + ptMetadata->tSWDebugInfo.tProjectorStatus[1].Level); + misp_info("ProjectorStatus[2] (on/off, level): (%d, %d).", + ptMetadata->tSWDebugInfo.tProjectorStatus[2].TurnOn, + ptMetadata->tSWDebugInfo.tProjectorStatus[2].Level); + misp_info("ProjectorStatus[3] (on/off, level): (%d, %d).", + ptMetadata->tSWDebugInfo.tProjectorStatus[3].TurnOn, + ptMetadata->tSWDebugInfo.tProjectorStatus[3].Level); + misp_info("ProjectorStatus[4] (on/off, level): (%d, %d).", + ptMetadata->tSWDebugInfo.tProjectorStatus[4].TurnOn, + ptMetadata->tSWDebugInfo.tProjectorStatus[4].Level); + misp_info("ProjectorStatus[5] (on/off, level): (%d, %d).", + ptMetadata->tSWDebugInfo.tProjectorStatus[5].TurnOn, + ptMetadata->tSWDebugInfo.tProjectorStatus[5].Level); + misp_info("ProjectorStatus[6] (on/off, level): (%d, %d).", + ptMetadata->tSWDebugInfo.tProjectorStatus[6].TurnOn, + ptMetadata->tSWDebugInfo.tProjectorStatus[6].Level); + misp_info("ProjectorStatus[7] (on/off, level): (%d, %d).", + ptMetadata->tSWDebugInfo.tProjectorStatus[7].TurnOn, + ptMetadata->tSWDebugInfo.tProjectorStatus[7].Level); + misp_info("GPIO_Dev on/off: (Dev0, Dev1) = (%d, %d).", + ptMetadata->tSWDebugInfo.tGPIO_Device[0].TurnOn, + ptMetadata->tSWDebugInfo.tGPIO_Device[1].TurnOn); + misp_info("IDD0_ISRTimeus: %llu us.", ptMetadata->tSWDebugInfo.IDD0_ISRTimeus); + misp_info("IDD1_ISRTimeus: %llu us.", ptMetadata->tSWDebugInfo.IDD1_ISRTimeus); + +#ifdef NEW_ABS + DualPathFrameSyncTimeDiff = + abs((s64)(ptMetadata->tSWDebugInfo.IDD1_ISRTimeus - ptMetadata->tSWDebugInfo.IDD0_ISRTimeus)); +#else + DualPathFrameSyncTimeDiff = + abs64((s64)(ptMetadata->tSWDebugInfo.IDD1_ISRTimeus - ptMetadata->tSWDebugInfo.IDD0_ISRTimeus)); +#endif + + misp_info("DualPathFrameSyncTimeDiff: %llu us.", DualPathFrameSyncTimeDiff); + + misp_info("---=== Metadata:IQDebug ===----"); + misp_info("QMerge_Ver: %d.", ptMetadata->tIQDebugInfo.Qmerge_Ver); + misp_info("Tool_Ver: %d. %d .%d.", ptMetadata->tIQDebugInfo.audTool_Ver[0], + ptMetadata->tIQDebugInfo.audTool_Ver[1], ptMetadata->tIQDebugInfo.audTool_Ver[2]); + misp_info("audTuning_Ver: %d. %d .%d.", ptMetadata->tIQDebugInfo.audTuning_Ver[0], + ptMetadata->tIQDebugInfo.audTuning_Ver[1], ptMetadata->tIQDebugInfo.audTuning_Ver[2]); + misp_info("Verify Debug: %d. %d.", ptMetadata->tIQDebugInfo.aucVerifyDebug[0], + ptMetadata->tIQDebugInfo.aucVerifyDebug[1]); + misp_info("2PDInfo: %d.", ptMetadata->tIQDebugInfo.uw2PD_Info); + misp_info("EngineEnable: %d. %d. %d. %d. %d. %d. %d. %d.", + ptMetadata->tIQDebugInfo.aucEngineEnable[0], ptMetadata->tIQDebugInfo.aucEngineEnable[1], + ptMetadata->tIQDebugInfo.aucEngineEnable[2], ptMetadata->tIQDebugInfo.aucEngineEnable[3], + ptMetadata->tIQDebugInfo.aucEngineEnable[4], ptMetadata->tIQDebugInfo.aucEngineEnable[5], + ptMetadata->tIQDebugInfo.aucEngineEnable[6], ptMetadata->tIQDebugInfo.aucEngineEnable[7]); + misp_info("CCM[0]: %d. %d. %d. %d. %d. %d. %d. %d. %d.", ptMetadata->tIQDebugInfo.awCCM[0][0], + ptMetadata->tIQDebugInfo.awCCM[0][1], ptMetadata->tIQDebugInfo.awCCM[0][2], + ptMetadata->tIQDebugInfo.awCCM[0][3], ptMetadata->tIQDebugInfo.awCCM[0][4], + ptMetadata->tIQDebugInfo.awCCM[0][5], ptMetadata->tIQDebugInfo.awCCM[0][6], + ptMetadata->tIQDebugInfo.awCCM[0][7], ptMetadata->tIQDebugInfo.awCCM[0][8]); + misp_info("CCM[1]: %d. %d. %d .%d. %d. %d. %d. %d. %d.", ptMetadata->tIQDebugInfo.awCCM[1][0], + ptMetadata->tIQDebugInfo.awCCM[1][1], ptMetadata->tIQDebugInfo.awCCM[1][2], + ptMetadata->tIQDebugInfo.awCCM[1][3], ptMetadata->tIQDebugInfo.awCCM[1][4], + ptMetadata->tIQDebugInfo.awCCM[1][5], ptMetadata->tIQDebugInfo.awCCM[1][6], + ptMetadata->tIQDebugInfo.awCCM[1][7], ptMetadata->tIQDebugInfo.awCCM[1][8]); + misp_info("ExpRatio: %d.", ptMetadata->tIQDebugInfo.ExpRatio); + misp_info("ParaAddr[0][ 0~ 9]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[0][0], ptMetadata->tIQDebugInfo.audParaAddr[0][1], + ptMetadata->tIQDebugInfo.audParaAddr[0][2], ptMetadata->tIQDebugInfo.audParaAddr[0][3], + ptMetadata->tIQDebugInfo.audParaAddr[0][4], ptMetadata->tIQDebugInfo.audParaAddr[0][5], + ptMetadata->tIQDebugInfo.audParaAddr[0][6], ptMetadata->tIQDebugInfo.audParaAddr[0][7], + ptMetadata->tIQDebugInfo.audParaAddr[0][8], ptMetadata->tIQDebugInfo.audParaAddr[0][9]); + misp_info("ParaAddr[0][10~19]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[0][10], ptMetadata->tIQDebugInfo.audParaAddr[0][11], + ptMetadata->tIQDebugInfo.audParaAddr[0][12], ptMetadata->tIQDebugInfo.audParaAddr[0][13], + ptMetadata->tIQDebugInfo.audParaAddr[0][14], ptMetadata->tIQDebugInfo.audParaAddr[0][15], + ptMetadata->tIQDebugInfo.audParaAddr[0][16], ptMetadata->tIQDebugInfo.audParaAddr[0][17], + ptMetadata->tIQDebugInfo.audParaAddr[0][18], ptMetadata->tIQDebugInfo.audParaAddr[0][19]); + misp_info("ParaAddr[0][20~29]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[0][20], ptMetadata->tIQDebugInfo.audParaAddr[0][21], + ptMetadata->tIQDebugInfo.audParaAddr[0][22], ptMetadata->tIQDebugInfo.audParaAddr[0][23], + ptMetadata->tIQDebugInfo.audParaAddr[0][24], ptMetadata->tIQDebugInfo.audParaAddr[0][25], + ptMetadata->tIQDebugInfo.audParaAddr[0][26], ptMetadata->tIQDebugInfo.audParaAddr[0][27], + ptMetadata->tIQDebugInfo.audParaAddr[0][28], ptMetadata->tIQDebugInfo.audParaAddr[0][29]); + misp_info("ParaAddr[0][30~39]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[0][30], ptMetadata->tIQDebugInfo.audParaAddr[0][31], + ptMetadata->tIQDebugInfo.audParaAddr[0][32], ptMetadata->tIQDebugInfo.audParaAddr[0][33], + ptMetadata->tIQDebugInfo.audParaAddr[0][34], ptMetadata->tIQDebugInfo.audParaAddr[0][35], + ptMetadata->tIQDebugInfo.audParaAddr[0][36], ptMetadata->tIQDebugInfo.audParaAddr[0][37], + ptMetadata->tIQDebugInfo.audParaAddr[0][38], ptMetadata->tIQDebugInfo.audParaAddr[0][39]); + misp_info("ParaAddr[0][40~49]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[0][40], ptMetadata->tIQDebugInfo.audParaAddr[0][41], + ptMetadata->tIQDebugInfo.audParaAddr[0][42], ptMetadata->tIQDebugInfo.audParaAddr[0][43], + ptMetadata->tIQDebugInfo.audParaAddr[0][44], ptMetadata->tIQDebugInfo.audParaAddr[0][45], + ptMetadata->tIQDebugInfo.audParaAddr[0][46], ptMetadata->tIQDebugInfo.audParaAddr[0][47], + ptMetadata->tIQDebugInfo.audParaAddr[0][48], ptMetadata->tIQDebugInfo.audParaAddr[0][49]); + misp_info("ParaAddr[0][50~59]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[0][50], ptMetadata->tIQDebugInfo.audParaAddr[0][51], + ptMetadata->tIQDebugInfo.audParaAddr[0][52], ptMetadata->tIQDebugInfo.audParaAddr[0][53], + ptMetadata->tIQDebugInfo.audParaAddr[0][54], ptMetadata->tIQDebugInfo.audParaAddr[0][55], + ptMetadata->tIQDebugInfo.audParaAddr[0][56], ptMetadata->tIQDebugInfo.audParaAddr[0][57], + ptMetadata->tIQDebugInfo.audParaAddr[0][58], ptMetadata->tIQDebugInfo.audParaAddr[0][59]); + misp_info("ParaAddr[0][60~69]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[0][60], ptMetadata->tIQDebugInfo.audParaAddr[0][61], + ptMetadata->tIQDebugInfo.audParaAddr[0][62], ptMetadata->tIQDebugInfo.audParaAddr[0][63], + ptMetadata->tIQDebugInfo.audParaAddr[0][64], ptMetadata->tIQDebugInfo.audParaAddr[0][65], + ptMetadata->tIQDebugInfo.audParaAddr[0][66], ptMetadata->tIQDebugInfo.audParaAddr[0][67], + ptMetadata->tIQDebugInfo.audParaAddr[0][68], ptMetadata->tIQDebugInfo.audParaAddr[0][69]); + misp_info("ParaAddr[0][70~79]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[0][70], ptMetadata->tIQDebugInfo.audParaAddr[0][71], + ptMetadata->tIQDebugInfo.audParaAddr[0][72], ptMetadata->tIQDebugInfo.audParaAddr[0][73], + ptMetadata->tIQDebugInfo.audParaAddr[0][74], ptMetadata->tIQDebugInfo.audParaAddr[0][75], + ptMetadata->tIQDebugInfo.audParaAddr[0][76], ptMetadata->tIQDebugInfo.audParaAddr[0][77], + ptMetadata->tIQDebugInfo.audParaAddr[0][78], ptMetadata->tIQDebugInfo.audParaAddr[0][79]); + misp_info("ParaAddr[1][ 0~ 9]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[1][0], ptMetadata->tIQDebugInfo.audParaAddr[1][1], + ptMetadata->tIQDebugInfo.audParaAddr[1][2], ptMetadata->tIQDebugInfo.audParaAddr[1][3], + ptMetadata->tIQDebugInfo.audParaAddr[1][4], ptMetadata->tIQDebugInfo.audParaAddr[1][5], + ptMetadata->tIQDebugInfo.audParaAddr[1][6], ptMetadata->tIQDebugInfo.audParaAddr[1][7], + ptMetadata->tIQDebugInfo.audParaAddr[1][8], ptMetadata->tIQDebugInfo.audParaAddr[1][9]); + misp_info("ParaAddr[1][10~19]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[1][10], ptMetadata->tIQDebugInfo.audParaAddr[1][11], + ptMetadata->tIQDebugInfo.audParaAddr[1][12], ptMetadata->tIQDebugInfo.audParaAddr[1][13], + ptMetadata->tIQDebugInfo.audParaAddr[1][14], ptMetadata->tIQDebugInfo.audParaAddr[1][15], + ptMetadata->tIQDebugInfo.audParaAddr[1][16], ptMetadata->tIQDebugInfo.audParaAddr[1][17], + ptMetadata->tIQDebugInfo.audParaAddr[1][18], ptMetadata->tIQDebugInfo.audParaAddr[1][19]); + misp_info("ParaAddr[1][20~29]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[1][20], ptMetadata->tIQDebugInfo.audParaAddr[1][21], + ptMetadata->tIQDebugInfo.audParaAddr[1][22], ptMetadata->tIQDebugInfo.audParaAddr[1][23], + ptMetadata->tIQDebugInfo.audParaAddr[1][24], ptMetadata->tIQDebugInfo.audParaAddr[1][25], + ptMetadata->tIQDebugInfo.audParaAddr[1][26], ptMetadata->tIQDebugInfo.audParaAddr[1][27], + ptMetadata->tIQDebugInfo.audParaAddr[1][28], ptMetadata->tIQDebugInfo.audParaAddr[1][29]); + misp_info("ParaAddr[1][30~39]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[1][30], ptMetadata->tIQDebugInfo.audParaAddr[1][31], + ptMetadata->tIQDebugInfo.audParaAddr[1][32], ptMetadata->tIQDebugInfo.audParaAddr[1][33], + ptMetadata->tIQDebugInfo.audParaAddr[1][34], ptMetadata->tIQDebugInfo.audParaAddr[1][35], + ptMetadata->tIQDebugInfo.audParaAddr[1][36], ptMetadata->tIQDebugInfo.audParaAddr[1][37], + ptMetadata->tIQDebugInfo.audParaAddr[1][38], ptMetadata->tIQDebugInfo.audParaAddr[1][39]); + misp_info("ParaAddr[1][40~49]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[1][40], ptMetadata->tIQDebugInfo.audParaAddr[1][41], + ptMetadata->tIQDebugInfo.audParaAddr[1][42], ptMetadata->tIQDebugInfo.audParaAddr[1][43], + ptMetadata->tIQDebugInfo.audParaAddr[1][44], ptMetadata->tIQDebugInfo.audParaAddr[1][45], + ptMetadata->tIQDebugInfo.audParaAddr[1][46], ptMetadata->tIQDebugInfo.audParaAddr[1][47], + ptMetadata->tIQDebugInfo.audParaAddr[1][48], ptMetadata->tIQDebugInfo.audParaAddr[1][49]); + misp_info("ParaAddr[1][50~59]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[1][50], ptMetadata->tIQDebugInfo.audParaAddr[1][51], + ptMetadata->tIQDebugInfo.audParaAddr[1][52], ptMetadata->tIQDebugInfo.audParaAddr[1][53], + ptMetadata->tIQDebugInfo.audParaAddr[1][54], ptMetadata->tIQDebugInfo.audParaAddr[1][55], + ptMetadata->tIQDebugInfo.audParaAddr[1][56], ptMetadata->tIQDebugInfo.audParaAddr[1][57], + ptMetadata->tIQDebugInfo.audParaAddr[1][58], ptMetadata->tIQDebugInfo.audParaAddr[1][59]); + misp_info("ParaAddr[1][60~69]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[1][60], ptMetadata->tIQDebugInfo.audParaAddr[1][61], + ptMetadata->tIQDebugInfo.audParaAddr[1][62], ptMetadata->tIQDebugInfo.audParaAddr[1][63], + ptMetadata->tIQDebugInfo.audParaAddr[1][64], ptMetadata->tIQDebugInfo.audParaAddr[1][65], + ptMetadata->tIQDebugInfo.audParaAddr[1][66], ptMetadata->tIQDebugInfo.audParaAddr[1][67], + ptMetadata->tIQDebugInfo.audParaAddr[1][68], ptMetadata->tIQDebugInfo.audParaAddr[1][69]); + misp_info("ParaAddr[1][70~79]: 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x. 0x%x.", + ptMetadata->tIQDebugInfo.audParaAddr[1][70], ptMetadata->tIQDebugInfo.audParaAddr[1][71], + ptMetadata->tIQDebugInfo.audParaAddr[1][72], ptMetadata->tIQDebugInfo.audParaAddr[1][73], + ptMetadata->tIQDebugInfo.audParaAddr[1][74], ptMetadata->tIQDebugInfo.audParaAddr[1][75], + ptMetadata->tIQDebugInfo.audParaAddr[1][76], ptMetadata->tIQDebugInfo.audParaAddr[1][77], + ptMetadata->tIQDebugInfo.audParaAddr[1][78], ptMetadata->tIQDebugInfo.audParaAddr[1][79]); + + misp_info("---=== Metadata:Histogram ===----"); + misp_info("Hist_S[256~259]: [%d. %d. %d. %d].", + ptMetadata->audHDRAEHistogram_Short[256], ptMetadata->audHDRAEHistogram_Short[257], + ptMetadata->audHDRAEHistogram_Short[258], ptMetadata->audHDRAEHistogram_Short[259]); + misp_info("Hist_L[256~259]: [%d. %d. %d. %d].", ptMetadata->audHDRAEHistogram_Long[256], + ptMetadata->audHDRAEHistogram_Long[257], ptMetadata->audHDRAEHistogram_Long[258], + ptMetadata->audHDRAEHistogram_Long[259]); + +} + +/** + *\brief log metadata status + *\param a_IsLog2File [In] 0: print to dmesg. 1: log to file. + *\return Error code + */ +errcode mini_isp_debug_metadata_info(void) +{ + errcode errcode = ERR_SUCCESS; + u32 metadata_addr; + CAPFLOWMGR_METADATA *ptMetadata = NULL; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + /* 1. read metadata structure addr */ + mini_isp_memory_read(DEBUG_INFO_METADATA_ADDR, (u8 *)&metadata_addr, 4); + if (metadata_addr == 0) { + misp_info("read meta data addr fail! L:%d", __LINE__); + goto EXIT; + } + + /* 2. allocate metadata buffer */ + ptMetadata = kzalloc(sizeof(CAPFLOWMGR_METADATA), GFP_KERNEL); + if (ptMetadata == NULL) { + errcode = -ENOMEM; + misp_info("allocate metadata buffer fail!"); + goto EXIT; + } + /* 3. read metadata structure context */ + mini_isp_memory_read(metadata_addr, (u8 *)ptMetadata, + sizeof(CAPFLOWMGR_METADATA)); + + /* 4. show metadata context */ + mini_isp_debug_metadata_parser(ptMetadata); + + /* 5. free metadata buffer */ + kfree(ptMetadata); +EXIT: + if (dev_global_variable->intf_status & INTF_SPI_READY && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return errcode; +} +EXPORT_SYMBOL(mini_isp_debug_metadata_info); + +static void mini_isp_debug_sensor_info_parser( + FEC_SENSOR_REAL_INFO atRealSensorInfo[], + u8 sensor_info_num, bool a_IsLog2File) +{ + u8 i = 0; + u32 ret = 0; + char *LogBuffer = NULL; + char filename[128]; + struct file *fp = NULL; + mm_segment_t fs = {0}; + u32 CurLogSize = 0; + + u64 SysTimeNow_ns, SysTimeNow_sec, Temp_u64; + + if (atRealSensorInfo == NULL) { + misp_info("%s fail!", __func__); + goto EXIT; + } + + if (a_IsLog2File) { + /* 200KB enougth for two hours */ + LogBuffer = kzalloc(LOG_BUF_SIZE, GFP_KERNEL); + if (LogBuffer == NULL) { + ret = -ENOMEM; + misp_err("%s, LogBuffer allocate fail", __func__); + goto EXIT; + } + + ret = mini_isp_create_directory(MINIISP_INFO_DUMPLOCATION); + + snprintf(filename, 128, "%s/sensor_info_log", + MINIISP_INFO_DUMPLOCATION); + #if ENABLE_FILP_OPEN_API + /* use file open */ + #else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + goto EXIT; + #endif + /*Get current segment descriptor*/ + fs = get_fs(); + + /*Set segment descriptor associated*/ + set_fs(get_ds()); + + if (IS_ERR(fp)) { + ret = PTR_ERR(fp); + set_fs(fs); + misp_err("%s open file failed. err: %d", __func__, ret); + goto EXIT; + } + + /* get linux system time */ + SysTimeNow_ns = local_clock(); + SysTimeNow_sec = SysTimeNow_ns; + SysTimeNow_ns = do_div(SysTimeNow_sec, 1000000000); + Temp_u64 = SysTimeNow_ns; + do_div(Temp_u64, 1000); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "SysTime: [%5lld.%06lld]\n", + SysTimeNow_sec, Temp_u64); + + for (i = 0; i < sensor_info_num; i++) { + /* LogBuffer full, write the file */ + if (CurLogSize + 512 > LOG_BUF_SIZE) { + vfs_write(fp, (char *)LogBuffer, CurLogSize, &fp->f_pos); + CurLogSize = 0; + } + + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "=============== Sensor Real Info ===============\n"); + + for (i = 0; i < sensor_info_num; i++) { + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, "---=== Sensor %d ===----\n", i); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, "VTS: %d\n", atRealSensorInfo[i].VTS); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, "HTS: %d\n", atRealSensorInfo[i].HTS); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "ImageWidth: %d\n", atRealSensorInfo[i].ImageWidth); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "ImageHeight: %d\n", atRealSensorInfo[i].ImageHeight); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "FrameTime: %d us\n", atRealSensorInfo[i].FrameTime); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "FrameRate: %d.%d fps\n", + atRealSensorInfo[i].FrameRate/100, atRealSensorInfo[i].FrameRate % 100); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "ExpTime: %d us\n", atRealSensorInfo[i].ExpTime); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "Gain: %d.%dx\n", atRealSensorInfo[i].Gain/100, atRealSensorInfo[i].Gain % 100); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "Mode: %d. (0~2: normal, master, slave)\n", atRealSensorInfo[i].SensorMode); + } + } + + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, "\n"); + + /* save final Log */ + vfs_write(fp, (char *)LogBuffer, CurLogSize, &fp->f_pos); + + /*Restore segment descriptor*/ + set_fs(fs); + filp_close(fp, NULL); + + } else { + /* print to dmesg */ + misp_info("=============== Sensor Real Info ==============="); + for (i = 0; i < sensor_info_num; i++) { + misp_info("---=== Sensor %d ===----", i); + misp_info("VTS: %d.", atRealSensorInfo[i].VTS); + misp_info("HTS: %d.", atRealSensorInfo[i].HTS); + misp_info("ImageWidth: %d.", atRealSensorInfo[i].ImageWidth); + misp_info("ImageHeight: %d.", atRealSensorInfo[i].ImageHeight); + misp_info("FrameTime: %d us.", atRealSensorInfo[i].FrameTime); + + misp_info("FrameRate: %d.%d fps.", atRealSensorInfo[i].FrameRate/100, + atRealSensorInfo[i].FrameRate % 100); + misp_info("ExpTime: %d us.", atRealSensorInfo[i].ExpTime); + misp_info("Gain: %d.%dx.", atRealSensorInfo[i].Gain/100, atRealSensorInfo[i].Gain % 100); + misp_info("Mode: %d. (0~2: normal, master, slave)", atRealSensorInfo[i].SensorMode); + } + } + +EXIT: + if (LogBuffer != NULL) + kfree(LogBuffer); + return; +} + +/** + *\brief log sensor status + *\param a_IsLog2File [In] 0: print to dmesg. 1: log to file. + *\return Error code + */ +errcode mini_isp_debug_sensor_info(bool a_IsLog2File) +{ + errcode errcode = ERR_SUCCESS; + u32 SensorInfo_addr = 0; + FEC_SENSOR_REAL_INFO atRealSensorInfo[2]; + u8 write_buffer[4]; + u8 sensor_info_num = 1; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + sensor_info_num = sizeof(atRealSensorInfo) / sizeof(FEC_SENSOR_REAL_INFO); + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + /* 1. active ISP front-end debug mode. AL6100 stop AEC control */ + write_buffer[0] = 1; + mini_isp_memory_write(DEBUG_INFO_FEC_DEBUG_MODE_ADDR, write_buffer, 1); + msleep(300); + + /* 2. read Sensor Info addr */ + mini_isp_memory_read(DEBUG_INFO_SENSOR_REAL_INFO_ADDR, (u8 *)&SensorInfo_addr, 4); + if (SensorInfo_addr == 0) { + misp_info("read SensorInfo addr fail! L:%d", __LINE__); + goto EXIT; + } + + /* 3. read sensor info context */ + mini_isp_memory_read(SensorInfo_addr, (u8 *)atRealSensorInfo, sizeof(atRealSensorInfo)); + + + /* 4. close ISP front-end debug mode. */ + write_buffer[0] = 0; + mini_isp_memory_write(DEBUG_INFO_FEC_DEBUG_MODE_ADDR, write_buffer, 1); + + /* 5. show sensor info context */ + mini_isp_debug_sensor_info_parser(atRealSensorInfo, sensor_info_num, a_IsLog2File); + +EXIT: + if (dev_global_variable->intf_status & INTF_SPI_READY && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return errcode; +} +EXPORT_SYMBOL(mini_isp_debug_sensor_info); + +static void mini_isp_debug_led_info_parser( + PROJECTOR_INFO atLED_INFO[], u8 led_info_num, bool a_IsLog2File) +{ + u8 i = 0; + u32 ret = 0; + char *LogBuffer = NULL; + char filename[128]; + struct file *fp = NULL; + mm_segment_t fs = {0}; + + u32 CurLogSize = 0; + u64 SysTimeNow_ns, SysTimeNow_sec, Temp_u64; + + if (atLED_INFO == NULL) { + misp_info("%s fail!", __func__); + goto EXIT; + } + + if (a_IsLog2File) { + /* 200KB enougth for two hours */ + LogBuffer = kzalloc(LOG_BUF_SIZE, GFP_KERNEL); + if (LogBuffer == NULL) { + ret = -ENOMEM; + misp_err("%s, LogBuffer allocate fail", __func__); + goto EXIT; + } + + ret = mini_isp_create_directory(MINIISP_INFO_DUMPLOCATION); + + snprintf(filename, 128, "%s/led_info_log", MINIISP_INFO_DUMPLOCATION); + #if ENABLE_FILP_OPEN_API + /* use file open */ + #else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + kfree(LogBuffer); + goto EXIT; + #endif + /*Get current segment descriptor*/ + fs = get_fs(); + + /*Set segment descriptor associated*/ + set_fs(get_ds()); + + if (IS_ERR(fp)) { + ret = PTR_ERR(fp); + set_fs(fs); + kfree(LogBuffer); + misp_err("%s open file failed. err: %d", __func__, ret); + goto EXIT; + } + + /* get linux system time */ + SysTimeNow_ns = local_clock(); + SysTimeNow_sec = SysTimeNow_ns; + SysTimeNow_ns = do_div(SysTimeNow_sec, 1000000000); + Temp_u64 = SysTimeNow_ns; + do_div(Temp_u64, 1000); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "SysTime: [%5lld.%06lld]\n", SysTimeNow_sec, Temp_u64); + for (i = 0; i < led_info_num; i++) { + /* LogBuffer full, write the file */ + if (CurLogSize + 256 > LOG_BUF_SIZE) { + vfs_write(fp, (char *)LogBuffer, CurLogSize, &fp->f_pos); + CurLogSize = 0; + } + + if (atLED_INFO[i].Type == E_LED_PROJECTOR) + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, "Projector ID: %d\n", i); + else if (atLED_INFO[i].Type == E_LED_FLOOD) + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, "Flood ID: %d\n", i); + else { + kfree(LogBuffer); + misp_info("%s parser err", __func__); + goto EXIT; + } + + /* one line 128 byte at most */ + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "level: %d, current: %d(mA), MaxCurrent: %d(mA)\n", + atLED_INFO[i].Level, atLED_INFO[i].Current, atLED_INFO[i].MaxCurrent); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "err: 0x%x, ErrStatus: 0x%x, ErrTemperature: %d\n", + atLED_INFO[i].errCode, atLED_INFO[i].ErrStatus, atLED_INFO[i].Temperature); + } + + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, "\n"); + + /* save final Log */ + vfs_write(fp, (char *)LogBuffer, CurLogSize, &fp->f_pos); + + /*Restore segment descriptor*/ + set_fs(fs); + filp_close(fp, NULL); + + if (LogBuffer) + kfree(LogBuffer); + } else { + /* printf to dmesg */ + for (i = 0; i < led_info_num; i++) { + if (atLED_INFO[i].Type == E_LED_PROJECTOR) + misp_info("Projector ID: %d", i); + else if (atLED_INFO[i].Type == E_LED_FLOOD) + misp_info("Flood ID: %d", i); + else { + misp_info("%s parser err", __func__); + goto EXIT; + } + + misp_info("level: %d, current: %d(mA), MaxCurrent: %d(mA)", + atLED_INFO[i].Level, atLED_INFO[i].Current, atLED_INFO[i].MaxCurrent); + misp_info("err: 0x%x, ErrStatus: 0x%x, ErrTemperature: %d", + atLED_INFO[i].errCode, atLED_INFO[i].ErrStatus, atLED_INFO[i].Temperature); + } + } + + +EXIT: + return; +} + +/** + *\brief log projector & flood status + *\param a_IsLog2File [In] 0: print to dmesg. 1: log to file. + *\return Error code + */ +errcode mini_isp_debug_led_info(bool a_IsLog2File) +{ + errcode errcode = ERR_SUCCESS; + const u32 maxWaitNum = 180; + u8 LED_INFO_NUM = 1; + u8 write_buffer[4]; + u32 FEC_DEBUG_FLAG = 0; + u32 led_info_addr = 0; + u32 i = 0; + PROJECTOR_INFO atLED_INFO[5]; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + LED_INFO_NUM = sizeof(atLED_INFO)/sizeof(PROJECTOR_INFO); + + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + + /* 1. Set Projector debug mode. AL6100 stop AEC control */ + write_buffer[0] = ADV_LOG_LIGHTING_PROJECTOR; + mini_isp_memory_write(DEBUG_INFO_FEC_DEBUG_MODE_ADDR, write_buffer, 1); + + /* 2. wait projector log collect */ + for (i = 0; i < maxWaitNum; i++) { + msleep(100); + mini_isp_memory_read(DEBUG_INFO_FEC_DEBUG_MODE_ADDR, (u8 *)&FEC_DEBUG_FLAG, 4); + if (FEC_DEBUG_FLAG == 0) + break; + + if (i == maxWaitNum-1) { + misp_info("wait projector log fail!"); + goto EXIT; + } else + misp_info("wait projector log.."); + } + + /* 3. Set flood debug mode. AL6100 stop AEC control */ + write_buffer[0] = ADV_LOG_LIGHTING_FLOOD; + mini_isp_memory_write(DEBUG_INFO_FEC_DEBUG_MODE_ADDR, write_buffer, 1); + + /* 4. wait flood log collect */ + for (i = 0; i < maxWaitNum; i++) { + msleep(100); + mini_isp_memory_read(DEBUG_INFO_FEC_DEBUG_MODE_ADDR, (u8 *)&FEC_DEBUG_FLAG, 4); + if (FEC_DEBUG_FLAG == 0) + break; + + if (i == maxWaitNum-1) { + misp_info("wait flood log fail!"); + goto EXIT; + } else + misp_info("wait flood log.."); + } + + /* 5. read led info addr */ + mini_isp_memory_read(DEBUG_INFO_LED_INFO_ADDR, (u8 *)&led_info_addr, 4); + + /* 6. read led info context */ + mini_isp_memory_read(led_info_addr, (u8 *)atLED_INFO, sizeof(atLED_INFO)); + + /* 7. show led info context */ + mini_isp_debug_led_info_parser(atLED_INFO, LED_INFO_NUM, a_IsLog2File); +EXIT: + if (dev_global_variable->intf_status & INTF_SPI_READY && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + return errcode; +} +EXPORT_SYMBOL(mini_isp_debug_led_info); + +bool mipi_rx_fps_first_run = true; +bool mipi_rx_fps_task_active = false; +static struct task_struct *mipi_rx_fps_task; + +static void mipi_rx_get_frame_count(u32 *rx0_count, u32 *rx1_count) +{ + #define RX0_FRAME_COUNT_REG 0xfff92010 + #define RX1_FRAME_COUNT_REG 0xfff95010 + + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + if (rx0_count == NULL && rx1_count == NULL) { + misp_info("%s input err", __func__); + return; + } + + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + if (rx0_count != NULL) { + mini_isp_register_read(RX0_FRAME_COUNT_REG, rx0_count); + *rx0_count = *rx0_count & 0xFFFF; /* only use 0~15 bit*/ + } + + if (rx1_count != NULL) { + mini_isp_register_read(RX1_FRAME_COUNT_REG, rx1_count); + *rx1_count = *rx1_count & 0xFFFF; /* only use 0~15 bit*/ + } + + if (dev_global_variable->intf_status & INTF_SPI_READY && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); +} + +int mipi_rx_fps_body(void *arg) +{ + u32 ret; + struct timeval TimeNow = {0}; + struct timeval TimePrev = {0}; + u32 Rx0_count_Now = 0, Rx0_count_Prev = 0; + u32 Rx1_count_Now = 0, Rx1_count_Prev = 0; + u32 Rx0_fps_d, Rx0_fps_f, Rx1_fps_d, Rx1_fps_f; + u32 Rx0_count_diff, Rx1_count_diff; + u32 tmp; + u32 Timediff_ms = 0; + u64 TimeNow_ms, TimePrev_ms, Temp_u64; + u64 SysTimeNow_sec; + u64 SysTimeNow_ns; + + char filename[128]; + struct file *fp = NULL; + mm_segment_t fs = {0}; + u32 CurLogSize = 0; + char *LogBuffer = NULL; + bool IsLog2File = *(bool *)arg; + + misp_info("%s S", __func__); + + if (IsLog2File) { + LogBuffer = kzalloc(LOG_BUF_SIZE, GFP_KERNEL); /* 200KB enougth for two hours */ + if (LogBuffer == NULL) { + misp_err("%s, LogBuffer allocate fail", __func__); + goto EXIT; + } + + ret = mini_isp_create_directory(MINIISP_INFO_DUMPLOCATION); + + snprintf(filename, 128, "%s/rx_fps_log", MINIISP_INFO_DUMPLOCATION); + #if ENABLE_FILP_OPEN_API + /* use file open */ + #else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + goto EXIT; + #endif + /*Get current segment descriptor*/ + fs = get_fs(); + + /*Set segment descriptor associated*/ + set_fs(get_ds()); + + if (IS_ERR(fp)) { + ret = PTR_ERR(fp); + set_fs(fs); + misp_err("%s open file failed. err: %d", __func__, ret); + goto EXIT; + } + + } + + while (!kthread_should_stop()) { + do_gettimeofday(&TimeNow); + mipi_rx_get_frame_count(&Rx0_count_Now, &Rx1_count_Now); + + if (mipi_rx_fps_first_run) { + mipi_rx_fps_first_run = false; + + /* keep previous time record */ + memcpy(&TimePrev, &TimeNow, sizeof(struct timespec)); + Rx0_count_Prev = Rx0_count_Now; + Rx1_count_Prev = Rx1_count_Now; + + msleep(2000); + continue; + } + + /* Calc rx frame count fps */ + TimeNow_ms = (TimeNow.tv_sec * 1000) + (TimeNow.tv_usec / 1000); + TimePrev_ms = (TimePrev.tv_sec * 1000) + (TimePrev.tv_usec / 1000); + Timediff_ms = (u32) (TimeNow_ms - TimePrev_ms); + + /* X1000 for ms precision, X100 for the two digit after the decimal point*/ + Rx0_count_diff = Rx0_count_Now - Rx0_count_Prev; + tmp = (Rx0_count_diff * 100 * 1000) / Timediff_ms; + Rx0_fps_d = tmp / 100; + Rx0_fps_f = tmp % 100; + + Rx1_count_diff = Rx1_count_Now - Rx1_count_Prev; + tmp = (Rx1_count_diff * 100 * 1000) / Timediff_ms; + Rx1_fps_d = tmp / 100; + Rx1_fps_f = tmp % 100; + + /* get linux system time */ + SysTimeNow_ns = local_clock(); + SysTimeNow_sec = SysTimeNow_ns; + SysTimeNow_ns = do_div(SysTimeNow_sec, 1000000000); + if (IsLog2File) { + /* LogBuffer full, write the file */ + if (CurLogSize + 128 > LOG_BUF_SIZE) { + vfs_write(fp, (char *)LogBuffer, CurLogSize, &fp->f_pos); + CurLogSize = 0; + } + + /* one line 128 byte at most */ + Temp_u64 = SysTimeNow_ns; + do_div(Temp_u64, 1000); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "[%5lld.%06lld]: Rx0 fps %d.%02d, Rx1 fps %d.%02d\n", + SysTimeNow_sec, Temp_u64, + Rx0_fps_d, Rx0_fps_f, Rx1_fps_d, Rx1_fps_f); + } else{ + Temp_u64 = SysTimeNow_ns; + do_div(Temp_u64, 1000); + misp_info("%s test", __func__); + misp_info("[%5lld.%06lld]: Rx0 fps %d.%02d, Rx1 fps %d.%02d", + SysTimeNow_sec, Temp_u64, + Rx0_fps_d, Rx0_fps_f, Rx1_fps_d, Rx1_fps_f); + } + + /* keep previous time record */ + memcpy(&TimePrev, &TimeNow, sizeof(struct timeval)); + Rx0_count_Prev = Rx0_count_Now; + Rx1_count_Prev = Rx1_count_Now; + + msleep(2000); + } + + if (IsLog2File) { + /* save final Log */ + vfs_write(fp, (char *)LogBuffer, CurLogSize, &fp->f_pos); + + /*Restore segment descriptor*/ + set_fs(fs); + filp_close(fp, NULL); + } + +EXIT: + misp_info("%s E", __func__); + if (LogBuffer != NULL) + kfree(LogBuffer); + + return 0; +} + +/** + *\brief start log mini rx frame count fps + *\param a_IsLog2File [In] 0: print to dmesg. 1: log to file. + *\return Error code + */ +int mini_isp_debug_mipi_rx_fps_start(bool a_IsLog2File) +{ + u32 ret = 0; + static bool IsLog2File; + + IsLog2File = a_IsLog2File; + + /* create mipi_rx_fps_task */ + if (!mipi_rx_fps_task_active) { + mipi_rx_fps_task = kthread_create(mipi_rx_fps_body, &IsLog2File, "mipi_rx_fps_task"); + if (IS_ERR(mipi_rx_fps_task)) { + ret = PTR_ERR(mipi_rx_fps_task); + mipi_rx_fps_task = NULL; + misp_info("%s, mipi_rx_fps_task initial fail, 0x%x", __func__, ret); + goto EXIT; + } + wake_up_process(mipi_rx_fps_task); + + mipi_rx_fps_task_active = true; + mipi_rx_fps_first_run = true; + misp_info("%s task create success!", __func__); + } else { + misp_info("%s already initial", __func__); + } + +EXIT: + return ret; +} +EXPORT_SYMBOL(mini_isp_debug_mipi_rx_fps_start); + +/** + *\brief stop log mini rx frame count fps + *\return none + */ +void mini_isp_debug_mipi_rx_fps_stop(void) +{ + /* delete mipi_rx_fps_task. + Can't delete task if this task is done. otherwise, it will busy waiting */ + if (mipi_rx_fps_task_active) { + if (mipi_rx_fps_task != NULL) { + kthread_stop(mipi_rx_fps_task); + mipi_rx_fps_task = NULL; + } + mipi_rx_fps_task_active = false; + misp_info("%s kill task success", __func__); + } else + misp_info("%s no task to kill", __func__); +} +EXPORT_SYMBOL(mini_isp_debug_mipi_rx_fps_stop); + +/** + *\brief list GPIO status + *\return none + */ +errcode mini_isp_debug_GPIO_Status(bool a_IsLog2File) +{ + errcode errcode = ERR_SUCCESS; + u32 aGPIO_RegVal[GPIO_NUMBER] = {0}; + u32 aGPIO_mode[GPIO_NUMBER] = {0}; + u32 aGPIO_IO[GPIO_NUMBER] = {0}; + u32 aGPIO_data[GPIO_NUMBER] = {0}; + u32 i = 0; + char filename[128]; + struct file *fp = NULL; + mm_segment_t fs = {0}; + + u32 CurLogSize = 0; + char *LogBuffer = NULL; + u64 SysTimeNow_ns, SysTimeNow_sec, Temp_u64; + struct misp_global_variable *dev_global_variable; + + dev_global_variable = get_mini_isp_global_variable(); + + mutex_lock(&dev_global_variable->busy_lock); + + if ((dev_global_variable->intf_status & INTF_SPI_READY) && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_A)) { + misp_info("%s a_to_e", __func__); + mini_isp_a_to_e(); + } + + if (a_IsLog2File) { + LogBuffer = kzalloc(LOG_BUF_SIZE, GFP_KERNEL); + if (LogBuffer == NULL) { + misp_err("%s, LogBuffer allocate fail", __func__); + goto EXIT; + } + + errcode = mini_isp_create_directory(MINIISP_INFO_DUMPLOCATION); + + snprintf(filename, 128, "%s/GPIO_Status_log", MINIISP_INFO_DUMPLOCATION); + + #if ENABLE_FILP_OPEN_API + /* use file open */ + #else + misp_info("Error! Currently not support file open api"); + misp_info("See define ENABLE_FILP_OPEN_API"); + goto EXIT; + #endif + /*Get current segment descriptor*/ + fs = get_fs(); + + /*Set segment descriptor associated*/ + set_fs(get_ds()); + + if (IS_ERR(fp)) { + errcode = PTR_ERR(fp); + set_fs(fs); + misp_err("%s open file failed. err: %d", __func__, errcode); + goto EXIT; + } + + /* get linux system time */ + SysTimeNow_ns = local_clock(); + SysTimeNow_sec = SysTimeNow_ns; + SysTimeNow_ns = do_div(SysTimeNow_sec, 1000000000); + Temp_u64 = SysTimeNow_ns; + do_div(Temp_u64, 1000); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "SysTime: [%5lld.%06lld]\n", SysTimeNow_sec, Temp_u64); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, "=== Check GPIO status ===\n"); + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "SK1 pin\tMapping\t\tmode\t\tI/O\tHigh/Low\n"); + + for (i = 0; i < GPIO_NUMBER; i++) { + /* read GPIO status */ + mini_isp_register_read(g_atGPIO[i].addr, &aGPIO_RegVal[i]); + aGPIO_mode[i] = aGPIO_RegVal[i] & 0x1F; + if (aGPIO_mode[i] > 1) + aGPIO_mode[i] = 1; + aGPIO_IO[i] = (aGPIO_RegVal[i] >> 6) & 0x1; + aGPIO_data[i] = (aGPIO_RegVal[i] >> 5) & 0x1; + + /* one line 128 byte at most */ + CurLogSize += snprintf(&LogBuffer[CurLogSize], 128, + "%s\t%s \t%s\t\t%s\t%s\n", + g_atGPIO[i].name, g_atGPIO[i].mapping, + aGPIO_mode[i] ? "Function" : "GPIO", + aGPIO_IO[i] ? "GPO" : "GPI", + aGPIO_data[i] ? "High" : "Low"); + + } + + /* save final Log */ + vfs_write(fp, (char *)LogBuffer, CurLogSize, &fp->f_pos); + + /*Restore segment descriptor*/ + set_fs(fs); + filp_close(fp, NULL); + } else { + misp_info("=== Check GPIO status ==="); + misp_info("SK1 pin\tMapping\t\tmode\t\tI/O\tHigh/Low"); + for (i = 0; i < GPIO_NUMBER; i++) { + /* read GPIO status */ + mini_isp_register_read(g_atGPIO[i].addr, &aGPIO_RegVal[i]); + aGPIO_mode[i] = aGPIO_RegVal[i] & 0x1F; + if (aGPIO_mode[i] > 1) + aGPIO_mode[i] = 1; + aGPIO_IO[i] = (aGPIO_RegVal[i] >> 6) & 0x1; + aGPIO_data[i] = (aGPIO_RegVal[i] >> 5) & 0x1; + + misp_info("%s\t%s \t%s\t\t%s\t%s", + g_atGPIO[i].name, g_atGPIO[i].mapping, + aGPIO_mode[i] ? "Function" : "GPIO", + aGPIO_IO[i] ? "GPO" : "GPI", + aGPIO_data[i] ? "High" : "Low"); + } + } + +EXIT: + if (dev_global_variable->intf_status & INTF_SPI_READY && + (dev_global_variable->altek_spi_mode == ALTEK_SPI_MODE_E)) { + misp_info("%s e_to_a", __func__); + mini_isp_e_to_a(); + } + + mutex_unlock(&dev_global_variable->busy_lock); + + if (LogBuffer != NULL) + kfree(LogBuffer); + + return errcode; +} +EXPORT_SYMBOL(mini_isp_debug_GPIO_Status); diff --git a/drivers/media/platform/altek/operation_cmd.c b/drivers/media/platform/altek/operation_cmd.c new file mode 100755 index 000000000000..3821241f48f3 --- /dev/null +++ b/drivers/media/platform/altek/operation_cmd.c @@ -0,0 +1,214 @@ +/* + * File: operation_cmd.c + * Description: operation command + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/10/14; Aaron Chuang; Initial version + * 2013/12/05; Bruce Chung; 2nd version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/******Include File******/ + + +#include +#include + +#include "include/error.h" +#include "include/mtype.h" +#include "include/error.h" +#include "include/isp_camera_cmd.h" +#include "include/miniisp.h" +#include "include/ispctrl_if_master.h" + + +/******Private Constant Definition******/ + + +#define MINI_ISP_LOG_TAG "[operation_cmd]" + +extern struct file *g_filp[FIRMWARE_MAX]; + +/******Public Function******/ + +/** + *\brief Mini ISP open + *\param devdata [In], CMD param + *\param opcode [In], CMD param + *\param param [In], CMD param + *\return Error code + */ +errcode mast_operation_cmd_miniisp_open(void *devdata, + u16 opcode, u8 *FileNametbl[]) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + char *pBootpath, /*boot code*/ + *pBasicpath, /*basic code*/ + *pAdvancedpath, /*advanced code*/ + *pScenariopath, /*scenario data*/ + *pHdrpath, /*hdr qmerge data*/ + *pIrp0path, /*irp0 qmerge data*/ + *pIrp1path, /*irp1 qmerge data*/ + *pPPmappath, /*pp map*/ + *pDepthpath; /*depth qmerge data*/ + + pBootpath = FileNametbl[0]; + pBasicpath = FileNametbl[1]; + pAdvancedpath = FileNametbl[2]; + pScenariopath = FileNametbl[3]; + pHdrpath = FileNametbl[4]; + pIrp0path = FileNametbl[5]; + pIrp1path = FileNametbl[6]; + pPPmappath = FileNametbl[7]; + pDepthpath = FileNametbl[8]; + + misp_info("%s - start", __func__); + + /*open boot code*/ + if (pBootpath) { + /* + *misp_info("%s - boot code, path: %s", + * __func__, pBootpath); + */ + err = ispctrl_if_mast_request_firmware(pBootpath, + BOOT_CODE); + if (err != ERR_SUCCESS) { + misp_err("%s - open boot code failed", __func__); + goto mast_operation_cmd_miniisp_open_end; + } + } + + /*open basic code*/ + if (pBasicpath) { + /* + *misp_info("%s - basic code, path: %s", + * __func__, pBasicpath); + */ + err = ispctrl_if_mast_request_firmware(pBasicpath, + BASIC_CODE); + if (err != ERR_SUCCESS) { + misp_err("%s - open basic code failed", __func__); + goto mast_operation_cmd_miniisp_open_end; + } + } + + /*open advanced code*/ + if (pAdvancedpath) { + /* + *misp_info("%s - advanced code, path: %s", + * __func__, pAdvancedpath); + */ + err = ispctrl_if_mast_request_firmware(pAdvancedpath, + ADVANCED_CODE); + if (err != ERR_SUCCESS) { + misp_err("%s - open advanced code failed", __func__); + goto mast_operation_cmd_miniisp_open_end; + } + } + + + /*open scenario data*/ + if (pScenariopath) { + /* + *misp_info("%s - scenario data, path: %s", + * __func__, pScenariopath); + */ + err = ispctrl_if_mast_request_firmware(pScenariopath, + SCENARIO_CODE); + if (err != ERR_SUCCESS) { + misp_err("%s - open scenario data failed", __func__); + goto mast_operation_cmd_miniisp_open_end; + } + } + + /*open hdr qmerge data*/ + if (pHdrpath) { + + err = ispctrl_if_mast_request_firmware(pHdrpath, + HDR_CODE); + if (err != ERR_SUCCESS) { + misp_err("%s - open hdr qmerge data failed", __func__); + goto mast_operation_cmd_miniisp_open_end; + } + } + /*open irp0 qmerge data*/ + if (pIrp0path) { + + err = ispctrl_if_mast_request_firmware(pIrp0path, + IRP0_CODE); + if (err != ERR_SUCCESS) { + misp_err("%s - open irp0 qmerge data failed", __func__); + goto mast_operation_cmd_miniisp_open_end; + } + } + /*open irp1 qmerge data*/ + if (pIrp1path) { + + err = ispctrl_if_mast_request_firmware(pIrp1path, + IRP1_CODE); + if (err != ERR_SUCCESS) { + misp_err("%s - open irp1 qmerge data failed", __func__); + goto mast_operation_cmd_miniisp_open_end; + } + } + + /*open pp map*/ + if (pPPmappath) { + + err = ispctrl_if_mast_request_firmware(pPPmappath, + PPMAP_CODE); + if (err != ERR_SUCCESS) { + misp_err("%s - open PP map failed", __func__); + goto mast_operation_cmd_miniisp_open_end; + } + } + + /*open depth qmerge data*/ + if (pDepthpath) { + + err = ispctrl_if_mast_request_firmware(pDepthpath, + DEPTH_CODE); + if (err != ERR_SUCCESS) { + /* Ignored error for 'No such file or directory' */ + if ((ENOENT + err) == 0) { + g_filp[DEPTH_CODE] = NULL; + err = ERR_SUCCESS; + } + misp_info("%s - open depth qmerge data failed", __func__); + /* goto mast_operation_cmd_miniisp_open_end; */ + } + } + + misp_info("%s end", __func__); + +mast_operation_cmd_miniisp_open_end: + + return err; +} + +/******Private Function******/ + + + + + +/****** End Of File******/ diff --git a/drivers/media/platform/altek/sys_manage_cmd.c b/drivers/media/platform/altek/sys_manage_cmd.c new file mode 100755 index 000000000000..509019b7253c --- /dev/null +++ b/drivers/media/platform/altek/sys_manage_cmd.c @@ -0,0 +1,281 @@ +/* + * File: sys_managec_md.c + * Description: System manage command + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + * 2013/10/14; Aaron Chuang; Initial version + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + + + +/* Standard C*/ + +/* Global Header Files*/ +/*#include */ + +#include "include/isp_camera_cmd.h" +/* ISP Ctrl IF slave*/ +#include "include/ispctrl_if_master.h" +/* ISP Ctrl IF slave error*/ +#include "include/error/ispctrl_if_master_err.h" + +/* Local Header Files*/ +#include "include/ispctrl_if_master_local.h" + + + +/******Include File******/ + + + +/******Private Constant Definition******/ + + +#define MINI_ISP_LOG_TAG "[sys_manage_cmd]" + + +/******Private Type Declaration******/ + + + +/******Private Function Prototype******/ + +/******Private Global Variable******/ + + + +/******Public Global Variable******/ + +/******Public Function******/ + +/** + *\brief Get Status of Last Executed Command + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_get_status_of_last_exec_command( + void *devdata, u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Parameter size*/ + u32 para_size = sizeof(struct system_cmd_status_of_last_command); + + + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, param, 0); + if (err != ERR_SUCCESS) + goto mast_sys_manage_cmd_get_status_of_last_exec_command_end; + + /* Get data from slave*/ + err = ispctrl_mast_recv_response_from_slave(devdata, param, + para_size, true); +mast_sys_manage_cmd_get_status_of_last_exec_command_end: + + return err; + + +} + +/** + *\brief Get Error Code Command + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_get_error_code_command(void *devdata, + u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Parameter size*/ + /*get last ten error code and error status*/ + u32 para_size = (sizeof(errcode))*10; + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, param, 0); + if (err != ERR_SUCCESS) + goto mast_sys_manage_cmd_get_error_code_command_end; + + /* Get data from slave*/ + err = ispctrl_mast_recv_response_from_slave(devdata, param, + para_size, false); + if (err != ERR_SUCCESS) + goto mast_sys_manage_cmd_get_error_code_command_end; + + misp_err("%s last error code %x %x %x %x", __func__, *(param), + *(param+1), *(param+2), *(param+3)); +mast_sys_manage_cmd_get_error_code_command_end: + + return err; +} + +/** + *\brief Set ISP register + *\param devdata [In], misp_data + *\param opCode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_set_isp_register(void *devdata, + u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Parameter size*/ + u32 para_size = sizeof(struct system_cmd_isp_register); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/** + *\brief Get ISP register + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_get_isp_register(void *devdata, + u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + /* Parameter size*/ + u32 para_size = sizeof(struct system_cmd_isp_register); + /* Response size*/ + u32 *reg_count = (u32 *)¶m[4]; + + + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + if (err != ERR_SUCCESS) + goto mast_sys_manage_cmd_get_isp_register_end; + + /* Update response size*/ + para_size = sizeof(struct system_cmd_isp_register) + *reg_count*4; + + /* Get data from slave*/ + err = ispctrl_if_mast_recv_isp_register_response_from_slave( + devdata, + param, + ¶_size, + *reg_count); +mast_sys_manage_cmd_get_isp_register_end: + + return err; +} + +/** + *\brief Set common log level + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_set_comomn_log_level(void *devdata, + u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size = sizeof(struct system_cmd_common_log_level); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + return err; +} + +/** + *\brief Get chip test report + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_get_chip_test_report(void *devdata, + u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size = 0; + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, + param, para_size); + if (err != ERR_SUCCESS) + goto mast_sys_manage_cmd_get_chip_test_report_end; + + /* Update response size*/ + para_size = ReportRegCount; + + /* Get data from slave*/ + err = ispctrl_mast_recv_response_from_slave(devdata, param, + para_size, true); +mast_sys_manage_cmd_get_chip_test_report_end: + + return err; +} + +/* + *\brief Get isp thermal + *\param devdata [In], misp_data + *\param opcode [In], Operation code + *\param param [In], CMD param + *\return Error code + */ +errcode mast_sys_manage_cmd_get_chip_thermal( + void *devdata, + u16 opcode, u8 *param) +{ + /* Error Code*/ + errcode err = ERR_SUCCESS; + u32 para_size = sizeof(u16); + + misp_info("%s - enter", __func__); + + /* Send command to slave*/ + err = ispctrl_mast_send_cmd_to_slave(devdata, opcode, NULL, 0); + if (err != ERR_SUCCESS) + goto mast_camera_profile_cmd_get_isp_thermal_end; + + /* Get data from slave*/ + err = ispctrl_mast_recv_response_from_slave(devdata, + param, para_size, true); + if (err != ERR_SUCCESS) { + misp_info("%s - err 0x%x", __func__, err); + goto mast_camera_profile_cmd_get_isp_thermal_end; + } + + misp_info("Get thermal value 0x%x", *(u16 *)param); + +mast_camera_profile_cmd_get_isp_thermal_end: + return err; +} + +/******End Of File******/ diff --git a/include/uapi/Kbuild b/include/uapi/Kbuild index aeb3366db4fc..96815bd434ff 100644 --- a/include/uapi/Kbuild +++ b/include/uapi/Kbuild @@ -14,3 +14,4 @@ header-y += xen/ header-y += scsi/ header-y += misc/ header-y += media/ +header-y += miniISP/ diff --git a/include/uapi/miniISP/Kbuild b/include/uapi/miniISP/Kbuild new file mode 100644 index 000000000000..0e318e6bfb3c --- /dev/null +++ b/include/uapi/miniISP/Kbuild @@ -0,0 +1,3 @@ +# ///ALTEK_TAG_HwMiniISP>>> +header-y += miniISP_ioctl.h +# ///ALTEK_TAG_HwMiniISP<<< \ No newline at end of file diff --git a/include/uapi/miniISP/miniISP_ioctl.h b/include/uapi/miniISP/miniISP_ioctl.h new file mode 100644 index 000000000000..a087e918b3f5 --- /dev/null +++ b/include/uapi/miniISP/miniISP_ioctl.h @@ -0,0 +1,164 @@ +/* + * File: miniISP_ioctl.h + * Description: miniISP ioctl + * + * Copyright 2019-2030 Altek Semiconductor Corporation + * + */ + +/* + * This file is part of al6100. + * + * al6100 is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2, as published by + * the Free Software Foundation. + * + * al6100 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for + * more details. + * + * You should have received a copy of the General Public License version 2 + * along with al6100. If not, see https://www.gnu.org/licenses/gpl-2.0.html. + */ + +/* /ALTEK_TAG_HwMiniISP>>> */ + +#ifndef _MINI_ISP_IOCTL_H_ +#define _MINI_ISP_IOCTL_H_ + +#include +#include /* _IOW(), _IOR() */ + +#define SPIBULK_BLOCKSIZE 8192 /* 8k bytes */ +#define SPI_CMD_LENGTH 64 + +#define ISPCMD_LOAD_FW 0x0001 +#define ISPCMD_PURE_BYPASS 0x0010 +#define ISPCMD_POWER_OFF 0x0100 +#define ISPCMD_ENTER_CP_MODE 0x0200 +#define ISPCMD_LEAVE_CP_MODE_STANDBY 0x0002 +#define ISPCMD_NONE 0x0000 + + +/*Calibration Profile*/ +#define ISPCMD_CAMERA_SET_SENSORMODE 0x300A +#define ISPCMD_CAMERA_GET_SENSORMODE 0x300B +#define ISPCMD_CAMERA_SET_OUTPUTFORMAT 0x300D +#define ISPCMD_CAMERA_SET_CP_MODE 0x300E +#define ISPCMD_CAMERA_SET_AE_STATISTICS 0x300F +#define ISPCMD_CAMERA_PREVIEWSTREAMONOFF 0x3010 +#define ISPCMD_CAMERA_DUALPDYCALCULATIONWEIGHT 0x3011 +#define ISPCMD_LED_POWERCONTROL 0x3012 +#define ISPCMD_CAMERA_ACTIVE_AE 0x3013 +#define ISPCMD_ISP_AECONTROLONOFF 0x3014 +#define ISPCMD_CAMERA_SET_FRAMERATELIMITS 0x3015 +#define ISPCMD_CAMERA_SET_PERIODDROPFRAME 0x3016 +#define ISPCMD_CAMERA_SET_MAX_EXPOSURE 0x3017 +#define ISPCMD_CAMERA_SET_AE_TARGET_MEAN 0x3018 +#define ISPCMD_CAMERA_FRAME_SYNC_CONTROL 0x3019 +#define ISPCMD_CAMERA_SET_SHOT_MODE 0x301A +#define ISPCMD_CAMERA_LIGHTING_CTRL 0x301B +#define ISPCMD_CAMERA_DEPTH_COMPENSATION 0x301C +#define ISPCMD_CAMERA_TRIGGER_DEPTH_PROCESS_CTRL 0x301D +#define ISPCMD_CAMERA_SET_MIN_EXPOSURE 0x301E +#define ISPCMD_CAMERA_SET_MAX_EXPOSURE_SLOPE 0x301F + + + +/* Bulk Data*/ +#define ISPCMD_BULK_WRITE_BASICCODE 0x2002 +#define ISPCMD_BULK_WRITE_BOOTCODE 0x2008 +#define ISPCMD_BULK_READ_MEMORY 0x2101 +#define ISPCMD_BULK_READ_COMLOG 0x2102 +#define ISPCMD_BULK_WRITE_CALIBRATION_DATA 0x210B + +/*Basic Setting*/ +#define ISPCMD_BASIC_SET_DEPTH_3A_INFO 0x10B9 +#define ISPCMD_BASIC_SET_DEPTH_AUTO_INTERLEAVE_MODE 0x10BC +#define ISPCMD_BASIC_SET_INTERLEAVE_MODE_DEPTH_TYPE 0x10BD +#define ISPCMD_BASIC_SET_DEPTH_POLISH_LEVEL 0x10BE + +/*System Cmd*/ +#define ISPCMD_SYSTEM_GET_STATUSOFLASTEXECUTEDCOMMAND 0x0015 +#define ISPCMD_SYSTEM_GET_ERRORCODE 0x0016 +#define ISPCMD_SYSTEM_SET_ISPREGISTER 0x0100 +#define ISPCMD_SYSTEM_GET_ISPREGISTER 0x0101 +/*#define ISPCMD_SYSTEM_SET_DEBUGCMD 0x0104*/ +#define ISPCMD_SYSTEM_SET_COMLOGLEVEL 0x0109 +#define ISPCMD_SYSTEM_GET_CHIPTESTREPORT 0x010A + +/*Operarion Code*/ +#define ISPCMD_MINIISPOPEN 0x4000 + + + +/* ALTEK_AL6100_KERNEL >>> */ +#define IOC_ISP_CTRL_FLOW_KERNEL_MAGIC 'D' + +#define IOCTL_ISP_RUN_TASK_INIT \ + _IOWR(IOC_ISP_CTRL_FLOW_KERNEL_MAGIC, BASE_MINIISP_CONTROL, struct miniISP_cmd_config) + +#define IOCTL_ISP_RUN_TASK_START \ + _IOWR(IOC_ISP_CTRL_FLOW_KERNEL_MAGIC, BASE_MINIISP_CONTROL + 1, struct miniISP_cmd_config) + +#define IOCTL_ISP_RUN_TASK_STOP \ + _IOWR(IOC_ISP_CTRL_FLOW_KERNEL_MAGIC, BASE_MINIISP_CONTROL + 2, struct miniISP_cmd_config) + +#define IOCTL_ISP_RUN_TASK_DEINIT \ + _IOWR(IOC_ISP_CTRL_FLOW_KERNEL_MAGIC, BASE_MINIISP_CONTROL + 3, struct miniISP_cmd_config) + +#define IOCTL_ISP_RUN_TASK_QUERY \ + _IOWR(IOC_ISP_CTRL_FLOW_KERNEL_MAGIC, BASE_MINIISP_CONTROL + 4, struct miniISP_cmd_config) + +struct miniISP_chi_param { + /* uint8_t board_power_always_on; //1: power is always on */ + uint8_t scid; + uint8_t irflood_mode; + uint8_t merge_mode; +} __attribute__ ((packed)); + + +/* ALTEK_AL6100_KERNEL <<< */ + + + + +/* TODO: Need to solve the kernel panic >>> */ +struct miniISP_cmd_config { + uint16_t opcode; + uint32_t size; + uint64_t param; +} __attribute__ ((packed)); + +#define BASE_MINIISP_CONTROL 100 + +#define IOC_ISP_CTRL_FLOW_MAGIC 'C' + +#define IOCTL_ISP_LOAD_FW \ + _IOWR(IOC_ISP_CTRL_FLOW_MAGIC, BASE_MINIISP_CONTROL, struct miniISP_cmd_config) + +#define IOCTL_ISP_PURE_BYPASS \ + _IOWR(IOC_ISP_CTRL_FLOW_MAGIC, BASE_MINIISP_CONTROL + 1, struct miniISP_cmd_config) + +#define IOCTL_ISP_POWER_OFF \ + _IOWR(IOC_ISP_CTRL_FLOW_MAGIC, BASE_MINIISP_CONTROL + 2, struct miniISP_cmd_config) + +#define IOCTL_ISP_ENTER_CP_MODE \ + _IOWR(IOC_ISP_CTRL_FLOW_MAGIC, BASE_MINIISP_CONTROL + 3, struct miniISP_cmd_config) + +#define IOCTL_ISP_LEAVE_CP_MODE \ + _IOWR(IOC_ISP_CTRL_FLOW_MAGIC, BASE_MINIISP_CONTROL + 4, struct miniISP_cmd_config) + +#define IOCTL_ISP_CTRL_CMD \ + _IOWR(IOC_ISP_CTRL_FLOW_MAGIC, BASE_MINIISP_CONTROL + 5, struct miniISP_cmd_config) + +#define IOCTL_ISP_POWER_ON \ + _IOWR(IOC_ISP_CTRL_FLOW_MAGIC, BASE_MINIISP_CONTROL + 6, struct miniISP_cmd_config) + +#define IOCTL_ISP_DEINIT \ + _IOWR(IOC_ISP_CTRL_FLOW_MAGIC, BASE_MINIISP_CONTROL + 7, struct miniISP_cmd_config) + +/* /ALTEK_TAG_HwMiniISP<<< */ +#endif + From a6f4f42b13082f21d8c20d29b8b321f349c048e9 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Thu, 18 Jul 2019 20:31:08 +0530 Subject: [PATCH 155/281] msm: kgsl: Fix race condition between drawobj and context destroy drawobj_destroy_sync() tries to cancel all pending sync events by taking local copy of pending list. In case of sync point timestamp event, it goes ahead and accesses context's events list assuming that event's context would be alive. But at the same time, if the other context, which is of interest for these sync point events, can be destroyed by cancelling all events in its group. This leads to use-after-free in drawobj_destroy_sync() path. Fix is to give the responsibility of putting the context's ref count to the thread which clears the pending mask. Change-Id: I8d08ef6ddb38ca917f75088071c04727bced11d2 Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/kgsl_drawobj.c | 39 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c index a1e0f4c0d29b..40b49c397a18 100644 --- a/drivers/gpu/msm/kgsl_drawobj.c +++ b/drivers/gpu/msm/kgsl_drawobj.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -223,8 +223,13 @@ static void drawobj_sync_func(struct kgsl_device *device, trace_syncpoint_timestamp_expire(event->syncobj, event->context, event->timestamp); - drawobj_sync_expire(device, event); - kgsl_context_put(event->context); + /* + * Put down the context ref count only if + * this thread successfully clears the pending bit mask. + */ + if (drawobj_sync_expire(device, event)) + kgsl_context_put(event->context); + kgsl_drawobj_put(&event->syncobj->base); } @@ -254,24 +259,11 @@ static void drawobj_destroy_sparse(struct kgsl_drawobj *drawobj) static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) { struct kgsl_drawobj_sync *syncobj = SYNCOBJ(drawobj); - unsigned long pending = 0; unsigned int i; /* Zap the canary timer */ del_timer_sync(&syncobj->timer); - /* - * Copy off the pending list and clear each pending event atomically - - * this will render any subsequent asynchronous callback harmless. - * This marks each event for deletion. If any pending fence callbacks - * run between now and the actual cancel, the associated structures - * are kfreed only in the cancel call. - */ - for_each_set_bit(i, &syncobj->pending, KGSL_MAX_SYNCPOINTS) { - if (test_and_clear_bit(i, &syncobj->pending)) - __set_bit(i, &pending); - } - /* * Clear all pending events - this will render any subsequent async * callbacks harmless @@ -279,8 +271,12 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) for (i = 0; i < syncobj->numsyncs; i++) { struct kgsl_drawobj_sync_event *event = &syncobj->synclist[i]; - /* Don't do anything if the event has already expired */ - if (!test_bit(i, &pending)) + /* + * Don't do anything if the event has already expired. + * If this thread clears the pending bit mask then it is + * responsible for doing context put. + */ + if (!test_and_clear_bit(i, &syncobj->pending)) continue; switch (event->type) { @@ -288,6 +284,11 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) kgsl_cancel_event(drawobj->device, &event->context->events, event->timestamp, drawobj_sync_func, event); + /* + * Do context put here to make sure the context is alive + * till this thread cancels kgsl event. + */ + kgsl_context_put(event->context); break; case KGSL_CMD_SYNCPOINT_TYPE_FENCE: kgsl_sync_fence_async_cancel(event->handle); @@ -300,7 +301,7 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) * If we cancelled an event, there's a good chance that the context is * on a dispatcher queue, so schedule to get it removed. */ - if (!bitmap_empty(&pending, KGSL_MAX_SYNCPOINTS) && + if (!bitmap_empty(&syncobj->pending, KGSL_MAX_SYNCPOINTS) && drawobj->device->ftbl->drawctxt_sched) drawobj->device->ftbl->drawctxt_sched(drawobj->device, drawobj->context); From 846f83f42e27285543aba70cb0e3944e89f859c1 Mon Sep 17 00:00:00 2001 From: Naitik Bharadiya Date: Tue, 23 Jul 2019 19:17:03 +0530 Subject: [PATCH 156/281] defconfig: msm: Enable/Disable configs for SDM845 Enable/Disable following configs for SDM845 target to align them with android base config. Enable : CONFIG_XFRM_INTERFACE CONFIG_MEMBARRIER CONFIG_ARM64_SW_TTBR0_PAN Disable : CONFIG_PM_AUTOSLEEP CONFIG_DEVMEM CONFIG_DEVKMEM. Change-Id: Ia3fe0c9d9a62580f8e347caae7a6f2448b6477d7 Signed-off-by: Naitik Bharadiya --- arch/arm64/configs/sdm845-perf_defconfig | 4 ++-- arch/arm64/configs/sdm845_defconfig | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index 9e0c7a888afd..ae24d2d900c4 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -38,7 +38,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set @@ -72,6 +71,7 @@ CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y # CONFIG_RANDOMIZE_MODULE_REGION_FULL is not set @@ -79,7 +79,6 @@ CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -96,6 +95,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index 99b464a1c3dc..dd6cf6cc1e0b 100755 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -39,7 +39,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -76,12 +75,12 @@ CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -99,6 +98,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -319,6 +319,8 @@ CONFIG_INPUT_QPNP_POWER_ON=y CONFIG_INPUT_UINPUT=y # CONFIG_SERIO_SERPORT is not set # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM_GENI=y CONFIG_SERIAL_MSM_GENI_CONSOLE=y CONFIG_DIAG_CHAR=y From ba408cee1c3773ca6129a716e0cbfe82c8550e7d Mon Sep 17 00:00:00 2001 From: zhaochen Date: Thu, 25 Jul 2019 10:01:13 +0800 Subject: [PATCH 157/281] usb: xhci: remove do not use function remove the upd720x_smmu_deinit function to avoid compile warning, which is not used. Change-Id: I83be97bdbce5712bf47e8d1146127d753baf37fd Signed-off-by: zhaochen --- drivers/usb/host/xhci-fwdload.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/usb/host/xhci-fwdload.c b/drivers/usb/host/xhci-fwdload.c index f214e03be659..e2966ec560d0 100644 --- a/drivers/usb/host/xhci-fwdload.c +++ b/drivers/usb/host/xhci-fwdload.c @@ -83,13 +83,6 @@ static struct dma_iommu_mapping *upd720x_smmu_init(struct device *dev) return mapping; } -static void upd720x_smmu_deinit(struct device *dev) -{ - arm_iommu_detach_device(dev); - arm_iommu_release_mapping(to_dma_iommu_mapping(dev)); -} - - static int upd720x_download_enable(struct pci_dev *pDev) { unsigned int read_data; From 9faa0ee72b19308e2c8a2e1e91192ed1715fd2ef Mon Sep 17 00:00:00 2001 From: zhaochen Date: Tue, 18 Jun 2019 17:31:17 +0800 Subject: [PATCH 158/281] defconfig: sdm845: Add UPD720X PCI-E to USB controller support Add upd720x pci-e to usb controller compile config to make the driver be compiled, which will use in sdm845 rb3. Change-Id: I9a297e2817e4301b0492787b255e081a5b7a1640 Signed-off-by: zhaochen --- arch/arm64/configs/sdm845-perf_defconfig | 1 + arch/arm64/configs/sdm845_defconfig | 1 + 2 files changed, 2 insertions(+) mode change 100755 => 100644 arch/arm64/configs/sdm845_defconfig diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index 4529bfb899c0..f62a85a42156 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -419,6 +419,7 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_UPD720X=y CONFIG_USB_ACM=y CONFIG_USB_STORAGE=y CONFIG_USB_DWC3=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig old mode 100755 new mode 100644 index c06356427028..9f6dba1f759f --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -423,6 +423,7 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_UPD720X=y CONFIG_USB_ACM=y CONFIG_USB_STORAGE=y CONFIG_USB_DWC3=y From 4af2e37bbd17caf14843db65f1039431b24b233f Mon Sep 17 00:00:00 2001 From: Chandan Kumar Jha Date: Mon, 22 Jul 2019 15:00:51 +0530 Subject: [PATCH 159/281] msm: camera: lrme: Handle release lock when returning from error case Release mutex before returning error. Change-Id: I6f13e04db6ee10e88aa38f43cef1be61e725889f Signed-off-by: Chandan Kumar Jha --- .../camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c index 9628c814bc12..dce58f30475e 100644 --- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c +++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c @@ -899,7 +899,7 @@ int cam_lrme_hw_stop(void *hw_priv, void *hw_stop_args, uint32_t arg_size) lrme_core->state = CAM_LRME_CORE_STATE_INIT; } else { CAM_ERR(CAM_LRME, "HW in wrong state %d", lrme_core->state); - return -EINVAL; + rc = -EINVAL; } unlock: @@ -951,7 +951,8 @@ int cam_lrme_hw_submit_req(void *hw_priv, void *hw_submit_args, if (lrme_core->req_submit != NULL) { CAM_ERR(CAM_LRME, "req_submit is not NULL"); - return -EBUSY; + rc = -EBUSY; + goto error; } rc = cam_lrme_hw_util_submit_req(lrme_core, frame_req); From 16f76c8cbdb1eec2e9da6e745332fdec6c7e6804 Mon Sep 17 00:00:00 2001 From: taojiang Date: Mon, 22 Jul 2019 18:03:25 +0800 Subject: [PATCH 160/281] ARM: dts: msm: disable eeprom@1 and camera@2 for spyro device disable eeprom@1 and camera@2 for spyro device to optimize boot time Change-Id: I290e160e29022f56f74eada0a9aefbd4feb84e6c Signed-off-by: taojiang --- arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi index 29d253eacccc..ad01314b395a 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi @@ -274,7 +274,7 @@ "sensor_cam_mclk"; qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>; qcom,cam-power-seq-delay = <1 1 1 30 30 5>; - status = "ok"; + status = "disabled"; clocks = <&clock_gcc clk_mclk2_clk_src>, <&clock_gcc clk_gcc_camss_mclk2_clk>; clock-names = "cam_src_clk", "cam_clk"; @@ -409,7 +409,7 @@ qcom,sensor-position = <1>; qcom,sensor-mode = <0>; qcom,cci-master = <0>; - status = "ok"; + status = "disabled"; clocks = <&clock_gcc clk_mclk2_clk_src>, <&clock_gcc clk_gcc_camss_mclk2_clk>; clock-names = "cam_src_clk", "cam_clk"; From ffa8ade470ab9df17d0923791433265a7365ce9b Mon Sep 17 00:00:00 2001 From: Rahul Agarwal Date: Tue, 16 Jul 2019 14:45:49 +0530 Subject: [PATCH 161/281] defconfig: sa415m: Rename defconfigs and enable boot marker Rename debug and perf defconfigs to make it same as machine name for sa415m auto telematics target. Also enabling boot marker config. BOOT_MARKER will create a separate sys entry which contains all boot markers relevant to KPI measurements. Change-Id: Ia582cf99e12d85697eb5fef491c97d37b1b701eb Signed-off-by: Rahul Agarwal --- .../{sdxpoorwills-auto-perf_defconfig => sa415m-perf_defconfig} | 1 + .../configs/{sdxpoorwills-auto_defconfig => sa415m_defconfig} | 1 + 2 files changed, 2 insertions(+) rename arch/arm/configs/{sdxpoorwills-auto-perf_defconfig => sa415m-perf_defconfig} (99%) rename arch/arm/configs/{sdxpoorwills-auto_defconfig => sa415m_defconfig} (99%) diff --git a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig b/arch/arm/configs/sa415m-perf_defconfig similarity index 99% rename from arch/arm/configs/sdxpoorwills-auto-perf_defconfig rename to arch/arm/configs/sa415m-perf_defconfig index b04fd97db0be..a5170207954f 100644 --- a/arch/arm/configs/sdxpoorwills-auto-perf_defconfig +++ b/arch/arm/configs/sa415m-perf_defconfig @@ -372,6 +372,7 @@ CONFIG_IOMMU_DEBUG_TRACKING=y CONFIG_IOMMU_TESTS=y CONFIG_QCOM_SCM=y CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_BOOT_TIME_MARKER=y CONFIG_QCOM_WATCHDOG_V2=y CONFIG_QCOM_MEMORY_DUMP_V2=y CONFIG_QCOM_BUS_SCALING=y diff --git a/arch/arm/configs/sdxpoorwills-auto_defconfig b/arch/arm/configs/sa415m_defconfig similarity index 99% rename from arch/arm/configs/sdxpoorwills-auto_defconfig rename to arch/arm/configs/sa415m_defconfig index 3d0cca3cb4b9..e10d4ef1bf15 100644 --- a/arch/arm/configs/sdxpoorwills-auto_defconfig +++ b/arch/arm/configs/sa415m_defconfig @@ -402,6 +402,7 @@ CONFIG_IOMMU_DEBUG_TRACKING=y CONFIG_IOMMU_TESTS=y CONFIG_QCOM_SCM=y CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_BOOT_TIME_MARKER=y CONFIG_QCOM_WATCHDOG_V2=y CONFIG_QCOM_MEMORY_DUMP_V2=y CONFIG_QCOM_BUS_SCALING=y From 16d00a288b235440613d2b9669e83940b9733ce6 Mon Sep 17 00:00:00 2001 From: Yuan Zhao Date: Fri, 26 Jul 2019 13:16:38 +0800 Subject: [PATCH 162/281] defconfig: Enable LT9611 drvier for SDM845 RB3 Enable defconfig for LT9611 driver support. Change-Id: I2ef5558452eb5bd27d725b93cd18c1cde2192bc2 Signed-off-by: Yuan Zhao --- arch/arm64/configs/sdm845-perf_defconfig | 1 + arch/arm64/configs/sdm845_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index f62a85a42156..4689f69013f1 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -392,6 +392,7 @@ CONFIG_QCOM_KGSL=y CONFIG_DRM=y CONFIG_DRM_SDE_EVTLOG_DEBUG=y CONFIG_DRM_SDE_RSC=y +CONFIG_DRM_LT_LT9611=y CONFIG_FB_VIRTUAL=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BACKLIGHT_CLASS_DEVICE=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index 9f6dba1f759f..e9eb7d1ba10c 100644 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -397,6 +397,7 @@ CONFIG_QCOM_KGSL=y CONFIG_DRM=y CONFIG_DRM_SDE_EVTLOG_DEBUG=y CONFIG_DRM_SDE_RSC=y +CONFIG_DRM_LT_LT9611=y CONFIG_FB_VIRTUAL=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BACKLIGHT_CLASS_DEVICE=y From 4b058d07da56ad2d460ba91d2cdc3aa398b1c270 Mon Sep 17 00:00:00 2001 From: Yuan Zhao Date: Mon, 15 Jul 2019 19:59:47 +0800 Subject: [PATCH 163/281] ARM: dts: msm: Enable LT9611 for SDM845 RB3 RB3 used LT9611 external brdige for the primary display. Enable LT9611 support. Change-Id: I655aebd673c482571702849755018058c8b307de Signed-off-by: Yuan Zhao --- arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi | 15 +++ .../boot/dts/qcom/sdm845-sde-display.dtsi | 23 +++++ arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi | 93 +++++++++++++++++++ 3 files changed, 131 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi index a7a234a3670e..86320c349e75 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi @@ -893,6 +893,21 @@ }; }; + ext_bridge_mux { + lt9611_pins: lt9611_pins { + mux { + pins = "gpio84", "gpio128", "gpio89"; + function = "gpio"; + }; + + config { + pins = "gpio84", "gpio128", "gpio89"; + bias-disable = <0>; /* no pull */ + drive-strength = <8>; + }; + }; + }; + sec_aux_pcm { sec_aux_pcm_sleep: sec_aux_pcm_sleep { mux { diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi index 7735237e95ff..aa3976d33c32 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi @@ -527,6 +527,29 @@ ibb-supply = <&ibb_regulator>; }; + ext_dsi_bridge_display: qcom,dsi-display@19 { + compatible = "qcom,dsi-display"; + label = "ext_dsi_bridge_display"; + qcom,display-type = "primary"; + + qcom,dsi-ctrl = <&mdss_dsi0>; + qcom,dsi-phy = <&mdss_dsi_phy0>; + clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>, + <&mdss_dsi0_pll PCLK_MUX_0_CLK>; + clock-names = "mux_byte_clk", "mux_pixel_clk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ext_dsi_out: endpoint { + }; + }; + }; + }; + sde_wb: qcom,wb-display@0 { compatible = "qcom,wb-display"; cell-index = <0>; diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi index e1159d3ca914..cf84ecf74997 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi @@ -204,3 +204,96 @@ &ipa_hw { status="disabled"; }; + +&dsi_nt35597_truly_dsc_cmd_display { + /delete-property/ qcom,dsi-display-active; +}; + +&mdss_mdp { + bridges = <<9611>; +}; + +&soc { + lt9611_vcc_eldo: lt9611-gpio-regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "lt9611_vcc_eldo"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <233>; + gpio = <&tlmm 89 0>; + enable-active-high; + }; +}; + +&qupv3_se10_i2c { + status = "ok"; + lt9611: lt,lt9611@3b { + compatible = "lt,lt9611"; + reg = <0x3b>; + interrupt-parent = <&tlmm>; + interrupts = <84 0>; + interrupt-names = "lt_irq"; + lt,irq-gpio = <&tlmm 84 0x0>; + lt,reset-gpio = <&tlmm 128 0x0>; + lt,non-pluggable; + lt,preferred-mode = "1920x1080"; + + pinctrl-names = "default"; + pinctrl-0 = <<9611_pins>; + + vdd-supply = <<9611_vcc_eldo>; + lt,supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + lt,supply-entry@0 { + reg = <0>; + lt,supply-name = "vdd"; + lt,supply-min-voltage = <1800000>; + lt,supply-max-voltage = <1800000>; + lt,supply-enable-load = <200000>; + lt,supply-post-on-sleep = <150>; + }; + }; + + lt,customize-modes { + lt,customize-mode-id@0 { + lt,mode-h-active = <1920>; + lt,mode-h-front-porch = <88>; + lt,mode-h-pulse-width = <44>; + lt,mode-h-back-porch = <148>; + lt,mode-h-active-high; + lt,mode-v-active = <1080>; + lt,mode-v-front-porch = <4>; + lt,mode-v-pulse-width = <5>; + lt,mode-v-back-porch = <36>; + lt,mode-v-active-high; + lt,mode-refresh-rate = <60>; + lt,mode-clock-in-khz = <148500>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + lt9611_in: endpoint { + remote-endpoint = <&ext_dsi_out>; + }; + }; + }; + }; +}; + +&ext_dsi_bridge_display { + qcom,dsi-display-active; + ports { + port@0 { + ext_dsi_out: endpoint { + remote-endpoint = <<9611_in>; + }; + }; + }; +}; From eb21d8acaccf440483d31a828561045ebeb91d98 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Fri, 26 Jul 2019 11:38:25 +0530 Subject: [PATCH 164/281] ARM: dts: msm: Setup two normal USB EPs in GSI mode for sa415m-ttp Configure two normal USB endpoints in GSI mode for RmNet LTE and CV2X combined usecase on SA415M TTP. Change-Id: I751dd29197ad19a5e67fccd3325719de35bfbb8e Signed-off-by: Ajay Agarwal --- arch/arm/boot/dts/qcom/sa415m-ttp.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi index 27d4437cb67d..1cf499e858a5 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi +++ b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi @@ -24,6 +24,9 @@ status = "okay"; qcom,connector-type-uAB; extcon = <0>, <0>, <0>, <&vbus_detect>; + dwc3@a600000 { + normal-eps-in-gsi-mode; + }; }; &soc { From 16e09e6ac33f486ea3de1706865b750ae4e8533e Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 25 Jul 2019 23:30:36 -0700 Subject: [PATCH 165/281] ARM: dts: msm: Set ethernet PHY reset delay for SA415M CCARD Set the Micrel PHY reset delay to 10 ms according to the specification of the chip. Change-Id: I4e9f489ec04a612931f241047785976bf9b46326 Signed-off-by: Gustavo Solaira --- arch/arm/boot/dts/qcom/sa415m-ccard.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi index d2e597da08bf..42676f0bdcae 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi +++ b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi @@ -151,6 +151,7 @@ /delete-property/ vreg_rgmii-supply; pinctrl-names = "default"; pinctrl-0 = <&vreg_rgmii_off_default>; + qcom,phy-reset-delay-msecs = <10>; }; &vreg_rgmii_io_pads { From 4d77c8c13a2f8d1d89b2c523724f2fe64c496217 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Fri, 26 Jul 2019 14:51:52 +0800 Subject: [PATCH 166/281] defconfig: disable dbgui on perf build for msm8937 If enable dbgui on performance build, qpss clock will be always on. so need to disable dbgui on performance build to avoid the power and performance issue. Change-Id: Ic0a24d8968c32677a0a8c688abd718ff53cd545a Signed-off-by: Yuanfang Zhang --- arch/arm/configs/msm8937-perf_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig index 36285ef66765..655d4db416b6 100755 --- a/arch/arm/configs/msm8937-perf_defconfig +++ b/arch/arm/configs/msm8937-perf_defconfig @@ -646,7 +646,6 @@ CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_QCOM_REPLICATOR=y -CONFIG_CORESIGHT_DBGUI=y CONFIG_CORESIGHT_STM=y CONFIG_CORESIGHT_TPDA=y CONFIG_CORESIGHT_TPDM=y From da7778bd498153420d16987452f8ec46f5604c43 Mon Sep 17 00:00:00 2001 From: Asish Bhattacharya Date: Sun, 30 Jun 2019 20:00:32 +0530 Subject: [PATCH 167/281] ASoC: msm: qdsp6v2: add support for AMR_WB_PLUS offload Add AMR_WB_PLUS to supported offload formats and send media format block through compress driver. Change-Id: I258dc05fd5b6442ef40a5d1d4538870c4ddcbe2e Signed-off-by: Asish Bhattacharya --- include/uapi/sound/compress_params.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/uapi/sound/compress_params.h b/include/uapi/sound/compress_params.h index c7d5b3484634..20431fef76a2 100644 --- a/include/uapi/sound/compress_params.h +++ b/include/uapi/sound/compress_params.h @@ -418,6 +418,9 @@ struct snd_dec_pcm { __u8 ch_map[MAX_PCM_DECODE_CHANNELS]; } __attribute__((packed, aligned(4))); +struct snd_dec_amrwb_plus { + __u32 bit_stream_fmt; +}; union snd_codec_options { struct snd_enc_wma wma; struct snd_enc_vorbis vorbis; @@ -431,6 +434,7 @@ union snd_codec_options { struct snd_dec_ape ape; struct snd_dec_aptx aptx_dec; struct snd_dec_pcm pcm_dec; + struct snd_dec_amrwb_plus amrwbplus; }; /** struct snd_codec_desc - description of codec capabilities From b7678704535be143b4011cd1159a500ea835c4e0 Mon Sep 17 00:00:00 2001 From: Mahesh Voorugonda Date: Mon, 22 Jul 2019 10:37:34 +0530 Subject: [PATCH 168/281] msm: vidc_3x: Add checks to avoid OOB access validate structures and payload sizes in the packet against packet size to avoid OOB access. Change-Id: I8bc3002e51a18e08b212b13af724480ec48994d7 Signed-off-by: Mahesh Voorugonda --- .../msm/vidc_3x/hfi_response_handler.c | 96 +++++++++++++++---- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c index 5dfb4427ba34..abf2ef1686f4 100644 --- a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c @@ -843,6 +843,20 @@ static enum vidc_status hfi_parse_init_done_properties( { enum vidc_status status = VIDC_ERR_NONE; u32 prop_id, next_offset; +#define VALIDATE_PROPERTY_STRUCTURE_SIZE(pkt_size, property_size) ({\ + if (pkt_size < property_size) { \ + status = VIDC_ERR_BAD_PARAM; \ + break; \ + } \ +}) + +#define VALIDATE_PROPERTY_PAYLOAD_SIZE(pkt_size, payload_size, \ + property_count) ({\ + if (pkt_size/payload_size < property_count) { \ + status = VIDC_ERR_BAD_PARAM; \ + break; \ + } \ +}) while (status == VIDC_ERR_NONE && num_properties && rem_bytes >= sizeof(u32)) { @@ -856,6 +870,9 @@ static enum vidc_status hfi_parse_init_done_properties( struct hfi_codec_mask_supported *prop = (struct hfi_codec_mask_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); codecs = prop->codecs; domain = prop->video_domains; @@ -869,11 +886,14 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_capability_supported_info *) (data_ptr + next_offset); - if ((rem_bytes - next_offset) < prop->num_capabilities * - sizeof(struct hfi_capability_supported)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - sizeof(u32), + sizeof(struct hfi_capability_supported), + prop->num_capabilities); + next_offset += sizeof(u32) + prop->num_capabilities * sizeof(struct hfi_capability_supported); @@ -894,10 +914,10 @@ static enum vidc_status hfi_parse_init_done_properties( char *fmt_ptr; struct hfi_uncompressed_plane_info *plane_info; - if ((rem_bytes - next_offset) < sizeof(*prop)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + num_format_entries = prop->format_entries; next_offset = sizeof(*prop); fmt_ptr = (char *)&prop->rg_format_info[0]; @@ -908,17 +928,19 @@ static enum vidc_status hfi_parse_init_done_properties( plane_info = (struct hfi_uncompressed_plane_info *) fmt_ptr; - if ((rem_bytes - next_offset) < - sizeof(*plane_info)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*plane_info)); + bytes_to_skip = sizeof(*plane_info) - sizeof(struct hfi_uncompressed_plane_constraints) + plane_info->num_planes * sizeof(struct hfi_uncompressed_plane_constraints); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + bytes_to_skip); fmt_ptr += bytes_to_skip; next_offset += bytes_to_skip; @@ -932,6 +954,13 @@ static enum vidc_status hfi_parse_init_done_properties( struct hfi_properties_supported *prop = (struct hfi_properties_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - sizeof(*prop) + + sizeof(u32), sizeof(u32), + prop->num_properties); next_offset += sizeof(*prop) - sizeof(u32) + prop->num_properties * sizeof(u32); num_properties--; @@ -948,6 +977,9 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_profile_level_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); ptr = (char *) &prop->rg_profile_level[0]; prof_count = prop->profile_count; next_offset += sizeof(u32); @@ -960,6 +992,9 @@ static enum vidc_status hfi_parse_init_done_properties( } while (prof_count) { prof_level = (struct hfi_profile_level *)ptr; + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prof_level)); capability. profile_level.profile_level[count].profile = prof_level->profile; @@ -976,6 +1011,9 @@ static enum vidc_status hfi_parse_init_done_properties( } case HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(struct hfi_interlace_format_supported)); next_offset += sizeof(struct hfi_interlace_format_supported); num_properties--; @@ -983,6 +1021,9 @@ static enum vidc_status hfi_parse_init_done_properties( } case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(struct hfi_nal_stream_format_supported)); next_offset += sizeof(struct hfi_nal_stream_format_supported); num_properties--; @@ -990,18 +1031,27 @@ static enum vidc_status hfi_parse_init_done_properties( } case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(u32)); next_offset += sizeof(u32); num_properties--; break; } case HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(u32)); next_offset += sizeof(u32); num_properties--; break; } case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(struct hfi_intra_refresh)); next_offset += sizeof(struct hfi_intra_refresh); num_properties--; @@ -1012,13 +1062,21 @@ static enum vidc_status hfi_parse_init_done_properties( struct hfi_buffer_alloc_mode_supported *prop = (struct hfi_buffer_alloc_mode_supported *) (data_ptr + next_offset); - + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); if (prop->num_entries >= 32) { dprintk(VIDC_ERR, "%s - num_entries: %d from f/w seems suspect\n", __func__, prop->num_entries); break; } + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - + sizeof(struct hfi_buffer_alloc_mode_supported) + + sizeof(u32), + sizeof(u32), + prop->num_entries); next_offset += sizeof(struct hfi_buffer_alloc_mode_supported) - sizeof(u32) + prop->num_entries * sizeof(u32); @@ -1036,8 +1094,12 @@ static enum vidc_status hfi_parse_init_done_properties( __func__, data_ptr, prop_id); break; } - rem_bytes -= next_offset; - data_ptr += next_offset; + if (rem_bytes > next_offset) { + rem_bytes -= next_offset; + data_ptr += next_offset; + } else { + rem_bytes = 0; + } } return status; From b7bbb31c28f451aa54069a7386d84f42a777ea5b Mon Sep 17 00:00:00 2001 From: Xipeng Gu Date: Tue, 16 Jul 2019 19:52:49 +0800 Subject: [PATCH 169/281] ARM: dts: msm: Enable RM69090 truly cmd mode panel support Add changes to: 1.add ldos for dsi and panel,configure PMIC gpio 12 as a fixed regulator and add it as panel power supply. 2.add panel properties for RM69090 truly command mode panel. Change-Id: I7c035bc4cd99f443373a4d5bc30df964146f68de Signed-off-by: Xipeng Gu --- .../dsi-panel-truly-rm69090-qvga-cmd.dtsi | 87 +++++++++++++++++++ .../qcom/sdm429-spyro-qrd-mdss-panels.dtsi | 9 ++ .../dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts | 29 +++++++ arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 20 ++++- .../boot/dts/qcom/sdm429w-regulator.dtsi | 12 +++ 5 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/dsi-panel-truly-rm69090-qvga-cmd.dtsi diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-truly-rm69090-qvga-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-truly-rm69090-qvga-cmd.dtsi new file mode 100644 index 000000000000..9c0ffc5ffdbe --- /dev/null +++ b/arch/arm64/boot/dts/qcom/dsi-panel-truly-rm69090-qvga-cmd.dtsi @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019, 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. + */ + +&mdss_mdp { + dsi_truly_rm69090_qvga_cmd: qcom,mdss_dsi_truly_rm69090_qvga_cmd { + qcom,mdss-dsi-panel-name = "rm69090 qvga cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <368>; + qcom,mdss-dsi-panel-height = <448>; + qcom,mdss-dsi-h-front-porch = <40>; + qcom,mdss-dsi-h-back-porch = <20>; + qcom,mdss-dsi-h-pulse-width = <2>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <8>; + qcom,mdss-dsi-v-front-porch = <6>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-pixel-packing = "tight"; + qcom,mdss-dsi-pixel-alignment = <0>; + qcom,mdss-dsi-on-command = [ + 15 01 00 00 00 00 02 FE 00 + 15 01 00 00 00 00 02 35 00 + 15 01 00 00 00 00 02 51 80 + 39 01 00 00 00 00 05 2A 00 10 01 7F + 39 01 00 00 00 00 05 2B 00 00 01 BF + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 40 00 02 29 00 + ]; + qcom,mdss-dsi-off-command = [ + 05 01 00 00 28 00 02 28 00 + 05 01 00 00 78 00 02 10 00 + 15 01 00 00 00 00 02 4F 01 + ]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-idle-on-command = [ + 05 01 00 00 00 00 01 39 /* Idle-Mode On */ + ]; + qcom,mdss-dsi-idle-off-command = [ + 05 01 00 00 00 00 01 38 /* Idle-Mode Off */ + ]; + qcom,mdss-dsi-idle-on-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-idle-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-panel-timings = [7d 25 1d 00 37 33 + 22 27 1e 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x09>; + qcom,mdss-dsi-t-clk-pre = <0x2c>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <255>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-reset-sequence = <1 1>, <0 12>, <1 12>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi index 247d312216a7..3fecf16aefb0 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi @@ -12,6 +12,7 @@ */ #include "dsi-panel-edo-rm67162-qvga-cmd.dtsi" +#include "dsi-panel-truly-rm69090-qvga-cmd.dtsi" &soc { dsi_pm660_panel_pwr_supply: dsi_pm660_panel_pwr_supply { @@ -83,3 +84,11 @@ qcom,partial-update-enabled; qcom,panel-roi-alignment = <2 2 4 2 320 2>; }; + +&dsi_truly_rm69090_qvga_cmd { + /delete-property/ qcom,mdss-dsi-panel-timings; + qcom,mdss-dsi-panel-timings-phy-12nm = [04 04 01 08 00 03 01 0D]; + qcom,panel-supply-entries = <&dsi_pm660_panel_pwr_supply>; + qcom,esd-check-enabled; + qcom,mdss-dsi-panel-status-check-mode = "te_signal_check"; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts index f70c45834fed..c579a85624b7 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts @@ -39,3 +39,32 @@ &sdhc_2 { cd-gpios = <&tlmm 67 0x1>; }; + +&mdss_dsi { + vddio-supply = <&L12A>; /* 1.8v */ +}; + +&mdss_dsi0_pll { + vddio-supply = <&L12A>; /* 1.8V */ +}; + +&mdss_dsi1_pll { + vddio-supply = <&L12A>; /* 1.8V */ +}; + +&mdss_dsi0 { + /delete-property/ qcom,platform-enable-gpio; + vdd-supply = <&vreg_d322_vdd>; /* 2.8v */ + qcom,dsi-pref-prim-pan = <&dsi_truly_rm69090_qvga_cmd>; +}; + +&pm660_gpios { + gpio@cb00 { + status = "ok"; + qcom,mode = <1>; + qcom,vin-sel = <0>; + qcom,src-sel = <0>; + qcom,master-en = <1>; + qcom,out-strength = <2>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index caab464ccf5b..e9d6c3e0ab4b 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -370,9 +370,23 @@ /* over-write the PM660 GPIO mappings for 429w */ &pm660_gpios { - interrupts = <0x0 0xc3 0 IRQ_TYPE_NONE>; - interrupt-names = "pm660_gpio4"; - qcom,gpios-disallowed = <1 2 3 5 6 7 8 9 10 11 12 13>; + interrupts = <0x0 0xc3 0 IRQ_TYPE_NONE>, + <0x0 0xcb 0 IRQ_TYPE_NONE>; + interrupt-names = "pm660_gpio4", "pm660_gpio12"; + qcom,gpios-disallowed = <1 2 3 5 6 7 8 9 10 11 13>; +}; + +/* pm660 gpio pinctrl configuration */ +&pm660_gpios { + /* GPIO 12 (DISPLAY_AVDD_EN) */ + vreg_d322 { + vreg_regulator_d322: vreg_regulator-d322 { + pins = "gpio12"; + function = "normal"; + output-enable; + qcom,drive-strength = <2>; + }; + }; }; &pm660_vadc { diff --git a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi index b4dd41eaef08..064e662db73e 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi @@ -358,4 +358,16 @@ regulator-min-microvolt = <2950000>; regulator-max-microvolt = <2950000>; }; + + vreg_d322_vdd: d322-vdd-fixed-regulator { + compatible = "regulator-fixed"; + regulator-name = "d322_vreg"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + startup-delay-us = <400>; + enable-active-high; + gpio = <&pm660_gpios 12 0>; + status = "okay"; + regulator-boot-on; + }; }; From eafad907eb7fa1a45e42384acea60a9924d18bf1 Mon Sep 17 00:00:00 2001 From: Fei Mao Date: Thu, 18 Jul 2019 14:53:54 +0800 Subject: [PATCH 170/281] ARM: dts: msm: Add touch for SDM429W spyro WDP Add device node for touch IC for SDM429W spyro WDP devices. Change-Id: I5037c328bfe6198be9c0e94a9c44cf6b2459d350 Signed-off-by: Fei Mao --- .../dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts index c579a85624b7..a32985e6bdb0 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts @@ -68,3 +68,32 @@ qcom,out-strength = <2>; }; }; + +&i2c_4 { + status = "ok"; + + tsc@24 { + cy,core { + cy,mt { + cy,name = "cyttsp5_mt"; + + cy,inp_dev_name = "cyttsp5_mt"; + cy,flags = <0x8>; + cy,abs = + <0x35 0 368 0 0 + 0x36 0 448 0 0 + 0x3a 0 255 0 0 + 0xffff 0 255 0 0 + 0x39 0 15 0 0 + 0x30 0 255 0 0 + 0x31 0 255 0 0 + 0x34 0xffffff81 127 0 0 + 0x37 0 1 0 0 + 0x3b 0 255 0 0>; + + }; + + }; + }; + +}; From 28d37884f11c30bc11b3a07fd6c006b73d4a74b4 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Tue, 23 Jul 2019 09:54:39 +0530 Subject: [PATCH 171/281] ARM: dts: msm: Add speed-bin 5 support for SDM439 Spyro derives its CPR configuration from SDM439. Add CPR support for speed-bin 5 for Spyro. While at it, update the CPR voltage step to 4mV to match PMIC. Change-Id: Ia2db2ed840a4ab9032366042f00a1a9ac086d912 Signed-off-by: Anirudh Ghayal --- arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi | 1 + arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi index b4dd41eaef08..4b521b220903 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi @@ -338,6 +338,7 @@ &soc { regulator@b018000 { vdd-apc-supply = <&pm660_s3>; + qcom,cpr-apc-volt-step = <4000>; }; vreg_sd_pad: vreg_sd_pad { diff --git a/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi index 750cedbe0261..c04017a2cb3a 100644 --- a/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, 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 @@ -467,7 +467,8 @@ qcom,cpr-speed-bin-max-corners = <0 (-1) 1 2 5>, <1 (-1) 1 2 5>, - <4 (-1) 1 2 6>; + <4 (-1) 1 2 6>, + <5 (-1) 1 2 6>; qcom,cpr-fuse-revision = <69 39 3 0>; qcom,cpr-quot-adjust-scaling-factor-max = <0 1400 1400>; qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>; From d89faed9b12abb04210b5c9ca65ad56b7f21626a Mon Sep 17 00:00:00 2001 From: Tapas Dey Date: Thu, 18 Jul 2019 13:39:13 +0530 Subject: [PATCH 172/281] ARM: dts: msm: Add NFC device node for Spyro Device node changes required on Spyro describing the GPIO configuration for Nfc controller chip. Modified corresponding Nfc device node for DVT platform. Change-Id: I42578eb45a25c711835383dae1f3d71bd38bc1f2 Signed-off-by: Tapas Dey --- .../boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi index cc104988b351..dda1f843338d 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi @@ -252,6 +252,43 @@ }; +&pm660_gpios { + nfc_clk { + nfc_clk_default: nfc_clk_default { + pins = "gpio4"; + function = "normal"; + input-enable; + power-source = <1>; + }; + }; +}; + +&i2c_5 { /* BLSP2 QUP1 (NFC) */ + #address-cells = <1>; + #size-cells = <0>; + + status = "ok"; + nq@28 { + compatible = "qcom,nq-nci"; + reg = <0x28>; + qcom,nq-irq = <&tlmm 17 0x00>; + qcom,nq-ven = <&tlmm 16 0x00>; + qcom,nq-firm = <&tlmm 130 0x00>; + qcom,nq-clkreq = <&pm660_gpios 4 0x00>; + qcom,nq-esepwr = <&tlmm 93 0x00>; + interrupt-parent = <&tlmm>; + qcom,clk-src = "BBCLK2"; + interrupts = <17 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active", "nfc_suspend"; + pinctrl-0 = <&nfc_int_active &nfc_disable_active + &nfc_clk_default>; + pinctrl-1 = <&nfc_int_suspend &nfc_disable_suspend>; + clocks = <&clock_gcc clk_bb_clk2_pin>; + clock-names = "ref_clk"; + }; +}; + &tlmm { pmx_ts_int_active { ts_int_active: ts_int_active { From 4adc058511b5381f9d8695dceca5825bd6127213 Mon Sep 17 00:00:00 2001 From: Sanjay Dwivedi Date: Fri, 26 Jul 2019 14:43:15 +0530 Subject: [PATCH 173/281] ARM: dts: Enable sequential load for non-secure pil loader targets Non Secure pil loader targets are enabled with sequential load of pil firmware blobs image, parallel pil loading is not supported. Change-Id: Id0254a312e55e50b69f760a1af304d7e4f040e58 Signed-off-by: Sanjay Dwivedi --- arch/arm64/boot/dts/qcom/msm8909.dtsi | 1 + arch/arm64/boot/dts/qcom/msm8917.dtsi | 3 ++- arch/arm64/boot/dts/qcom/msm8937.dtsi | 1 + arch/arm64/boot/dts/qcom/msm8953.dtsi | 3 ++- arch/arm64/boot/dts/qcom/sdm670.dtsi | 1 + 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8909.dtsi b/arch/arm64/boot/dts/qcom/msm8909.dtsi index 01f17902da07..826a3a6ee8b8 100644 --- a/arch/arm64/boot/dts/qcom/msm8909.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8909.dtsi @@ -1914,6 +1914,7 @@ qcom,firmware-name = "modem"; qcom,pil-self-auth; + qcom,sequential-fw-load; qcom,sysmon-id = <0>; qcom,ssctl-instance-id = <0x12>; qcom,reset-clk; diff --git a/arch/arm64/boot/dts/qcom/msm8917.dtsi b/arch/arm64/boot/dts/qcom/msm8917.dtsi index e1ec68586624..06730134cf2c 100644 --- a/arch/arm64/boot/dts/qcom/msm8917.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8917.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, 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 @@ -1337,6 +1337,7 @@ qcom,firmware-name = "modem"; qcom,pil-self-auth; + qcom,sequential-fw-load; qcom,override-acc-1 = <0x80800000>; qcom,sysmon-id = <0>; qcom,ssctl-instance-id = <0x12>; diff --git a/arch/arm64/boot/dts/qcom/msm8937.dtsi b/arch/arm64/boot/dts/qcom/msm8937.dtsi index 5158729eb740..e8e7a63d49de 100644 --- a/arch/arm64/boot/dts/qcom/msm8937.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8937.dtsi @@ -1608,6 +1608,7 @@ qcom,pil-mss-memsetup; qcom,firmware-name = "modem"; qcom,pil-self-auth; + qcom,sequential-fw-load; qcom,override-acc-1 = <0x80800000>; qcom,sysmon-id = <0>; qcom,ssctl-instance-id = <0x12>; diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi index b1cfed4954d8..6c9a9899baeb 100644 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, 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 @@ -2007,6 +2007,7 @@ qcom,pil-mss-memsetup; qcom,firmware-name = "modem"; qcom,pil-self-auth; + qcom,sequential-fw-load; qcom,sysmon-id = <0>; qcom,ssctl-instance-id = <0x12>; qcom,qdsp6v56-1-10; diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi index 021549cf5cac..1e25e3be7ebc 100644 --- a/arch/arm64/boot/dts/qcom/sdm670.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi @@ -2224,6 +2224,7 @@ vdd_mss-uV = ; qcom,firmware-name = "modem"; qcom,pil-self-auth; + qcom,sequential-fw-load; qcom,sysmon-id = <0>; qcom,minidump-id = <3>; qcom,ssctl-instance-id = <0x12>; From 9927d25daf80119cc22e538b035666fadab885d5 Mon Sep 17 00:00:00 2001 From: Sriharsha Allenki Date: Mon, 22 Jul 2019 17:05:45 +0530 Subject: [PATCH 174/281] usb: ccid: Fix possible scenario of double unlock There is a possible case of double unlock of the spinlock ccid_dev->lock when the ccid daemon is trying to write while the disable is being processed. Fix this by going to done once the unlock is done. Also, remove the unnecessary goto at the end of the function call. Change-Id: Idab0801cbf9db91e18d933c8088a4af479b8691f Signed-off-by: Sriharsha Allenki --- drivers/usb/gadget/function/f_ccid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_ccid.c b/drivers/usb/gadget/function/f_ccid.c index 631597e7ba2e..33490a880028 100644 --- a/drivers/usb/gadget/function/f_ccid.c +++ b/drivers/usb/gadget/function/f_ccid.c @@ -857,9 +857,9 @@ static ssize_t ccid_bulk_write(struct file *fp, const char __user *buf, &bulk_dev->tx_idle))) ccid_request_free(req, ccid_dev->in); r = -ENODEV; + goto done; } spin_unlock_irqrestore(&ccid_dev->lock, flags); - goto done; } done: pr_debug("ccid_bulk_write returning %d\n", r); From f942dd4058a316821d5160084d1933006419ebbb Mon Sep 17 00:00:00 2001 From: Neng Chen Date: Mon, 29 Jul 2019 19:57:22 +0800 Subject: [PATCH 175/281] ARM: dts: msm: change camera csid power supply USB and DSI use L6, and camera csid also uses this LDO. So need to change the power supply to meet the new range. Change-Id: I61cf5e9a344739d9d8f6e4da77ac87ac86d6420e Signed-off-by: Neng Chen --- arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index caab464ccf5b..a702fd7cabe1 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -206,21 +206,21 @@ qcom,csid@1b30000 { /delete-property/ qcom,mipi-csi-vdd-supply; /delete-property/ qcom,csi-vdd-voltage; - qcom,csi-vdd-voltage = <928000>; + qcom,csi-vdd-voltage = <800000>; qcom,mipi-csi-vdd-supply = <&pm660_l6>; }; qcom,csid@1b30400 { /delete-property/ qcom,mipi-csi-vdd-supply; /delete-property/ qcom,csi-vdd-voltage; - qcom,csi-vdd-voltage = <928000>; + qcom,csi-vdd-voltage = <800000>; qcom,mipi-csi-vdd-supply = <&pm660_l6>; }; qcom,csid@1b30800 { /delete-property/ qcom,mipi-csi-vdd-supply; /delete-property/ qcom,csi-vdd-voltage; - qcom,csi-vdd-voltage = <928000>; + qcom,csi-vdd-voltage = <800000>; qcom,mipi-csi-vdd-supply = <&pm660_l6>; }; From 41fbc5eb9515daabccbae9724020eccef8b352bf Mon Sep 17 00:00:00 2001 From: Prakasha Nayak Date: Fri, 22 Mar 2019 20:45:41 +0530 Subject: [PATCH 176/281] msm: camera: isp: Handle Dual VFE incase of event mismatch Handle event counter mismatch comes due to scheduling issues Change-Id: I2efc53e9487629b008f38502c58b641a2b68952c Signed-off-by: Prakasha Nayak --- .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 53 ++++++++++++++- .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h | 64 ++++++++++--------- .../isp_hw_mgr/isp_hw/include/cam_isp_hw.h | 3 +- .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c | 3 +- .../vfe_hw/vfe_top/cam_vfe_camif_ver2.c | 39 ++++++++++- .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c | 19 +++++- 6 files changed, 144 insertions(+), 37 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 63fc442bd205..56ef199db5b5 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -2159,6 +2159,7 @@ static int cam_ife_mgr_restart_hw(void *start_hw_args) } CAM_DBG(CAM_ISP, "START CID SRC ... in ctx id:%d", ctx->ctx_index); + ctx->dual_ife_irq_mismatch_cnt = 0; /* Start IFE root node: do nothing */ CAM_DBG(CAM_ISP, "Exit...(success)"); return 0; @@ -2378,6 +2379,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv, memset(ctx->base, 0, sizeof(ctx->base)); /* release cdm handle */ + ctx->dual_ife_irq_mismatch_cnt = 0; cam_cdm_release(ctx->cdm_handle); /* clean context */ @@ -2968,6 +2970,36 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet, } } +static void cam_ife_mgr_ctx_irq_dump(struct cam_ife_hw_mgr_ctx *ctx) +{ + struct cam_ife_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + struct cam_isp_hw_get_cmd_update cmd_update; + int i = 0; + + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { + if (hw_mgr_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT) + continue; + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + switch (hw_mgr_res->hw_res[i]->res_id) { + case CAM_ISP_HW_VFE_IN_CAMIF: + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + cmd_update.res = hw_mgr_res->hw_res[i]; + cmd_update.cmd_type = + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP; + hw_intf->hw_ops.process_cmd(hw_intf->hw_priv, + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, + &cmd_update, sizeof(cmd_update)); + break; + default: + break; + } + } + } +} + static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) { int rc = 0; @@ -3618,11 +3650,26 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( (event_cnt[core_idx1] && (event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) { + if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt > 10) { + rc = -1; + return rc; + } + CAM_ERR_RATE_LIMIT(CAM_ISP, - "One of the VFE cound not generate hw event %d", + "One of the VFE could not generate hw event %d", hw_event_type); - rc = -1; - return rc; + if (event_cnt[core_idx0] >= 2) { + event_cnt[core_idx0]--; + ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++; + } + if (event_cnt[core_idx1] >= 2) { + event_cnt[core_idx1]--; + ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++; + } + + if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt == 1) + cam_ife_mgr_ctx_irq_dump(ife_hw_mgr_ctx); + rc = 0; } CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d", diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h index 9bfa34fe91ab..3a910b420098 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -97,35 +97,38 @@ struct cam_ife_hw_mgr_debug { /** * struct cam_vfe_hw_mgr_ctx - IFE HW manager Context object * - * @list: used by the ctx list. - * @common: common acquired context data - * @ctx_index: acquired context id. - * @hw_mgr: IFE hw mgr which owns this context - * @ctx_in_use: flag to tell whether context is active - * @res_list_ife_in: Starting resource(TPG,PHY0, PHY1...) Can only be - * one. - * @res_list_csid: CSID resource list - * @res_list_ife_src: IFE input resource list - * @res_list_ife_out: IFE output resoruces array - * @free_res_list: Free resources list for the branch node - * @res_pool: memory storage for the free resource list - * @irq_status0_mask: irq_status0_mask for the context - * @irq_status1_mask: irq_status1_mask for the context - * @base device base index array contain the all IFE HW - * instance associated with this context. - * @num_base number of valid base data in the base array - * @cdm_handle cdm hw acquire handle - * @cdm_ops cdm util operation pointer for building - * cdm commands - * @cdm_cmd cdm base and length request pointer - * @sof_cnt sof count value per core, used for dual VFE - * @epoch_cnt epoch count value per core, used for dual VFE - * @eof_cnt eof count value per core, used for dual VFE - * @overflow_pending flat to specify the overflow is pending for the - * context - * @is_rdi_only_context flag to specify the context has only rdi resource - * @config_done_complete indicator for configuration complete - * @init_done indicate whether init hw is done + * @list: used by the ctx list. + * @common: common acquired context data + * @ctx_index: acquired context id. + * @hw_mgr: IFE hw mgr which owns this context + * @ctx_in_use: flag to tell whether context is active + * @res_list_ife_in: Starting resource(TPG,PHY0, PHY1...) Can only be + * one. + * @res_list_csid: CSID resource list + * @res_list_ife_src: IFE input resource list + * @res_list_ife_out: IFE output resoruces array + * @free_res_list: Free resources list for the branch node + * @res_pool: memory storage for the free resource list + * @irq_status0_mask: irq_status0_mask for the context + * @irq_status1_mask: irq_status1_mask for the context + * @base device base index array contain the all IFE HW + * instance associated with this context. + * @num_base number of valid base data in the base array + * @cdm_handle cdm hw acquire handle + * @cdm_ops cdm util operation pointer for building + * cdm commands + * @cdm_cmd cdm base and length request pointer + * @sof_cnt sof count value per core, used for dual VFE + * @epoch_cnt epoch count value per core, used for dual VFE + * @eof_cnt eof count value per core, used for dual VFE + * @overflow_pending flag to specify the overflow is pending for the + * context + * @is_rdi_only_context flag to specify the context has only rdi + * resource + * @config_done_complete indicator for configuration complete + * @init_done indicate whether init hw is done + * @dual_ife_irq_mismatch_cnt irq mismatch count value per core, used for + * dual VFE */ struct cam_ife_hw_mgr_ctx { struct list_head list; @@ -160,6 +163,7 @@ struct cam_ife_hw_mgr_ctx { uint32_t is_rdi_only_context; struct completion config_done_complete; bool init_done; + uint32_t dual_ife_irq_mismatch_cnt; }; /** diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index 54aa4c23b4d1..2b814ac27d02 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -97,6 +97,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_GET_REG_DUMP, CAM_ISP_HW_CMD_SOF_IRQ_DEBUG, CAM_ISP_HW_CMD_SET_CAMIF_DEBUG, + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, CAM_ISP_HW_CMD_MAX, }; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c index f6becfbf41a1..d8af62794f9c 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -696,6 +696,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_CLOCK_UPDATE: case CAM_ISP_HW_CMD_BW_UPDATE: case CAM_ISP_HW_CMD_BW_CONTROL: + case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: rc = core_info->vfe_top->hw_ops.process_cmd( core_info->vfe_top->top_priv, cmd_type, cmd_args, arg_size); diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c index fc257ecaa604..528eb6dcabfb 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -378,6 +378,40 @@ static int cam_vfe_camif_reg_dump( return rc; } +static int cam_vfe_camif_irq_reg_dump( + struct cam_isp_resource_node *camif_res) +{ + struct cam_vfe_mux_camif_data *camif_priv; + struct cam_vfe_soc_private *soc_private; + int rc = 0; + + if (!camif_res) { + CAM_ERR(CAM_ISP, "Error! Invalid input arguments\n"); + return -EINVAL; + } + + if ((camif_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) || + (camif_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)) { + CAM_ERR(CAM_ISP, "Error! Invalid state\n"); + return 0; + } + + camif_priv = (struct cam_vfe_mux_camif_data *)camif_res->res_priv; + soc_private = camif_priv->soc_info->soc_private; + + CAM_INFO(CAM_ISP, + "Core Id =%d Mask reg: offset 0x%x val 0x%x offset 0x%x val 0x%x", + camif_priv->hw_intf->hw_idx, + 0x5c, cam_io_r_mb(camif_priv->mem_base + 0x5c), + 0x60, cam_io_r_mb(camif_priv->mem_base + 0x60)); + CAM_INFO(CAM_ISP, + "Core Id =%d Status reg: offset 0x%x val 0x%x offset 0x%x val 0x%x", + camif_priv->hw_intf->hw_idx, + 0x6c, cam_io_r_mb(camif_priv->mem_base + 0x6c), + 0x70, cam_io_r_mb(camif_priv->mem_base + 0x70)); + return rc; +} + static int cam_vfe_camif_resource_stop( struct cam_isp_resource_node *camif_res) { @@ -465,6 +499,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node, (struct cam_vfe_mux_camif_data *)rsrc_node->res_priv; camif_priv->camif_debug = *((uint32_t *)cmd_args); break; + case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: + rc = cam_vfe_camif_irq_reg_dump(rsrc_node); + break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c index 47a04388ea8d..7ec11e8c5007 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -379,6 +379,19 @@ static int cam_vfe_top_mux_get_reg_update( return -EINVAL; } +static int cam_vfe_get_irq_register_dump( + struct cam_vfe_top_ver2_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + struct cam_isp_hw_get_cmd_update *cmd_update = cmd_args; + + if (cmd_update->res->process_cmd) + cmd_update->res->process_cmd(cmd_update->res, + CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, cmd_args, arg_size); + + return 0; +} + int cam_vfe_top_get_hw_caps(void *device_priv, void *get_hw_cap_args, uint32_t arg_size) { @@ -657,6 +670,10 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_BW_CONTROL: rc = cam_vfe_top_bw_control(top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: + rc = cam_vfe_get_irq_register_dump(top_priv, + cmd_args, arg_size); + break; default: rc = -EINVAL; CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type); From 051a6e26d2b71e7341e6887700cf9512dc8ad1c6 Mon Sep 17 00:00:00 2001 From: Nagireddy Annem Date: Thu, 18 Jul 2019 14:46:50 +0530 Subject: [PATCH 177/281] arm: dts: msm: Add dts support for apq8009w 1GB DDR Add dts support for apq8009w 1GB DDR. Change-Id: I627c2ce59a7e16c30d612b395319fff00960a08a Signed-off-by: Nagireddy Annem --- arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts b/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts index 1f91311ead1d..e23d1a6e19d4 100644 --- a/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts +++ b/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts @@ -26,7 +26,8 @@ qcom,msm-id = <265 0>, <301 0>; qcom,board-id = <8 0x10f>, - <8 0x117>; + <8 0x117>, + <8 0x17>; qcom,pmic-id = <0x0001001b 0x0 0x0 0x0>, <0x0001011b 0x0 0x0 0x0>; }; From dbe3fbfebdd8d24d8b4a1c37f8ee04ae79f4a323 Mon Sep 17 00:00:00 2001 From: zhaochen Date: Tue, 30 Jul 2019 14:42:02 +0800 Subject: [PATCH 178/281] ARM: dts: msm: add sequential firmware load to spyro Add sequential-fw-load in pil_mss to fix the modem firmware load problem. Change-Id: I2d1c1b0fbdbb9a8ade51143de16c145483e306d0 Signed-off-by: Zhaoyuan Cheng --- arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi index 80f89d908639..a951c7d2e997 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi @@ -13,3 +13,7 @@ #include "sdm429.dtsi" #include "sdm429w-pm660.dtsi" + +&pil_mss { + qcom,sequential-fw-load; +}; From a9da307abd85c6656750955f6f9b70f8180c3587 Mon Sep 17 00:00:00 2001 From: Chinmay Agarwal Date: Mon, 29 Jul 2019 19:15:30 +0530 Subject: [PATCH 179/281] defconfig: sdm670: Enable missing networking options Android Kernel Net Testing requires additional configuration options to work properly. Enable the following- SYN_COOKIES INET_UDP_DIAG IP_SCTP INET_SCTP_DIAG Change-Id: I89f0fdaa6adb6ae532933b2b89eed7e7068596de Signed-off-by: Chinmay Agarwal --- arch/arm/configs/sdm670-perf_defconfig | 5 ++++- arch/arm/configs/sdm670_defconfig | 5 ++++- arch/arm64/configs/sdm670-perf_defconfig | 4 +++- arch/arm64/configs/sdm670_defconfig | 4 +++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/arch/arm/configs/sdm670-perf_defconfig b/arch/arm/configs/sdm670-perf_defconfig index d597ff072851..c67ee518542d 100755 --- a/arch/arm/configs/sdm670-perf_defconfig +++ b/arch/arm/configs/sdm670-perf_defconfig @@ -99,9 +99,11 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y +CONFIG_INET_UDP_DIAG=y CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y @@ -117,7 +119,6 @@ CONFIG_NF_CONNTRACK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=y CONFIG_NF_CONNTRACK_FTP=y @@ -163,6 +164,7 @@ CONFIG_NETFILTER_XT_MATCH_POLICY=y CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y CONFIG_NETFILTER_XT_MATCH_QUOTA=y CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set CONFIG_NETFILTER_XT_MATCH_SOCKET=y CONFIG_NETFILTER_XT_MATCH_STATE=y CONFIG_NETFILTER_XT_MATCH_STATISTIC=y @@ -196,6 +198,7 @@ CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y CONFIG_BRIDGE_NF_EBTABLES=y CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_IP_SCTP=y CONFIG_L2TP=y CONFIG_L2TP_V3=y CONFIG_L2TP_IP=y diff --git a/arch/arm/configs/sdm670_defconfig b/arch/arm/configs/sdm670_defconfig index 83aaf9b64952..6a92eb410bcd 100755 --- a/arch/arm/configs/sdm670_defconfig +++ b/arch/arm/configs/sdm670_defconfig @@ -102,9 +102,11 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y +CONFIG_INET_UDP_DIAG=y CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y @@ -120,7 +122,6 @@ CONFIG_NF_CONNTRACK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=y CONFIG_NF_CONNTRACK_FTP=y @@ -167,6 +168,7 @@ CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y CONFIG_NETFILTER_XT_MATCH_QUOTA=y CONFIG_NETFILTER_XT_MATCH_QUOTA2=y CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set CONFIG_NETFILTER_XT_MATCH_SOCKET=y CONFIG_NETFILTER_XT_MATCH_STATE=y CONFIG_NETFILTER_XT_MATCH_STATISTIC=y @@ -200,6 +202,7 @@ CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y CONFIG_BRIDGE_NF_EBTABLES=y CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_IP_SCTP=y CONFIG_L2TP=y CONFIG_L2TP_DEBUGFS=y CONFIG_L2TP_V3=y diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig index d75479ee755f..325ea8cd40d8 100755 --- a/arch/arm64/configs/sdm670-perf_defconfig +++ b/arch/arm64/configs/sdm670-perf_defconfig @@ -104,6 +104,7 @@ CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_NET_IPGRE_DEMUX=y +CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y @@ -125,7 +126,6 @@ CONFIG_NF_CONNTRACK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=y CONFIG_NF_CONNTRACK_FTP=y @@ -172,6 +172,7 @@ CONFIG_NETFILTER_XT_MATCH_POLICY=y CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y CONFIG_NETFILTER_XT_MATCH_QUOTA=y CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set CONFIG_NETFILTER_XT_MATCH_SOCKET=y CONFIG_NETFILTER_XT_MATCH_STATE=y CONFIG_NETFILTER_XT_MATCH_STATISTIC=y @@ -205,6 +206,7 @@ CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y CONFIG_BRIDGE_NF_EBTABLES=y CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_IP_SCTP=y CONFIG_L2TP=y CONFIG_L2TP_V3=y CONFIG_L2TP_IP=y diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig index 1eea89124a53..2948bdd685d1 100755 --- a/arch/arm64/configs/sdm670_defconfig +++ b/arch/arm64/configs/sdm670_defconfig @@ -109,6 +109,7 @@ CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_NET_IPGRE_DEMUX=y +CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y @@ -130,7 +131,6 @@ CONFIG_NF_CONNTRACK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_SCTP=y CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=y CONFIG_NF_CONNTRACK_FTP=y @@ -178,6 +178,7 @@ CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y CONFIG_NETFILTER_XT_MATCH_QUOTA=y CONFIG_NETFILTER_XT_MATCH_QUOTA2=y CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set CONFIG_NETFILTER_XT_MATCH_SOCKET=y CONFIG_NETFILTER_XT_MATCH_STATE=y CONFIG_NETFILTER_XT_MATCH_STATISTIC=y @@ -211,6 +212,7 @@ CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y CONFIG_BRIDGE_NF_EBTABLES=y CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_IP_SCTP=y CONFIG_L2TP=y CONFIG_L2TP_DEBUGFS=y CONFIG_L2TP_V3=y From 1b235ff0d0ff541e13ec57c3283fa69363495c07 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Tue, 25 Jun 2019 15:13:48 +0530 Subject: [PATCH 180/281] msm: mhi_dev: Add cv2x HW channel support in MHI driver CV2X channels are used to transfer latency sensitive information between host and modem using the IPA HW-accelerated path. Change-Id: I3fd15de5115c4e861469f19623a7d81893020f4a Signed-off-by: Rama Krishna Phani A --- drivers/platform/msm/mhi_dev/mhi.c | 26 +++++++++++++++++++------ drivers/platform/msm/mhi_dev/mhi.h | 1 + drivers/platform/msm/mhi_dev/mhi_hwio.h | 6 +++--- drivers/platform/msm/mhi_dev/mhi_mmio.c | 7 ++++++- drivers/platform/msm/mhi_dev/mhi_uci.c | 24 +++++++++++++++++++++++ include/linux/msm_mhi_dev.h | 6 ++++-- include/uapi/linux/mhi.h | 1 + 7 files changed, 59 insertions(+), 12 deletions(-) diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c index b70742b1aa91..905f13aafc98 100644 --- a/drivers/platform/msm/mhi_dev/mhi.c +++ b/drivers/platform/msm/mhi_dev/mhi.c @@ -44,7 +44,6 @@ #define MHI_RING_PRIMARY_EVT_ID 1 #define MHI_1K_SIZE 0x1000 /* Updated Specification for event start is NER - 2 and end - NER -1 */ -#define MHI_HW_ACC_EVT_RING_START 3 #define MHI_HW_ACC_EVT_RING_END 1 #define MHI_HOST_REGION_NUM 2 @@ -306,7 +305,7 @@ static void mhi_dev_get_erdb_db_cfg(struct mhi_dev *mhi, break; default: erdb_cfg->base = mhi->cfg.event_rings - - MHI_HW_ACC_EVT_RING_START; + (mhi->cfg.hw_event_rings); erdb_cfg->end = mhi->cfg.event_rings - MHI_HW_ACC_EVT_RING_END; break; @@ -496,17 +495,32 @@ static int mhi_hwc_chcmd(struct mhi_dev *mhi, uint chid, case MHI_DEV_RING_EL_START: connect_params.channel_id = chid; connect_params.sys.skip_ep_cfg = true; - if (chid == MHI_CLIENT_ADPL_IN) + + switch (chid) { + case MHI_CLIENT_ADPL_IN: connect_params.sys.client = IPA_CLIENT_MHI_DPL_CONS; - else if ((chid % 2) == 0x0) + break; + case MHI_CLIENT_IP_HW_0_OUT: connect_params.sys.client = IPA_CLIENT_MHI_PROD; - else + break; + case MHI_CLIENT_IP_HW_0_IN: connect_params.sys.client = IPA_CLIENT_MHI_CONS; + break; + case MHI_CLIENT_IP_HW_1_OUT: + connect_params.sys.client = IPA_CLIENT_MHI2_PROD; + break; + case MHI_CLIENT_IP_HW_1_IN: + connect_params.sys.client = IPA_CLIENT_MHI2_CONS; + break; + default: + pr_err("Invalid channel = 0x%X\n", chid); + return -EINVAL; + } rc = ipa_mhi_connect_pipe(&connect_params, &mhi->ipa_clnt_hndl[chid-HW_CHANNEL_BASE]); if (rc) - pr_err("HW Channel%d start failed 0x%X\n", + pr_err("HW Channel%d start failed : %d\n", chid, rc); break; case MHI_DEV_RING_EL_INVALID: diff --git a/drivers/platform/msm/mhi_dev/mhi.h b/drivers/platform/msm/mhi_dev/mhi.h index 5c03fb5b4588..4b6af8fcbdaa 100644 --- a/drivers/platform/msm/mhi_dev/mhi.h +++ b/drivers/platform/msm/mhi_dev/mhi.h @@ -263,6 +263,7 @@ struct mhi_config { uint32_t mhi_reg_len; uint32_t version; uint32_t event_rings; + uint32_t hw_event_rings; uint32_t channels; uint32_t chdb_offset; uint32_t erdb_offset; diff --git a/drivers/platform/msm/mhi_dev/mhi_hwio.h b/drivers/platform/msm/mhi_dev/mhi_hwio.h index 936cac74a172..dae2c8e11e2f 100644 --- a/drivers/platform/msm/mhi_dev/mhi_hwio.h +++ b/drivers/platform/msm/mhi_dev/mhi_hwio.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2017-2019, 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 @@ -65,8 +65,8 @@ #define MHIVER_MHIVER_SHIFT 0x0 #define MHICFG (0x0110) -#define MHICFG_RESERVED_BITS31_24_MASK 0xff000000 -#define MHICFG_RESERVED_BITS31_24_SHIFT 0x18 +#define MHICFG_NHWER_MASK 0xff000000 +#define MHICFG_NHWER_SHIFT 0x18 #define MHICFG_NER_MASK 0xff0000 #define MHICFG_NER_SHIFT 0x10 #define MHICFG_RESERVED_BITS15_8_MASK 0xff00 diff --git a/drivers/platform/msm/mhi_dev/mhi_mmio.c b/drivers/platform/msm/mhi_dev/mhi_mmio.c index 22cf67149658..53fbf71188b9 100644 --- a/drivers/platform/msm/mhi_dev/mhi_mmio.c +++ b/drivers/platform/msm/mhi_dev/mhi_mmio.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2017-2019, 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 @@ -953,6 +953,11 @@ int mhi_dev_mmio_init(struct mhi_dev *dev) if (rc) return rc; + rc = mhi_dev_mmio_masked_read(dev, MHICFG, MHICFG_NHWER_MASK, + MHICFG_NHWER_SHIFT, &dev->cfg.hw_event_rings); + if (rc) + return rc; + rc = mhi_dev_mmio_read(dev, CHDBOFF, &dev->cfg.chdb_offset); if (rc) return rc; diff --git a/drivers/platform/msm/mhi_dev/mhi_uci.c b/drivers/platform/msm/mhi_dev/mhi_uci.c index 00942c31d1f2..22ab30fa4b05 100644 --- a/drivers/platform/msm/mhi_dev/mhi_uci.c +++ b/drivers/platform/msm/mhi_dev/mhi_uci.c @@ -38,6 +38,7 @@ #define MAX_NR_TRBS_PER_CHAN 9 #define MHI_QTI_IFACE_ID 4 #define MHI_ADPL_IFACE_ID 5 +#define MHI_CV2X_IFACE_ID 6 #define DEVICE_NAME "mhi" #define MAX_DEVICE_NAME_SIZE 80 @@ -1576,6 +1577,29 @@ static long mhi_uci_client_ioctl(struct file *file, unsigned int cmd, uci_log(UCI_DBG_DBG, "DPL ipa_prod_idx:%d\n", epinfo.ipa_ep_pair.prod_pipe_num); + rc = copy_to_user((void __user *)arg, &epinfo, + sizeof(epinfo)); + if (rc) + uci_log(UCI_DBG_ERROR, "copying to user space failed"); + } else if (cmd == MHI_UCI_CV2X_EP_LOOKUP) { + uci_log(UCI_DBG_DBG, "CV2X EP_LOOKUP for client:%d\n", + uci_handle->client_index); + epinfo.ph_ep_info.ep_type = DATA_EP_TYPE_PCIE; + epinfo.ph_ep_info.peripheral_iface_id = MHI_CV2X_IFACE_ID; + epinfo.ipa_ep_pair.cons_pipe_num = + ipa_get_ep_mapping(IPA_CLIENT_MHI2_PROD); + epinfo.ipa_ep_pair.prod_pipe_num = + ipa_get_ep_mapping(IPA_CLIENT_MHI2_CONS); + + uci_log(UCI_DBG_DBG, "client:%d ep_type:%d intf:%d\n", + uci_handle->client_index, + epinfo.ph_ep_info.ep_type, + epinfo.ph_ep_info.peripheral_iface_id); + + uci_log(UCI_DBG_DBG, "ipa_cons2_idx:%d ipa_prod2_idx:%d\n", + epinfo.ipa_ep_pair.cons_pipe_num, + epinfo.ipa_ep_pair.prod_pipe_num); + rc = copy_to_user((void __user *)arg, &epinfo, sizeof(epinfo)); if (rc) diff --git a/include/linux/msm_mhi_dev.h b/include/linux/msm_mhi_dev.h index 312f984c9ec5..f717c109e062 100644 --- a/include/linux/msm_mhi_dev.h +++ b/include/linux/msm_mhi_dev.h @@ -133,9 +133,11 @@ enum mhi_client_channel { MHI_CLIENT_IP_HW_0_OUT = 100, MHI_CLIENT_IP_HW_0_IN = 101, MHI_CLIENT_ADPL_IN = 102, - MHI_CLIENT_RESERVED_2_LOWER = 103, + MHI_CLIENT_IP_HW_1_OUT = 105, + MHI_CLIENT_IP_HW_1_IN = 106, + MHI_CLIENT_RESERVED_2_LOWER = 107, MHI_CLIENT_RESERVED_2_UPPER = 127, - MHI_MAX_CHANNELS = 103, + MHI_MAX_CHANNELS = 107, MHI_CLIENT_INVALID = 0xFFFFFFFF }; diff --git a/include/uapi/linux/mhi.h b/include/uapi/linux/mhi.h index 6442c8584367..e6b4b7b3abf5 100644 --- a/include/uapi/linux/mhi.h +++ b/include/uapi/linux/mhi.h @@ -33,6 +33,7 @@ struct ep_info { #define MHI_UCI_EP_LOOKUP _IOR(MHI_UCI_IOCTL_MAGIC, 2, struct ep_info) #define MHI_UCI_DPL_EP_LOOKUP _IOR(MHI_UCI_IOCTL_MAGIC, 3, struct ep_info) +#define MHI_UCI_CV2X_EP_LOOKUP _IOR(MHI_UCI_IOCTL_MAGIC, 4, struct ep_info) #endif /* _UAPI_MHI_H */ From eba8f2a8630f4b1943105dbc427414b94039fc62 Mon Sep 17 00:00:00 2001 From: Sharath Chandra Vurukala Date: Mon, 29 Jul 2019 16:16:50 +0530 Subject: [PATCH 181/281] Revert "fib_rules: fix error in backport of e9919a24d302" This reverts commit b2fc35160871b97f132c8bd00b65558c93529be8. Revert "fib_rules: return 0 directly if an exactly same rule" "exists when NLM_F_EXCL not supplied" This reverts commit 1fff19a925e524556e85efcd728efad5274ce5b6. Change-Id: If18c802f64a41a83721e2ecf06136ac1ae8fa6cb Signed-off-by: Sharath Chandra Vurukala --- net/core/fib_rules.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 268e32005273..31c4041f7586 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -486,10 +486,9 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh) rule->uid_range = fib_kuid_range_unset; } - if (rule_exists(ops, frh, tb, rule)) { - err = 0; - if (nlh->nlmsg_flags & NLM_F_EXCL) - err = -EEXIST; + if ((nlh->nlmsg_flags & NLM_F_EXCL) && + rule_exists(ops, frh, tb, rule)) { + err = -EEXIST; goto errout_free; } From 82cbd083fec52882f884432638a3f59f8f6bf09a Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Thu, 9 May 2019 20:35:09 +0530 Subject: [PATCH 182/281] msm: vidc: Ensure size of the data available before typecasting Ensure the available data size with in the packet before type casting from smaller data type to larger data type in order to avoid information leak or packet out of boundary access. Change-Id: I8614a8b3f930c87af8aa49f77ea9d768a73ea203 Signed-off-by: Priyanka Gujjula --- .../platform/msm/vidc/hfi_response_handler.c | 30 +++++++++++++------ drivers/media/platform/msm/vidc/vidc_hfi.h | 4 +-- .../media/platform/msm/vidc/vidc_hfi_helper.h | 1 - .../msm/vidc_3x/hfi_response_handler.c | 30 +++++++++++++------ drivers/media/platform/msm/vidc_3x/vidc_hfi.h | 4 +-- .../platform/msm/vidc_3x/vidc_hfi_helper.h | 1 - 6 files changed, 46 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index bde311010a68..6c2eebef23c5 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -370,6 +370,12 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id, "hal_process_session_init_done: bad_pkt_size\n"); return -E2BIG; } + if (pkt->size < sizeof(struct hfi_msg_event_notify_packet) - sizeof(u32) + + sizeof(struct hfi_msg_release_buffer_ref_event_packet)) { + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, pkt->size); + return -E2BIG; + } data = (struct hfi_msg_release_buffer_ref_event_packet *) pkt->rg_ext_event_data; @@ -1558,15 +1564,13 @@ static int hfi_process_session_etb_done(u32 device_id, struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt; struct msm_vidc_cb_data_done data_done = {0}; struct hfi_picture_type *hfi_picture_type = NULL; + u32 is_sync_frame; dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size < - sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { - dprintk(VIDC_ERR, - "hal_process_session_etb_done: bad_pkt_size\n"); - return -E2BIG; - } + sizeof(struct hfi_msg_session_empty_buffer_done_packet)) + goto bad_packet_size; data_done.device_id = device_id; data_done.session_id = (void *)(uintptr_t)pkt->session_id; @@ -1586,8 +1590,13 @@ static int hfi_process_session_etb_done(u32 device_id, data_done.input_done.extra_data_buffer = pkt->extra_data_buffer; data_done.input_done.status = hfi_map_err_status(pkt->error_type); - hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0]; - if (hfi_picture_type->is_sync_frame) { + is_sync_frame = pkt->rgData[0]; + if (is_sync_frame == 1) { + if (pkt->size < + sizeof(struct hfi_msg_session_empty_buffer_done_packet) + + sizeof(struct hfi_picture_type)) + goto bad_packet_size; + hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[1]; if (hfi_picture_type->picture_type) data_done.input_done.flags = hfi_picture_type->picture_type; @@ -1604,6 +1613,10 @@ static int hfi_process_session_etb_done(u32 device_id, info->response.data = data_done; return 0; +bad_packet_size: + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; } static int hfi_process_session_ftb_done( @@ -1838,8 +1851,7 @@ static int hfi_process_session_rel_buf_done(u32 device_id, cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done); cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); - cmd_done.data.buffer_info = - *(struct hal_buffer_info *)pkt->rg_buffer_info; + cmd_done.data.buffer_info.buffer_addr = *pkt->rg_buffer_info; cmd_done.size = sizeof(struct hal_buffer_info); info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h index 0cfe6934520a..949eb0d4ab40 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 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 @@ -601,7 +601,7 @@ struct hfi_msg_session_empty_buffer_done_packet { u32 extra_data_buffer; u32 flags; struct hfi_frame_cr_stats_type ubwc_cr_stats; - u32 rgData[0]; + u32 rgData[1]; }; struct hfi_msg_session_fill_buffer_done_compressed_packet { diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h index 733cbb9b93cb..f66d6c9bcee1 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h @@ -655,7 +655,6 @@ struct hfi_bit_depth { }; struct hfi_picture_type { - u32 is_sync_frame; u32 picture_type; }; diff --git a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c index abf2ef1686f4..654d9fa93692 100644 --- a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c @@ -287,6 +287,12 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id, "hal_process_session_init_done: bad_pkt_size\n"); return -E2BIG; } + if (pkt->size < sizeof(struct hfi_msg_event_notify_packet) - sizeof(u32) + + sizeof(struct hfi_msg_release_buffer_ref_event_packet)) { + dprintk(VIDC_ERR, + "hfi_msg_release_buffer_ref_event: bad_pkt_size\n"); + return -E2BIG; + } data = (struct hfi_msg_release_buffer_ref_event_packet *) pkt->rg_ext_event_data; @@ -1540,15 +1546,13 @@ static int hfi_process_session_etb_done(u32 device_id, struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt; struct msm_vidc_cb_data_done data_done = {0}; struct hfi_picture_type *hfi_picture_type = NULL; + u32 is_sync_frame; dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size < - sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { - dprintk(VIDC_ERR, - "hal_process_session_etb_done: bad_pkt_size\n"); - return -E2BIG; - } + sizeof(struct hfi_msg_session_empty_buffer_done_packet)) + goto bad_packet_size; data_done.device_id = device_id; data_done.session_id = (void *)(uintptr_t)pkt->session_id; @@ -1563,8 +1567,13 @@ static int hfi_process_session_etb_done(u32 device_id, (ion_phys_addr_t)pkt->extra_data_buffer; data_done.input_done.status = hfi_map_err_status(pkt->error_type); - hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0]; - if (hfi_picture_type->is_sync_frame) { + is_sync_frame = pkt->rgData[0]; + if (is_sync_frame == 1) { + if (pkt->size < + sizeof(struct hfi_msg_session_empty_buffer_done_packet) + + sizeof(struct hfi_picture_type)) + goto bad_packet_size; + hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[1]; if (hfi_picture_type->picture_type) data_done.input_done.flags = hfi_picture_type->picture_type; @@ -1583,6 +1592,10 @@ static int hfi_process_session_etb_done(u32 device_id, }; return 0; +bad_packet_size: + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; } static int hfi_process_session_ftb_done( @@ -1823,8 +1836,7 @@ static int hfi_process_session_rel_buf_done(u32 device_id, cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); if (pkt->rg_buffer_info) { - cmd_done.data.buffer_info = - *(struct hal_buffer_info *)pkt->rg_buffer_info; + cmd_done.data.buffer_info.buffer_addr = *pkt->rg_buffer_info; cmd_done.size = sizeof(struct hal_buffer_info); } else { dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n"); diff --git a/drivers/media/platform/msm/vidc_3x/vidc_hfi.h b/drivers/media/platform/msm/vidc_3x/vidc_hfi.h index d0fd4934e67a..903603bcac07 100644 --- a/drivers/media/platform/msm/vidc_3x/vidc_hfi.h +++ b/drivers/media/platform/msm/vidc_3x/vidc_hfi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, 2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 2018-2019 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 @@ -662,7 +662,7 @@ struct hfi_msg_session_empty_buffer_done_packet { u32 input_tag; u32 packet_buffer; u32 extra_data_buffer; - u32 rgData[0]; + u32 rgData[1]; }; struct hfi_msg_session_fill_buffer_done_compressed_packet { diff --git a/drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h index c09cf84c5d39..16c390a9781e 100644 --- a/drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h +++ b/drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h @@ -701,7 +701,6 @@ struct hfi_bit_depth { }; struct hfi_picture_type { - u32 is_sync_frame; u32 picture_type; }; From dabe152b88bf98b05fd5ecea855e0fdb1637b1f3 Mon Sep 17 00:00:00 2001 From: Xiao Li Date: Tue, 30 Jul 2019 21:10:39 +0800 Subject: [PATCH 183/281] ASoC: aw8896: add resume/suspend methods for codec driver Add resume/suspend methods for aw8896 codec driver to control LDO supply for PA chip's DVDD pin so as to lower the power consumption when device get in suspend mode. Change-Id: I9a5ec5350e4fbe22794abb1e063b28a3aeae0e48 Signed-off-by: Xiao Li --- sound/soc/codecs/aw8896.c | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sound/soc/codecs/aw8896.c b/sound/soc/codecs/aw8896.c index 2592b480a4a3..24d5aaa2ad71 100644 --- a/sound/soc/codecs/aw8896.c +++ b/sound/soc/codecs/aw8896.c @@ -982,9 +982,49 @@ static int aw8896_codec_write(struct snd_soc_codec *codec, unsigned int reg, return -EINVAL; } +#ifdef CONFIG_PM +static int aw8896_suspend(struct snd_soc_codec *codec) +{ + int ret = 0; + struct aw8896 *aw8896 = snd_soc_codec_get_drvdata(codec); + + /* clear FW/DSP status flags so the DSP can get into + * correct status after resume + */ + aw8896->init = 0; + aw8896->dsp_fw_state = AW8896_DSP_FW_FAIL; + aw8896->dsp_cfg_state = AW8896_DSP_CFG_FAIL; + + ret = regulator_disable(aw8896->supply.regulator); + if (ret < 0) + dev_err(codec->dev, "%s: fail to disable regulator, err:%d\n", + __func__, ret); + + return 0; +} + +static int aw8896_resume(struct snd_soc_codec *codec) +{ + int ret = 0; + struct aw8896 *aw8896 = snd_soc_codec_get_drvdata(codec); + + ret = regulator_enable(aw8896->supply.regulator); + if (ret < 0) + dev_err(codec->dev, "%s: fail to enable regulator, err:%d\n", + __func__, ret); + + return 0; +} +#else +#define aw8896_suspend NULL +#define aw8896_resume NULL +#endif + static struct snd_soc_codec_driver soc_codec_dev_aw8896 = { .probe = aw8896_probe, .remove = aw8896_remove, + .suspend = aw8896_suspend, + .resume = aw8896_resume, .read = aw8896_codec_read, .write = aw8896_codec_write, .reg_cache_size = AW8896_REG_MAX, From d023ec17cff0edf6ac69ef220b618283a029dffb Mon Sep 17 00:00:00 2001 From: Protik Biswas Date: Thu, 4 Jul 2019 09:54:34 +0530 Subject: [PATCH 184/281] soc: qcom: bgcom_spi: Logging of BG GPIO values Need to capture the GPIO values during bgcom Resume failure and induce force crash. Change-Id: I14190cda97d8dd21332cc8fb77c0c3651c568f15 Signed-off-by: Protik Biswas --- drivers/soc/qcom/bgcom_spi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/soc/qcom/bgcom_spi.c b/drivers/soc/qcom/bgcom_spi.c index 024b4914e7d7..8ef2c06cb80b 100644 --- a/drivers/soc/qcom/bgcom_spi.c +++ b/drivers/soc/qcom/bgcom_spi.c @@ -857,6 +857,11 @@ int bgcom_resume(void *handle) if (retry == MAX_RETRY) { /* BG failed to resume. Trigger BG soft reset. */ pr_err("BG failed to resume\n"); + pr_err("%s: gpio#95 value is: %d\n", + __func__, gpio_get_value(95)); + pr_err("%s: gpio#97 value is: %d\n", + __func__, gpio_get_value(97)); + BUG(); bg_soft_reset(); return -ETIMEDOUT; } From 72554b1f2a6e6bc749643da282a19a2670f41d03 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Tue, 30 Jul 2019 22:24:45 +0530 Subject: [PATCH 185/281] ARM: dts: msm: Add wakeup capable flag to thermal zones for MSM8937/SDM439 All TSENS and ADC sensor interrupts are wakeup capable. More over all cooling devices are platform cooling devices and will not loose mitigation state after suspend resume. So add wakeup capable sensor flag to all TSENS, ADC sensors, pmic alarm sensor and BCL thermal zones for MSM8937/SDM439/SDM429. This will ignore post suspend thermal zone re-evaluation for these thermal zones. Change-Id: I28fcfda7a4a209984de5d12af7b18230c1fe0a72 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm64/boot/dts/qcom/msm8937-thermal.dtsi | 31 ++++++++++++++++++- arch/arm64/boot/dts/qcom/pm8937.dtsi | 6 ++++ arch/arm64/boot/dts/qcom/pm8953.dtsi | 5 ++- arch/arm64/boot/dts/qcom/pmi632.dtsi | 9 +++++- arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi | 3 +- arch/arm64/boot/dts/qcom/sdm439-pmi632.dtsi | 4 ++- 6 files changed, 53 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8937-thermal.dtsi b/arch/arm64/boot/dts/qcom/msm8937-thermal.dtsi index 014825396845..c474c0996134 100644 --- a/arch/arm64/boot/dts/qcom/msm8937-thermal.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8937-thermal.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, 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 @@ -48,6 +48,7 @@ polling-delay = <0>; thermal-governor = "user_space"; thermal-sensors = <&tsens0 0>; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -62,6 +63,7 @@ polling-delay = <0>; thermal-governor = "user_space"; thermal-sensors = <&tsens0 1>; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -76,6 +78,7 @@ polling-delay = <0>; thermal-governor = "user_space"; thermal-sensors = <&tsens0 2>; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -90,6 +93,7 @@ polling-delay = <0>; thermal-governor = "user_space"; thermal-sensors = <&tsens0 3>; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -104,6 +108,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 4>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -118,6 +123,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 5>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -132,6 +138,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 6>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -146,6 +153,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 7>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -160,6 +168,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 8>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -174,6 +183,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 9>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -188,6 +198,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 10>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { temperature = <125000>; @@ -202,6 +213,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 10>; thermal-governor = "step_wise"; + wake-capable-sensor; trips { gpu_step_trip: gpu-step-trip { temperature = <95000>; @@ -223,6 +235,7 @@ polling-delay-passive = <50>; polling-delay = <100>; thermal-governor = "step_wise"; + wake-capable-sensor; trips { cpu_trip:cpu-trip { temperature = <85000>; @@ -287,6 +300,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 5>; thermal-governor = "step_wise"; + wake-capable-sensor; trips { apc1_cpu0_trip: apc1-cpu0-trip { temperature = <105000>; @@ -309,6 +323,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 6>; thermal-governor = "step_wise"; + wake-capable-sensor; trips { apc1_cpu1_trip: apc1-cpu1-trip { temperature = <105000>; @@ -331,6 +346,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 7>; thermal-governor = "step_wise"; + wake-capable-sensor; trips { apc1_cpu2_trip: apc1-cpu2-trip { temperature = <105000>; @@ -353,6 +369,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 8>; thermal-governor = "step_wise"; + wake-capable-sensor; trips { apc1_cpu3_trip: apc1-cpu3-trip { temperature = <105000>; @@ -375,6 +392,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 9>; thermal-governor = "step_wise"; + wake-capable-sensor; trips { cpuss0_step_trip: cpuss0-step-trip { temperature = <105000>; @@ -415,6 +433,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 0>; + wake-capable-sensor; tracks-low; trips { aoss0_trip: aoss-trip { @@ -445,6 +464,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 1>; + wake-capable-sensor; tracks-low; trips { mdm_core_trip: mdm-core-trip { @@ -475,6 +495,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 2>; + wake-capable-sensor; tracks-low; trips { qdsp_trip: qdsp-trip { @@ -505,6 +526,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 3>; + wake-capable-sensor; tracks-low; trips { camera_trip: camera-trip { @@ -535,6 +557,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 4>; + wake-capable-sensor; tracks-low; trips { cpuss1_trip: cpuss1-trip { @@ -565,6 +588,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 5>; + wake-capable-sensor; tracks-low; trips { cpu0_trip: apc1-cpu0-trip { @@ -595,6 +619,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 6>; + wake-capable-sensor; tracks-low; trips { cpu1_trip: apc1-cpu1-trip { @@ -625,6 +650,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 7>; + wake-capable-sensor; tracks-low; trips { cpu2_trip: apc1-cpu2-trip { @@ -655,6 +681,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 8>; + wake-capable-sensor; tracks-low; trips { cpu3_trip: apc1-cpu3-trip { @@ -685,6 +712,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 9>; + wake-capable-sensor; tracks-low; trips { cpuss0_lowf_trip: cpuss0-lowf-trip { @@ -715,6 +743,7 @@ polling-delay = <0>; thermal-governor = "low_limits_floor"; thermal-sensors = <&tsens0 10>; + wake-capable-sensor; tracks-low; trips { gpu_lowf_trip: gpu-lowf-trip { diff --git a/arch/arm64/boot/dts/qcom/pm8937.dtsi b/arch/arm64/boot/dts/qcom/pm8937.dtsi index b97cec6b7871..43585d9569b7 100644 --- a/arch/arm64/boot/dts/qcom/pm8937.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8937.dtsi @@ -338,6 +338,7 @@ polling-delay = <0>; thermal-sensors = <&pm8937_vadc 0x11>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { @@ -353,6 +354,7 @@ polling-delay = <0>; thermal-sensors = <&pm8937_vadc 0x32>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { @@ -368,6 +370,7 @@ polling-delay = <0>; thermal-sensors = <&pm8937_vadc 0x3c>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { @@ -383,6 +386,7 @@ polling-delay = <0>; thermal-sensors = <&pm8937_vadc 0x13>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { @@ -398,6 +402,7 @@ polling-delay = <0>; thermal-sensors = <&pm8937_adc_tm 0x36>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { @@ -413,6 +418,7 @@ polling-delay = <0>; thermal-governor = "step_wise"; thermal-sensors = <&pm8937_temp_alarm>; + wake-capable-sensor; trips { pm8937_trip0: pm8937-trip0 { diff --git a/arch/arm64/boot/dts/qcom/pm8953.dtsi b/arch/arm64/boot/dts/qcom/pm8953.dtsi index 10c010e08cd1..32735f94baa0 100644 --- a/arch/arm64/boot/dts/qcom/pm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8953.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, 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 @@ -360,6 +360,7 @@ polling-delay = <0>; thermal-sensors = <&pm8953_adc_tm 0x32>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { @@ -375,6 +376,7 @@ polling-delay = <0>; thermal-sensors = <&pm8953_vadc 0x3c>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { @@ -389,6 +391,7 @@ polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&pm8953_tz>; + wake-capable-sensor; trips { pm8953_trip0: pm8953-trip0 { diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi index da15b33355ec..6919e741e006 100644 --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -753,6 +753,7 @@ polling-delay = <0>; thermal-governor = "step_wise"; thermal-sensors = <&bcl_sensor 0>; + wake-capable-sensor; trips { pmi632_ibat_lvl0: ibat-lvl0 { @@ -768,6 +769,7 @@ polling-delay = <0>; thermal-governor = "step_wise"; thermal-sensors = <&bcl_sensor 1>; + wake-capable-sensor; trips { ibat-lvl1 { @@ -783,6 +785,7 @@ polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&bcl_sensor 2>; + wake-capable-sensor; tracks-low; trips { @@ -799,6 +802,7 @@ polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&bcl_sensor 3>; + wake-capable-sensor; tracks-low; trips { @@ -815,6 +819,7 @@ polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&bcl_sensor 4>; + wake-capable-sensor; tracks-low; trips { @@ -831,6 +836,7 @@ polling-delay = <0>; thermal-governor = "low_limits_cap"; thermal-sensors = <&bcl_soc>; + wake-capable-sensor; tracks-low; trips { @@ -847,6 +853,7 @@ polling-delay = <0>; thermal-governor = "step_wise"; thermal-sensors = <&pmi632_tz>; + wake-capable-sensor; trips { pmi632_tz_trip0: pmi632-trip0 { diff --git a/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi b/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi index 615489eb92a0..44d89fb5da7c 100644 --- a/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, 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 @@ -277,6 +277,7 @@ polling-delay = <0>; thermal-sensors = <&pm8953_adc_tm 0x36>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { diff --git a/arch/arm64/boot/dts/qcom/sdm439-pmi632.dtsi b/arch/arm64/boot/dts/qcom/sdm439-pmi632.dtsi index 446b3737a0b9..3608d5501d65 100644 --- a/arch/arm64/boot/dts/qcom/sdm439-pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm439-pmi632.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, 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 @@ -132,6 +132,7 @@ polling-delay = <0>; thermal-sensors = <&pmi632_adc_tm 0x53>; thermal-governor = "step_wise"; + wake-capable-sensor; trips { quiet_batt_439_trip1: quiet-batt-trip1 { @@ -302,6 +303,7 @@ polling-delay = <0>; thermal-sensors = <&pmi632_adc_tm 0x53>; thermal-governor = "user_space"; + wake-capable-sensor; trips { active-config0 { From c91892abe7c97fb72b015f2859433a19caf37c7c Mon Sep 17 00:00:00 2001 From: Mangalaram ARCHANA Date: Fri, 12 Jul 2019 14:47:01 +0530 Subject: [PATCH 186/281] msm: camera: isp: After flush resetting the hardware For active list and wait list flush, ife hardware need to stop at frame boundary and release the fences. Ife hardware need to reset to make sure that vfe bus write master fifos are cleared. Start the ife hardware after reset and set the isp context state to sof. Change-Id: Ic931b84f4eb99b892cd67274b0d461afc8bedf3e Signed-off-by: Mangalaram ARCHANA --- .../msm/camera/cam_core/cam_hw_mgr_intf.h | 12 +++++ .../msm/camera/cam_isp/cam_isp_context.c | 26 +++++++--- .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 47 +++++++++++++++++-- .../isp_hw/ife_csid_hw/cam_ife_csid_core.c | 8 ---- 4 files changed, 74 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h b/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h index 656fcfac3996..c48665f60d1c 100644 --- a/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h +++ b/drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h @@ -245,6 +245,16 @@ struct cam_hw_dump_pf_args { bool *mem_found; }; +/** + * struct cam_hw_reset_args -hw reset arguments + * + * @ctxt_to_hw_map: HW context from the acquire + * + */ +struct cam_hw_reset_args { + void *ctxt_to_hw_map; +}; + /* enum cam_hw_mgr_command - Hardware manager command type */ enum cam_hw_mgr_command { CAM_HW_MGR_CMD_INTERNAL, @@ -294,6 +304,7 @@ struct cam_hw_cmd_args { * @hw_open: Function pointer for HW init * @hw_close: Function pointer for HW deinit * @hw_flush: Function pointer for HW flush + * @hw_reset: Function pointer for HW reset * */ struct cam_hw_mgr_intf { @@ -312,6 +323,7 @@ struct cam_hw_mgr_intf { int (*hw_open)(void *hw_priv, void *fw_download_args); int (*hw_close)(void *hw_priv, void *hw_close_args); int (*hw_flush)(void *hw_priv, void *hw_flush_args); + int (*hw_reset)(void *hw_priv, void *hw_reset_args); }; #endif /* _CAM_HW_MGR_INTF_H_ */ diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index 8fc2519117be..419f349dbeed 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -1399,9 +1399,11 @@ static int __cam_isp_ctx_flush_req_in_top_state( struct cam_isp_stop_args stop_isp; struct cam_hw_stop_args stop_args; struct cam_isp_start_args start_isp; + struct cam_hw_reset_args reset_args; int rc = 0; - CAM_DBG(CAM_ISP, "try to flush pending list"); + CAM_DBG(CAM_ISP, "ctx id:%d try to flush pending list", + ctx->ctx_id); spin_lock_bh(&ctx->lock); rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req); spin_unlock_bh(&ctx->lock); @@ -1412,7 +1414,9 @@ static int __cam_isp_ctx_flush_req_in_top_state( if ((list_empty(&ctx->wait_req_list)) && (list_empty(&ctx->active_req_list))) { spin_unlock_bh(&ctx->lock); - CAM_DBG(CAM_ISP, "active and wait list are empty"); + CAM_DBG(CAM_ISP, + "ctx id:%d active and wait list are empty", + ctx->ctx_id); goto end; } spin_unlock_bh(&ctx->lock); @@ -1424,12 +1428,21 @@ static int __cam_isp_ctx_flush_req_in_top_state( stop_args.args = (void *)&stop_isp; ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv, &stop_args); + CAM_DBG(CAM_ISP, "try to reset hw"); + /* Reset hw */ + reset_args.ctxt_to_hw_map = ctx_isp->hw_ctx; + rc = ctx->hw_mgr_intf->hw_reset(ctx->hw_mgr_intf->hw_mgr_priv, + &reset_args); + if (rc) + goto end; spin_lock_bh(&ctx->lock); - CAM_DBG(CAM_ISP, "try to flush wait list"); + CAM_DBG(CAM_ISP, "ctx id:%d try to flush wait list", + ctx->ctx_id); rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list, flush_req); - CAM_DBG(CAM_ISP, "try to flush active list"); + CAM_DBG(CAM_ISP, "ctx id:%d try to flush active list", + ctx->ctx_id); rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list, flush_req); ctx_isp->active_req_cnt = 0; @@ -1445,8 +1458,9 @@ static int __cam_isp_ctx_flush_req_in_top_state( } end: - CAM_DBG(CAM_ISP, "Flush request in top state %d", - ctx->state); + ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; + CAM_DBG(CAM_ISP, "ctx id:%d Flush request in top state %d", + ctx->ctx_id, ctx->state); return rc; } diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 63fc442bd205..2695c54fc323 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -1940,6 +1940,11 @@ static int cam_ife_mgr_pause_hw(struct cam_ife_hw_mgr_ctx *ctx) return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_EXCLUDE); } +static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx) +{ + return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE); +} + /* entry function: stop_hw */ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) { @@ -2344,6 +2349,42 @@ static int cam_ife_mgr_write(void *hw_mgr_priv, void *write_args) return -EPERM; } +static int cam_ife_mgr_reset(void *hw_mgr_priv, void *hw_reset_args) +{ + struct cam_ife_hw_mgr *hw_mgr = hw_mgr_priv; + struct cam_hw_reset_args *reset_args = hw_reset_args; + struct cam_ife_hw_mgr_ctx *ctx; + struct cam_ife_hw_mgr_res *hw_mgr_res; + uint32_t i; + int rc = 0; + + if (!hw_mgr_priv || !hw_reset_args) { + CAM_ERR(CAM_ISP, "Invalid arguments"); + return -EINVAL; + } + + ctx = (struct cam_ife_hw_mgr_ctx *)reset_args->ctxt_to_hw_map; + if (!ctx || !ctx->ctx_in_use) { + CAM_ERR(CAM_ISP, "Invalid context is used"); + return -EPERM; + } + CAM_DBG(CAM_ISP, "reset csid and vfe hw"); + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, + list) { + rc = cam_ife_hw_mgr_reset_csid_res(hw_mgr_res); + if (rc) { + CAM_ERR(CAM_ISP, "Failed RESET (%d) rc:%d", + hw_mgr_res->res_id, rc); + goto end; + } + } + + for (i = 0; i < ctx->num_base; i++) + rc = cam_ife_mgr_reset_vfe_hw(hw_mgr, ctx->base[i].idx); +end: + return rc; +} + static int cam_ife_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args) { @@ -2854,11 +2895,6 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, return rc; } -static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx) -{ - return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE); -} - static int cam_ife_mgr_sof_irq_debug( struct cam_ife_hw_mgr_ctx *ctx, uint32_t sof_irq_enable) @@ -4593,6 +4629,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) hw_mgr_intf->hw_prepare_update = cam_ife_mgr_prepare_hw_update; hw_mgr_intf->hw_config = cam_ife_mgr_config_hw; hw_mgr_intf->hw_cmd = cam_ife_mgr_cmd; + hw_mgr_intf->hw_reset = cam_ife_mgr_reset; if (iommu_hdl) *iommu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl; diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index 11860c9c79d4..7205e27b9121 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -506,10 +506,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw, reinit_completion(complete); reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all; - /* Enable the Test gen before reset */ - cam_io_w_mb(1, csid_hw->hw_info->soc_info.reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_ctrl_addr); - /* Reset the corresponding ife csid path */ cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base + reset_strb_addr); @@ -524,10 +520,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw, rc = -ETIMEDOUT; } - /* Disable Test Gen after reset*/ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_ctrl_addr); - end: return rc; From 366538082e86619903d6ff6d4e9ec698b45a4609 Mon Sep 17 00:00:00 2001 From: Monika Singh Date: Thu, 25 Jul 2019 12:03:06 +0530 Subject: [PATCH 187/281] ARM: dts: msm: Fix cmnlib loading issue SDM845 In qseecom driver node add entry to ensure cmnlib is loaded by UEFI to fix cmnlib loading issue. Change-Id: I8627fe083c5afc001855c310c7c2a6545e065e53 Signed-off-by: Monika Singh --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 9bf544d06426..327feb5775fc 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -2509,6 +2509,7 @@ qcom,support-fde; qcom,no-clock-support; qcom,fde-key-size; + qcom,commonlib64-loaded-by-uefi; qcom,msm-bus,name = "qseecom-noc"; qcom,msm-bus,num-cases = <4>; qcom,msm-bus,num-paths = <1>; From 2c0437df5f756d544d74353819dd83f77bbf1426 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Fri, 26 Jul 2019 16:09:32 +0530 Subject: [PATCH 188/281] iio: qcom-rradc: Add batt_id delay property for RRADC Add DT property to set batt_id hardware settling delay time. Change-Id: I3ca6078d45efdfcec38027586fc5a740aa03f698 Signed-off-by: Jishnu Prakash --- .../bindings/iio/adc/qcom-rradc.txt | 4 +++ drivers/iio/adc/qcom-rradc.c | 34 +++++++++++++++---- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/qcom-rradc.txt b/Documentation/devicetree/bindings/iio/adc/qcom-rradc.txt index 1ab49edfe30c..240c6d82deb0 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom-rradc.txt +++ b/Documentation/devicetree/bindings/iio/adc/qcom-rradc.txt @@ -45,6 +45,10 @@ Optional property: - qcom,pmic-revid : Phandle pointing to the revision peripheral node. Use it to query the PMIC fabrication ID for applying the appropriate temperature compensation parameters. +- qcom,batt-id-delay-ms : + Value type: + Definition: Used to specify HW settling time in MS for measuring BATT_ID. + Possible values are: 0, 1, 4, 12, 20, 40, 60, 80. Example: /* RRADC node */ diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c index 6c86d7df5502..1bb10832bd2e 100644 --- a/drivers/iio/adc/qcom-rradc.c +++ b/drivers/iio/adc/qcom-rradc.c @@ -199,7 +199,8 @@ #define FG_RR_TP_REV_VERSION2 29 #define FG_RR_TP_REV_VERSION3 32 -#define BATT_ID_SETTLE_DELAY_80_MS 0xE0 +#define BATT_ID_SETTLE_SHIFT 5 +#define RRADC_BATT_ID_DELAY_MAX 8 /* * The channel number is not a physical index in hardware, @@ -231,6 +232,7 @@ struct rradc_chip { struct mutex lock; struct regmap *regmap; u16 base; + int batt_id_delay; struct iio_chan_spec *iio_chans; unsigned int nchannels; struct rradc_chan_prop *chan_props; @@ -258,6 +260,8 @@ struct rradc_chan_prop { u16 adc_code, int *result); }; +static const int batt_id_delays[] = {0, 1, 4, 12, 20, 40, 60, 80}; + static int rradc_masked_write(struct rradc_chip *rr_adc, u16 offset, u8 mask, u8 val) { @@ -855,7 +859,7 @@ static int rradc_enable_batt_id_channel(struct rradc_chip *chip, bool enable) static int rradc_do_batt_id_conversion(struct rradc_chip *chip, struct rradc_chan_prop *prop, u16 *data, u8 *buf) { - int rc = 0, ret = 0; + int rc = 0, ret = 0, batt_id_delay; rc = rradc_enable_batt_id_channel(chip, true); if (rc < 0) { @@ -863,11 +867,12 @@ static int rradc_do_batt_id_conversion(struct rradc_chip *chip, return rc; } - rc = rradc_masked_write(chip, FG_ADC_RR_BATT_ID_CFG, - BATT_ID_SETTLE_DELAY_80_MS, BATT_ID_SETTLE_DELAY_80_MS); - if (rc < 0) { - pr_err("BATT_ID settling time config failed:%d\n", rc); - ret = rc; + if (chip->batt_id_delay != -EINVAL) { + batt_id_delay = chip->batt_id_delay << BATT_ID_SETTLE_SHIFT; + rc = rradc_masked_write(chip, FG_ADC_RR_BATT_ID_CFG, + batt_id_delay, batt_id_delay); + if (rc < 0) + pr_err("BATT_ID settling time config failed:%d\n", rc); } rc = rradc_masked_write(chip, FG_ADC_RR_BATT_ID_TRIGGER, @@ -1138,6 +1143,21 @@ static int rradc_get_dt_data(struct rradc_chip *chip, struct device_node *node) return rc; } + chip->batt_id_delay = -EINVAL; + + rc = of_property_read_u32(node, "qcom,batt-id-delay-ms", + &chip->batt_id_delay); + if (!rc) { + for (i = 0; i < RRADC_BATT_ID_DELAY_MAX; i++) { + if (chip->batt_id_delay == batt_id_delays[i]) + break; + } + if (i == RRADC_BATT_ID_DELAY_MAX) + pr_err("Invalid batt_id_delay, rc=%d\n", rc); + else + chip->batt_id_delay = i; + } + chip->base = base; chip->revid_dev_node = of_parse_phandle(node, "qcom,pmic-revid", 0); if (chip->revid_dev_node) { From f8091d58772a25ee380722b1ba47de1c25443dac Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Sun, 28 Jul 2019 19:59:13 +0530 Subject: [PATCH 189/281] ARM: dts: msm: Set batt_id settling delay to 80MS for SDM429w With default hardware settling time, batt_id may be read incorrectly from RRADC on PM660 on SDM429w due to the presence of a parallel capacitor, which increases the settling time required. Set batt_id settling delay to maximum value of 80MS for SDM429w. Change-Id: I084ca45e4e532ac8ebadd3bad215000b786e5908 Signed-off-by: Jishnu Prakash --- arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index 450691b42381..412d03c342b3 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -542,6 +542,7 @@ #size-cells = <0>; #io-channel-cells = <1>; qcom,pmic-revid = <&pm660_revid>; + qcom,batt-id-delay-ms = <80>; }; pm660_fg: qpnp,fg { From 4c38c59a2996d1fa27c50e44cc2e28f07ab06d50 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Wed, 31 Jul 2019 19:56:44 +0530 Subject: [PATCH 190/281] msm: ipa: Fix SMEM mapping to AP CB When Q6 SMEM memory is mapped to AP CB only partial range is mapped as a result when IPA tries to access beyond mapped range it results in an SMMU S1 fault. Make changes to map the full SMEM region. Change-Id: I81d5d7b27635a97bb50115ddb3a6b2d56e753c2e Signed-off-by: Chaitanya Pratapa --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 6de07dc79c59..6a81bb34ef9b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -6371,6 +6371,7 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) /* map SMEM memory for IPA table accesses */ smem_addr = smem_alloc(SMEM_IPA_FILTER_TABLE, IPA_SMEM_SIZE, SMEM_MODEM, 0); + q6_smem_size = IPA_SMEM_SIZE; } else { IPADBG("ipa q6 smem size = %d\n", q6_smem_size); smem_addr = smem_alloc(SMEM_IPA_FILTER_TABLE, q6_smem_size, @@ -6383,7 +6384,7 @@ static int ipa_smmu_ap_cb_probe(struct device *dev) phys_addr_t pa_p; u32 size_p; - IPA_SMMU_ROUND_TO_PAGE(iova, pa, IPA_SMEM_SIZE, + IPA_SMMU_ROUND_TO_PAGE(iova, pa, q6_smem_size, iova_p, pa_p, size_p); IPADBG("mapping 0x%lx to 0x%pa size %d\n", iova_p, &pa_p, size_p); From 005e9b21e703a9abc00deec3db4c5f84982b8445 Mon Sep 17 00:00:00 2001 From: Ziyu Jian Date: Wed, 13 Mar 2019 13:55:16 +0800 Subject: [PATCH 191/281] ARM: dts: media: Add Altek mini isp support for sdm845 robotics This change will enable Altek mini isp for sdm845 robotics project. Change-Id: I63a8d39991262d0579dc6e417ca80c628b360e4e Signed-off-by: Ziyu Jian --- .../devicetree/bindings/vendor-prefixes.txt | 1 + .../boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi | 14 ++++++++++++++ .../qcom/sdm845-v2-camera-sensor-mtp-robotics.dtsi | 14 ++++++++++++++ arch/arm64/boot/dts/qcom/sdm845-v2-robotics.dtsi | 6 ++++++ 4 files changed, 35 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 0f6ef921834c..3b0b909c6fab 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -322,3 +322,4 @@ zyxel ZyXEL Communications Corp. inven InvenSense, Inc. cy Parade. awinic Shanghai Awinic Technology Co., Ltd. +altek Altek Corporation diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi index 8f25cb020c22..aeff01c9d606 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-rb3.dtsi @@ -331,3 +331,17 @@ clock-rates = <24000000>; }; }; + +&qupv3_se5_spi { + status = "ok"; + mini_isp@0 { + compatible = "altek,isp"; + reg = <0>; + spi-max-frequency = <50000000>; + spi-cpol; + spi-cpha; + /*spi-cs-high;*/ + irq-gpios = <&tlmm 24 0x00>; + status = "ok"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2-camera-sensor-mtp-robotics.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2-camera-sensor-mtp-robotics.dtsi index a1f51633edf9..b1c2cf2c00c8 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2-camera-sensor-mtp-robotics.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2-camera-sensor-mtp-robotics.dtsi @@ -580,3 +580,17 @@ clock-rates = <24000000>; }; }; + +&qupv3_se15_spi { + status = "ok"; + mini_isp@0 { + compatible = "altek,isp"; + reg = <0>; + spi-max-frequency = <50000000>; + spi-cpol; + spi-cpha; + /*spi-cs-high;*/ + irq-gpios = <&tlmm 121 0x00>; + status = "ok"; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2-robotics.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2-robotics.dtsi index 7f4e710917cb..a6f4e7d8f0df 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2-robotics.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2-robotics.dtsi @@ -42,3 +42,9 @@ }; }; + +&soc { + qcom,qbt1000 { + status = "disabled"; + }; +}; From 52057dd688b13404a98838523849546b1e88ecf4 Mon Sep 17 00:00:00 2001 From: jiangjia Date: Thu, 1 Aug 2019 14:46:24 +0800 Subject: [PATCH 192/281] ARM: dts: msm: Enable the secure mem region for Spyro Spyro need support Trusted UI, so enable the secure mem, and set the size as 4M according to the display resolution. Change-Id: I9fa0e100483e4de35852e6d7525fcc92f20a6140 Signed-off-by: Jiangjiang Shen --- .../boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi index dda1f843338d..8b886f9f8d7a 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi @@ -168,6 +168,22 @@ }; }; +&soc { + qcom,ion { + qcom,ion-heap@8 { /* CP_MM HEAP */ + reg = <8>; + memory-region = <&secure_mem>; + qcom,ion-heap-type = "SECURE_DMA"; + }; + }; +}; + +&secure_mem { + alignment = <0 0x400000>; + size = <0 0x400000>; + status = "okay"; +}; + &modem_mem { reg = <0x0 0x86800000 0x0 0x5000000>; }; From 33457b74066012c525070ab964446dce9f619547 Mon Sep 17 00:00:00 2001 From: Naitik Bharadiya Date: Tue, 23 Jul 2019 19:27:03 +0530 Subject: [PATCH 193/281] defconfig: msm: enable CONFIG_USB_RTL8152 for SDM845 Enable config for Realtek RTL8152/RTL8153 based USB Ethernet Adapters for SDM845 target. This is to align them with android base config. Change-Id: I78be67f2ed6636ed68b016427b0d0c990a398b97 Signed-off-by: Naitik Bharadiya --- arch/arm64/configs/sdm845-perf_defconfig | 1 + arch/arm64/configs/sdm845_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index ae24d2d900c4..4cdd447df6b4 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -292,6 +292,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y CONFIG_WIL6210=m # CONFIG_WIL6210_TRACING is not set diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index dd6cf6cc1e0b..9f3347c8311f 100755 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -298,6 +298,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y CONFIG_WIL6210=m CONFIG_WCNSS_MEM_PRE_ALLOC=y From b2dd27b9430ea7bc86dd9e5b003e1ffb0c8b84d9 Mon Sep 17 00:00:00 2001 From: Fei Mao Date: Mon, 29 Jul 2019 18:42:31 +0800 Subject: [PATCH 194/281] input: touchscreen: cyttsp5: release resources when no touch When no touch is plugged in, release resources correctly. Change-Id: Ie527a86bbb7707b6744c872da2f39623ba7d600b Signed-off-by: Fei Mao --- .../input/touchscreen/cyttsp5/cyttsp5_core.c | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c index 64cc51060fb1..119ac457dee1 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c @@ -306,8 +306,12 @@ static void cyttsp5_free_hid_reports_(struct cyttsp5_core_data *cd) for (i = 0; i < cd->num_hid_reports; i++) { report = cd->hid_reports[i]; - for (j = 0; j < report->num_fields; j++) + if (!report) + continue; + for (j = 0; j < report->num_fields; j++) { kfree(report->fields[j]); + report->fields[j] = NULL; + } kfree(report); cd->hid_reports[i] = NULL; } @@ -4633,7 +4637,7 @@ static int cyttsp5_startup_(struct cyttsp5_core_data *cd, bool reset) rc = cyttsp5_check_and_deassert_int(cd); - if (reset || retry != CY_CORE_STARTUP_RETRY_COUNT) { + if (rc || retry != CY_CORE_STARTUP_RETRY_COUNT) { /* reset hardware */ rc = cyttsp5_reset_and_wait(cd); if (rc < 0) { @@ -4773,12 +4777,11 @@ static int cyttsp5_startup_(struct cyttsp5_core_data *cd, bool reset) /* attention startup */ call_atten_cb(cd, CY_ATTEN_STARTUP, 0); + cyttsp5_start_wd_timer(cd); exit: if (!rc) cd->startup_retry_count = 0; - cyttsp5_start_wd_timer(cd); - if (!detected) rc = -ENODEV; @@ -4806,6 +4809,10 @@ static int cyttsp5_startup(struct cyttsp5_core_data *cd, bool reset) rc = cyttsp5_startup_(cd, reset); + /* Wake the waiters for end of startup */ + if (!rc) + wake_up(&cd->wait_q); + if (release_exclusive(cd, cd->dev) < 0) /* Don't return fail code, mode is already changed. */ dev_err(cd->dev, "%s: fail to release exclusive\n", __func__); @@ -4818,9 +4825,6 @@ static int cyttsp5_startup(struct cyttsp5_core_data *cd, bool reset) cd->startup_state = STARTUP_NONE; mutex_unlock(&cd->system_lock); - /* Wake the waiters for end of startup */ - wake_up(&cd->wait_q); - return rc; } @@ -5759,6 +5763,8 @@ static struct cyttsp5_core_commands _cyttsp5_core_commands = { struct cyttsp5_core_commands *cyttsp5_get_commands(void) { + if (!is_cyttsp5_probe_success) + return NULL; return &_cyttsp5_core_commands; } EXPORT_SYMBOL_GPL(cyttsp5_get_commands); @@ -6436,12 +6442,12 @@ int cyttsp5_probe(const struct cyttsp5_bus_ops *ops, struct device *dev, cyttsp5_btn_release(dev); error_startup_mt: cyttsp5_mt_release(dev); + cyttsp5_free_si_ptrs(cd); error_startup: pm_runtime_disable(dev); device_init_wakeup(dev, 0); cancel_work_sync(&cd->startup_work); cyttsp5_stop_wd_timer(cd); - cyttsp5_free_si_ptrs(cd); remove_sysfs_interfaces(dev); error_attr_create: free_irq(cd->irq, cd); @@ -6453,7 +6459,7 @@ int cyttsp5_probe(const struct cyttsp5_bus_ops *ops, struct device *dev, cyttsp5_del_core(dev); dev_set_drvdata(dev, NULL); error_power: - kfree(cd); + cyttsp5_power_init(cd, false); error_alloc_data: error_no_pdata: dev_err(dev, "%s failed.\n", __func__); From 2b61555081ad6173f6da94f7679a68c3f02091f5 Mon Sep 17 00:00:00 2001 From: jiangjia Date: Thu, 1 Aug 2019 14:14:43 +0800 Subject: [PATCH 195/281] ARM: dts: msm: Disable avb for Spyro Spyro is for go devices, enable avb will degrade the performance, including boot time, memory, and latency. Change-Id: I0eeb5a86ac3f1a6fa3393fe7ae9e6ef21bab61af Signed-off-by: Jiangjiang Shen --- arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi index dda1f843338d..6d69b5da984d 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi @@ -152,7 +152,7 @@ "/dev/block/platform/soc/7824900.sdhci/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait,avb"; + fsmgr_flags = "wait"; status = "ok"; }; system { @@ -161,7 +161,7 @@ "/dev/block/platform/soc/7824900.sdhci/by-name/system"; type = "ext4"; mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait,avb"; + fsmgr_flags = "wait"; status = "ok"; }; }; From 72dbad2d5ad5861ce4b37c5bddb7eb76dba1918a Mon Sep 17 00:00:00 2001 From: Tengfei Fan Date: Wed, 17 Jul 2019 09:17:53 +0800 Subject: [PATCH 196/281] AndroidKernel: support compile external modules depend on Image Add TARGET_PREBUILT_INT_KERNEL_IMAGE to support compile modules to dependence on Image. Change-Id: If8f5825c3028fc8cd304cf745bcf68a6b2d28ec4 Signed-off-by: Tengfei Fan --- AndroidKernel.mk | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/AndroidKernel.mk b/AndroidKernel.mk index 790e713c42f5..1c2f92cb9f74 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -210,14 +210,31 @@ $(KERNEL_CONFIG): $(KERNEL_OUT) echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \ $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) oldconfig; fi -$(TARGET_PREBUILT_INT_KERNEL): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) +ifeq ($(TARGET_KERNEL_APPEND_DTB), true) +TARGET_PREBUILT_INT_KERNEL_IMAGE := $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/Image +$(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_USR) +$(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) + $(hide) echo "Building kernel modules..." + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) Image + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) modules + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) modules_install + $(mv-modules) + $(clean-module-folder) + +$(TARGET_PREBUILT_INT_KERNEL): $(TARGET_PREBUILT_INT_KERNEL_IMAGE) $(hide) echo "Building kernel..." $(hide) rm -rf $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) +else +TARGET_PREBUILT_INT_KERNEL_IMAGE := $(TARGET_PREBUILT_INT_KERNEL) +$(TARGET_PREBUILT_INT_KERNEL): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) + $(hide) echo "Building kernel..." + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) modules $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) modules_install $(mv-modules) $(clean-module-folder) +endif $(KERNEL_HEADERS_INSTALL): $(KERNEL_OUT) $(hide) if [ ! -z "$(KERNEL_HEADER_DEFCONFIG)" ]; then \ From f4c6a3a21b46ff5ade7dd6227d488f13d3ffa20b Mon Sep 17 00:00:00 2001 From: Srikanth Uyyala Date: Fri, 12 Jul 2019 16:11:46 +0530 Subject: [PATCH 197/281] msm: camera_v2: reject the late request when request_frame is very late or reg_update is missing for previous frame reject it inform using drop_reconfig flag. Change-Id: Ic7be9c765da63e2c84c4ce2ff05a3cc146f5c2bd Signed-off-by: Srikanth Uyyala Signed-off-by: Sumalatha Malothu --- .../msm/camera_v2/isp/msm_isp_axi_util.c | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) 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 d60982e53867..5d48c7b2ed40 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 @@ -626,12 +626,9 @@ static void msm_isp_update_framedrop_reg(struct msm_vfe_axi_stream *stream_info, MSM_VFE_STREAM_STOP_PERIOD; } - if (stream_info->undelivered_request_cnt > 0 && - drop_reconfig != 1) + if (stream_info->undelivered_request_cnt > 0) stream_info->current_framedrop_period = MSM_VFE_STREAM_STOP_PERIOD; - if (stream_info->controllable_output && drop_reconfig == 1) - stream_info->current_framedrop_period = 1; /* * re-configure the period pattern, only if it's not already * set to what we want @@ -3676,9 +3673,10 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, (stream_info->undelivered_request_cnt <= MAX_BUFFERS_IN_HW) ) { - pr_debug("%s:%d invalid time to request frame %d\n", + pr_debug("%s:%d invalid time to request frame %d try drop_reconfig\n", __func__, __LINE__, frame_id); vfe_dev->isp_page->drop_reconfig = 1; + return 0; } else if ((vfe_dev->axi_data.src_info[frame_src].active) && ((frame_id == vfe_dev->axi_data.src_info[frame_src].frame_id) || @@ -3686,10 +3684,11 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, (stream_info->undelivered_request_cnt <= MAX_BUFFERS_IN_HW)) { vfe_dev->isp_page->drop_reconfig = 1; - pr_debug("%s: vfe_%d request_frame %d cur frame id %d pix %d\n", + pr_debug("%s: vfe_%d request_frame %d cur frame id %d pix %d try drop_reconfig\n", __func__, vfe_dev->pdev->id, frame_id, vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id, vfe_dev->axi_data.src_info[VFE_PIX_0].active); + return 0; } else if ((vfe_dev->axi_data.src_info[frame_src].active && (frame_id != vfe_dev->axi_data.src_info[frame_src].frame_id + vfe_dev-> axi_data.src_info[frame_src].sof_counter_step)) || @@ -3710,19 +3709,18 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, if ((frame_src == VFE_PIX_0) && !stream_info->undelivered_request_cnt && MSM_VFE_STREAM_STOP_PERIOD != stream_info->activated_framedrop_period) { + /* wm is reloaded if undelivered_request_cnt is zero. + * As per the hw behavior wm should be disabled or skip writing + * before reload happens other wise wm could start writing from + * middle of the frame and could result in image corruption. + * instead of dropping frame in this error scenario use + * drop_reconfig flag to process the request in next sof. + */ pr_debug("%s:%d vfe %d frame_id %d prev_pattern %x stream_id %x\n", __func__, __LINE__, vfe_dev->pdev->id, frame_id, stream_info->activated_framedrop_period, stream_info->stream_id); - - rc = msm_isp_return_empty_buffer(vfe_dev, stream_info, - user_stream_id, frame_id, buf_index, frame_src); - if (rc < 0) - pr_err("%s:%d failed: return_empty_buffer src %d\n", - __func__, __LINE__, frame_src); - stream_info->current_framedrop_period = - MSM_VFE_STREAM_STOP_PERIOD; - msm_isp_cfg_framedrop_reg(stream_info); + vfe_dev->isp_page->drop_reconfig = 1; return 0; } From ec9c04b81df0d76b86a46b604f9a680cfc963338 Mon Sep 17 00:00:00 2001 From: Naman Padhiar Date: Mon, 3 Jun 2019 15:13:30 +0530 Subject: [PATCH 198/281] icnss: Synchronize idle shutdown and restart If WLAN interface is not brought up for certain amount of time after it is created, idle shutdown will happen to power off WLAN device. Idle restart will happen to power up WLAN device if WLAN is needed by user again. Add the support in platform driver. Change-Id: I63e85c7de20536fc4146e05146e72537095025e5 Signed-off-by: Naman Padhiar --- drivers/soc/qcom/icnss.c | 108 +++++++++++++++++++++++++++++++++++++++ include/soc/qcom/icnss.h | 4 ++ 2 files changed, 112 insertions(+) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index a2cbfd83a70d..469125717eb5 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -199,6 +199,8 @@ enum icnss_driver_event_type { ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND, + ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN, + ICNSS_DRIVER_EVENT_IDLE_RESTART, ICNSS_DRIVER_EVENT_MAX, }; @@ -291,6 +293,7 @@ enum icnss_driver_state { ICNSS_MODE_ON, ICNSS_BLOCK_SHUTDOWN, ICNSS_PDR, + ICNSS_MODEM_CRASHED, }; struct ce_irq_list { @@ -626,6 +629,10 @@ static char *icnss_driver_event_to_str(enum icnss_driver_event_type type) return "PD_SERVICE_DOWN"; case ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND: return "FW_EARLY_CRASH_IND"; + case ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN: + return "IDLE_SHUTDOWN"; + case ICNSS_DRIVER_EVENT_IDLE_RESTART: + return "IDLE_RESTART"; case ICNSS_DRIVER_EVENT_MAX: return "EVENT_MAX"; } @@ -2361,6 +2368,7 @@ static int icnss_pd_restart_complete(struct icnss_priv *priv) icnss_call_driver_shutdown(priv); clear_bit(ICNSS_PDR, &priv->state); + clear_bit(ICNSS_MODEM_CRASHED, &priv->state); clear_bit(ICNSS_REJUVENATE, &priv->state); clear_bit(ICNSS_PD_RESTART, &priv->state); priv->early_crash_ind = false; @@ -2707,6 +2715,51 @@ static int icnss_driver_event_early_crash_ind(struct icnss_priv *priv, return ret; } +static int icnss_driver_event_idle_shutdown(void *data) +{ + int ret = 0; + + if (!penv->ops || !penv->ops->idle_shutdown) + return 0; + + if (test_bit(ICNSS_MODEM_CRASHED, &penv->state) || + test_bit(ICNSS_PDR, &penv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle shutdown callback\n"); + ret = -EBUSY; + } else { + icnss_pr_dbg("Calling driver idle shutdown, state: 0x%lx\n", + penv->state); + icnss_block_shutdown(true); + ret = penv->ops->idle_shutdown(&penv->pdev->dev); + icnss_block_shutdown(false); + } + + return ret; +} + +static int icnss_driver_event_idle_restart(void *data) +{ + int ret = 0; + + if (!penv->ops || !penv->ops->idle_restart) + return 0; + + if (test_bit(ICNSS_MODEM_CRASHED, &penv->state) || + test_bit(ICNSS_PDR, &penv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle restart callback\n"); + ret = -EBUSY; + } else { + icnss_pr_dbg("Calling driver idle restart, state: 0x%lx\n", + penv->state); + icnss_block_shutdown(true); + ret = penv->ops->idle_restart(&penv->pdev->dev); + icnss_block_shutdown(false); + } + + return ret; +} static void icnss_driver_event_work(struct work_struct *work) { @@ -2753,6 +2806,12 @@ static void icnss_driver_event_work(struct work_struct *work) ret = icnss_driver_event_early_crash_ind(penv, event->data); break; + case ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN: + ret = icnss_driver_event_idle_shutdown(event->data); + break; + case ICNSS_DRIVER_EVENT_IDLE_RESTART: + ret = icnss_driver_event_idle_restart(event->data); + break; default: icnss_pr_err("Invalid Event type: %d", event->type); kfree(event); @@ -2861,6 +2920,9 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, priv->is_ssr = true; + if (notif->crashed) + set_bit(ICNSS_MODEM_CRASHED, &priv->state); + if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) { if (!wait_for_completion_timeout(&priv->unblock_shutdown, @@ -3745,6 +3807,48 @@ int icnss_trigger_recovery(struct device *dev) } EXPORT_SYMBOL(icnss_trigger_recovery); +int icnss_idle_shutdown(struct device *dev) +{ + struct icnss_priv *priv = dev_get_drvdata(dev); + + if (!priv) { + icnss_pr_err("Invalid drvdata: dev %pK", dev); + return -EINVAL; + } + + if (test_bit(ICNSS_MODEM_CRASHED, &priv->state) || + test_bit(ICNSS_PDR, &priv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle shutdown\n"); + return -EBUSY; + } + + return icnss_driver_event_post(ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN, + ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL); +} +EXPORT_SYMBOL(icnss_idle_shutdown); + +int icnss_idle_restart(struct device *dev) +{ + struct icnss_priv *priv = dev_get_drvdata(dev); + + if (!priv) { + icnss_pr_err("Invalid drvdata: dev %pK", dev); + return -EINVAL; + } + + if (test_bit(ICNSS_MODEM_CRASHED, &priv->state) || + test_bit(ICNSS_PDR, &priv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle restart\n"); + return -EBUSY; + } + + return icnss_driver_event_post(ICNSS_DRIVER_EVENT_IDLE_RESTART, + ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL); +} +EXPORT_SYMBOL(icnss_idle_restart); + static int icnss_smmu_init(struct icnss_priv *priv) { @@ -4241,6 +4345,10 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv) continue; case ICNSS_PDR: seq_puts(s, "PDR TRIGGERED"); + continue; + case ICNSS_MODEM_CRASHED: + seq_puts(s, "MODEM CRASHED"); + continue; } seq_printf(s, "UNKNOWN-%d", i); diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h index e55353a1141a..bff4d3f387a0 100644 --- a/include/soc/qcom/icnss.h +++ b/include/soc/qcom/icnss.h @@ -51,6 +51,8 @@ struct icnss_driver_ops { int (*resume_noirq)(struct device *dev); int (*uevent)(struct device *dev, struct icnss_uevent_data *uevent); int (*set_therm_state)(struct device *dev, unsigned long thermal_state); + int (*idle_shutdown)(struct device *dev); + int (*idle_restart)(struct device *dev); }; @@ -151,4 +153,6 @@ extern int icnss_thermal_register(struct device *dev, unsigned long max_state); extern void icnss_thermal_unregister(struct device *dev); extern int icnss_get_curr_therm_state(struct device *dev, unsigned long *thermal_state); +extern int icnss_idle_restart(struct device *dev); +extern int icnss_idle_shutdown(struct device *dev); #endif /* _ICNSS_WLAN_H_ */ From 09d9d6931e2949b02b3cdccc52965e1ed04ca7c5 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Thu, 18 Jul 2019 20:31:08 +0530 Subject: [PATCH 199/281] msm: kgsl: Fix race condition between drawobj and context destroy drawobj_destroy_sync() tries to cancel all pending sync events by taking local copy of pending list. In case of sync point timestamp event, it goes ahead and accesses context's events list assuming that event's context would be alive. But at the same time, if the other context, which is of interest for these sync point events, can be destroyed by cancelling all events in its group. This leads to use-after-free in drawobj_destroy_sync() path. Fix is to give the responsibility of putting the context's ref count to the thread which clears the pending mask. Change-Id: I8d08ef6ddb38ca917f75088071c04727bced11d2 Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/kgsl_drawobj.c | 39 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c index a1e0f4c0d29b..40b49c397a18 100644 --- a/drivers/gpu/msm/kgsl_drawobj.c +++ b/drivers/gpu/msm/kgsl_drawobj.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, 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 @@ -223,8 +223,13 @@ static void drawobj_sync_func(struct kgsl_device *device, trace_syncpoint_timestamp_expire(event->syncobj, event->context, event->timestamp); - drawobj_sync_expire(device, event); - kgsl_context_put(event->context); + /* + * Put down the context ref count only if + * this thread successfully clears the pending bit mask. + */ + if (drawobj_sync_expire(device, event)) + kgsl_context_put(event->context); + kgsl_drawobj_put(&event->syncobj->base); } @@ -254,24 +259,11 @@ static void drawobj_destroy_sparse(struct kgsl_drawobj *drawobj) static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) { struct kgsl_drawobj_sync *syncobj = SYNCOBJ(drawobj); - unsigned long pending = 0; unsigned int i; /* Zap the canary timer */ del_timer_sync(&syncobj->timer); - /* - * Copy off the pending list and clear each pending event atomically - - * this will render any subsequent asynchronous callback harmless. - * This marks each event for deletion. If any pending fence callbacks - * run between now and the actual cancel, the associated structures - * are kfreed only in the cancel call. - */ - for_each_set_bit(i, &syncobj->pending, KGSL_MAX_SYNCPOINTS) { - if (test_and_clear_bit(i, &syncobj->pending)) - __set_bit(i, &pending); - } - /* * Clear all pending events - this will render any subsequent async * callbacks harmless @@ -279,8 +271,12 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) for (i = 0; i < syncobj->numsyncs; i++) { struct kgsl_drawobj_sync_event *event = &syncobj->synclist[i]; - /* Don't do anything if the event has already expired */ - if (!test_bit(i, &pending)) + /* + * Don't do anything if the event has already expired. + * If this thread clears the pending bit mask then it is + * responsible for doing context put. + */ + if (!test_and_clear_bit(i, &syncobj->pending)) continue; switch (event->type) { @@ -288,6 +284,11 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) kgsl_cancel_event(drawobj->device, &event->context->events, event->timestamp, drawobj_sync_func, event); + /* + * Do context put here to make sure the context is alive + * till this thread cancels kgsl event. + */ + kgsl_context_put(event->context); break; case KGSL_CMD_SYNCPOINT_TYPE_FENCE: kgsl_sync_fence_async_cancel(event->handle); @@ -300,7 +301,7 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj) * If we cancelled an event, there's a good chance that the context is * on a dispatcher queue, so schedule to get it removed. */ - if (!bitmap_empty(&pending, KGSL_MAX_SYNCPOINTS) && + if (!bitmap_empty(&syncobj->pending, KGSL_MAX_SYNCPOINTS) && drawobj->device->ftbl->drawctxt_sched) drawobj->device->ftbl->drawctxt_sched(drawobj->device, drawobj->context); From 706e2398bc7aef19c188399dc092a601940e7105 Mon Sep 17 00:00:00 2001 From: Mahesh Voorugonda Date: Mon, 22 Jul 2019 10:37:34 +0530 Subject: [PATCH 200/281] msm: vidc_3x: Add checks to avoid OOB access validate structures and payload sizes in the packet against packet size to avoid OOB access. Change-Id: I8bc3002e51a18e08b212b13af724480ec48994d7 Signed-off-by: Mahesh Voorugonda --- .../msm/vidc_3x/hfi_response_handler.c | 96 +++++++++++++++---- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c index 5dfb4427ba34..abf2ef1686f4 100644 --- a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c @@ -843,6 +843,20 @@ static enum vidc_status hfi_parse_init_done_properties( { enum vidc_status status = VIDC_ERR_NONE; u32 prop_id, next_offset; +#define VALIDATE_PROPERTY_STRUCTURE_SIZE(pkt_size, property_size) ({\ + if (pkt_size < property_size) { \ + status = VIDC_ERR_BAD_PARAM; \ + break; \ + } \ +}) + +#define VALIDATE_PROPERTY_PAYLOAD_SIZE(pkt_size, payload_size, \ + property_count) ({\ + if (pkt_size/payload_size < property_count) { \ + status = VIDC_ERR_BAD_PARAM; \ + break; \ + } \ +}) while (status == VIDC_ERR_NONE && num_properties && rem_bytes >= sizeof(u32)) { @@ -856,6 +870,9 @@ static enum vidc_status hfi_parse_init_done_properties( struct hfi_codec_mask_supported *prop = (struct hfi_codec_mask_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); codecs = prop->codecs; domain = prop->video_domains; @@ -869,11 +886,14 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_capability_supported_info *) (data_ptr + next_offset); - if ((rem_bytes - next_offset) < prop->num_capabilities * - sizeof(struct hfi_capability_supported)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - sizeof(u32), + sizeof(struct hfi_capability_supported), + prop->num_capabilities); + next_offset += sizeof(u32) + prop->num_capabilities * sizeof(struct hfi_capability_supported); @@ -894,10 +914,10 @@ static enum vidc_status hfi_parse_init_done_properties( char *fmt_ptr; struct hfi_uncompressed_plane_info *plane_info; - if ((rem_bytes - next_offset) < sizeof(*prop)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + num_format_entries = prop->format_entries; next_offset = sizeof(*prop); fmt_ptr = (char *)&prop->rg_format_info[0]; @@ -908,17 +928,19 @@ static enum vidc_status hfi_parse_init_done_properties( plane_info = (struct hfi_uncompressed_plane_info *) fmt_ptr; - if ((rem_bytes - next_offset) < - sizeof(*plane_info)) { - status = VIDC_ERR_BAD_PARAM; - break; - } + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*plane_info)); + bytes_to_skip = sizeof(*plane_info) - sizeof(struct hfi_uncompressed_plane_constraints) + plane_info->num_planes * sizeof(struct hfi_uncompressed_plane_constraints); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + bytes_to_skip); fmt_ptr += bytes_to_skip; next_offset += bytes_to_skip; @@ -932,6 +954,13 @@ static enum vidc_status hfi_parse_init_done_properties( struct hfi_properties_supported *prop = (struct hfi_properties_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - sizeof(*prop) + + sizeof(u32), sizeof(u32), + prop->num_properties); next_offset += sizeof(*prop) - sizeof(u32) + prop->num_properties * sizeof(u32); num_properties--; @@ -948,6 +977,9 @@ static enum vidc_status hfi_parse_init_done_properties( (struct hfi_profile_level_supported *) (data_ptr + next_offset); + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); ptr = (char *) &prop->rg_profile_level[0]; prof_count = prop->profile_count; next_offset += sizeof(u32); @@ -960,6 +992,9 @@ static enum vidc_status hfi_parse_init_done_properties( } while (prof_count) { prof_level = (struct hfi_profile_level *)ptr; + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prof_level)); capability. profile_level.profile_level[count].profile = prof_level->profile; @@ -976,6 +1011,9 @@ static enum vidc_status hfi_parse_init_done_properties( } case HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(struct hfi_interlace_format_supported)); next_offset += sizeof(struct hfi_interlace_format_supported); num_properties--; @@ -983,6 +1021,9 @@ static enum vidc_status hfi_parse_init_done_properties( } case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(struct hfi_nal_stream_format_supported)); next_offset += sizeof(struct hfi_nal_stream_format_supported); num_properties--; @@ -990,18 +1031,27 @@ static enum vidc_status hfi_parse_init_done_properties( } case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(u32)); next_offset += sizeof(u32); num_properties--; break; } case HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(u32)); next_offset += sizeof(u32); num_properties--; break; } case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH: { + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(struct hfi_intra_refresh)); next_offset += sizeof(struct hfi_intra_refresh); num_properties--; @@ -1012,13 +1062,21 @@ static enum vidc_status hfi_parse_init_done_properties( struct hfi_buffer_alloc_mode_supported *prop = (struct hfi_buffer_alloc_mode_supported *) (data_ptr + next_offset); - + VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes - + next_offset, + sizeof(*prop)); if (prop->num_entries >= 32) { dprintk(VIDC_ERR, "%s - num_entries: %d from f/w seems suspect\n", __func__, prop->num_entries); break; } + VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes - + next_offset - + sizeof(struct hfi_buffer_alloc_mode_supported) + + sizeof(u32), + sizeof(u32), + prop->num_entries); next_offset += sizeof(struct hfi_buffer_alloc_mode_supported) - sizeof(u32) + prop->num_entries * sizeof(u32); @@ -1036,8 +1094,12 @@ static enum vidc_status hfi_parse_init_done_properties( __func__, data_ptr, prop_id); break; } - rem_bytes -= next_offset; - data_ptr += next_offset; + if (rem_bytes > next_offset) { + rem_bytes -= next_offset; + data_ptr += next_offset; + } else { + rem_bytes = 0; + } } return status; From 4021d2b6f0f0c09b27aac5e68a2ac3c1eb5921b6 Mon Sep 17 00:00:00 2001 From: Sharath Chandra Vurukala Date: Mon, 29 Jul 2019 16:16:50 +0530 Subject: [PATCH 201/281] Revert "fib_rules: fix error in backport of e9919a24d302" This reverts commit b2fc35160871b97f132c8bd00b65558c93529be8. Revert "fib_rules: return 0 directly if an exactly same rule" "exists when NLM_F_EXCL not supplied" This reverts commit 1fff19a925e524556e85efcd728efad5274ce5b6. Change-Id: If18c802f64a41a83721e2ecf06136ac1ae8fa6cb Signed-off-by: Sharath Chandra Vurukala --- net/core/fib_rules.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 268e32005273..31c4041f7586 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -486,10 +486,9 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh) rule->uid_range = fib_kuid_range_unset; } - if (rule_exists(ops, frh, tb, rule)) { - err = 0; - if (nlh->nlmsg_flags & NLM_F_EXCL) - err = -EEXIST; + if ((nlh->nlmsg_flags & NLM_F_EXCL) && + rule_exists(ops, frh, tb, rule)) { + err = -EEXIST; goto errout_free; } From 421f0e0aa74fa0ef116f996d84a9219ef32e541e Mon Sep 17 00:00:00 2001 From: Naitik Bharadiya Date: Tue, 23 Jul 2019 19:17:03 +0530 Subject: [PATCH 202/281] defconfig: msm: Enable/Disable configs for SDM845 Enable/Disable following configs for SDM845 target to align them with android base config. Enable : CONFIG_XFRM_INTERFACE CONFIG_MEMBARRIER CONFIG_ARM64_SW_TTBR0_PAN Disable : CONFIG_PM_AUTOSLEEP CONFIG_DEVMEM CONFIG_DEVKMEM. Change-Id: Ia3fe0c9d9a62580f8e347caae7a6f2448b6477d7 Signed-off-by: Naitik Bharadiya --- arch/arm64/configs/sdm845-perf_defconfig | 4 ++-- arch/arm64/configs/sdm845_defconfig | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index 4529bfb899c0..d25bf1e66ce1 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -38,7 +38,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set @@ -72,6 +71,7 @@ CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y # CONFIG_RANDOMIZE_MODULE_REGION_FULL is not set @@ -79,7 +79,6 @@ CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -96,6 +95,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index c06356427028..04c845573f3d 100755 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -39,7 +39,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -76,12 +75,12 @@ CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_ARM64_VHE is not set CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -99,6 +98,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -319,6 +319,8 @@ CONFIG_INPUT_QPNP_POWER_ON=y CONFIG_INPUT_UINPUT=y # CONFIG_SERIO_SERPORT is not set # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM_GENI=y CONFIG_SERIAL_MSM_GENI_CONSOLE=y CONFIG_DIAG_CHAR=y From d6b2f8956d3c4742d682255e32cfe3a001d658ae Mon Sep 17 00:00:00 2001 From: Naitik Bharadiya Date: Tue, 23 Jul 2019 19:27:03 +0530 Subject: [PATCH 203/281] defconfig: msm: enable CONFIG_USB_RTL8152 for SDM845 Enable config for Realtek RTL8152/RTL8153 based USB Ethernet Adapters for SDM845 target. This is to align them with android base config. Change-Id: I78be67f2ed6636ed68b016427b0d0c990a398b97 Signed-off-by: Naitik Bharadiya --- arch/arm64/configs/sdm845-perf_defconfig | 1 + arch/arm64/configs/sdm845_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index d25bf1e66ce1..693a08590a04 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -292,6 +292,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y CONFIG_WIL6210=m # CONFIG_WIL6210_TRACING is not set diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index 04c845573f3d..4dbeda2ac5fe 100755 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -298,6 +298,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y CONFIG_WIL6210=m CONFIG_WCNSS_MEM_PRE_ALLOC=y From 779f6ba7deb07d14d720cf09b92f3d2e55ae7369 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Tue, 30 Jul 2019 12:13:24 +0530 Subject: [PATCH 204/281] diag: dci: Validate pkt length before parsing for full header Few commands with smaller length than dci packet request header can fail due to present header length check. Modify the length check to cater to smaller length packets. Change-Id: Icf2e45b4eb1be0f2a15f47e58baffe86ece20a1d Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 130 +++++++++++++++++++++++------------ 1 file changed, 87 insertions(+), 43 deletions(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 57d65442057d..12bc3ac5032b 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -726,32 +726,47 @@ int diag_dci_query_event_mask(struct diag_dci_client_tbl *entry, return ((*event_mask_ptr & byte_mask) == byte_mask) ? 1 : 0; } -static int diag_dci_filter_commands(struct diag_pkt_header_t *header) +static int diag_dci_filter_commands(struct diag_pkt_header_t *header, + int header_len) { if (!header) return -ENOMEM; - switch (header->cmd_code) { - case 0x7d: /* Msg Mask Configuration */ - case 0x73: /* Log Mask Configuration */ - case 0x81: /* Event Mask Configuration */ - case 0x82: /* Event Mask Change */ - case 0x60: /* Event Mask Toggle */ - return 1; - } + if (header_len <= 0) + return -EIO; - if (header->cmd_code == 0x4b && header->subsys_id == 0x12) { - switch (header->subsys_cmd_code) { - case 0x60: /* Extended Event Mask Config */ - case 0x61: /* Extended Msg Mask Config */ - case 0x62: /* Extended Log Mask Config */ - case 0x20C: /* Set current Preset ID */ - case 0x20D: /* Get current Preset ID */ - case 0x218: /* HDLC Disabled Command */ + if (header_len) { + switch (header->cmd_code) { + case 0x7d: /* Msg Mask Configuration */ + case 0x73: /* Log Mask Configuration */ + case 0x81: /* Event Mask Configuration */ + case 0x82: /* Event Mask Change */ + case 0x60: /* Event Mask Toggle */ + DIAG_LOG(DIAG_DEBUG_DCI, + "diag: command not supported: %d\n", + header->cmd_code); return 1; } } + if (header_len >= (3*sizeof(uint8_t))) { + if (header->cmd_code == 0x4b && header->subsys_id == 0x12) { + switch (header->subsys_cmd_code) { + case 0x60: /* Extended Event Mask Config */ + case 0x61: /* Extended Msg Mask Config */ + case 0x62: /* Extended Log Mask Config */ + case 0x20C: /* Set current Preset ID */ + case 0x20D: /* Get current Preset ID */ + case 0x218: /* HDLC Disabled Command */ + DIAG_LOG(DIAG_DEBUG_DCI, + "diag: command not supported %d %d %d\n", + header->cmd_code, header->subsys_id, + header->subsys_cmd_code); + return 1; + } + } + } + return 0; } @@ -1800,22 +1815,26 @@ int diag_dci_send_handshake_pkt(int index) static int diag_dci_process_apps_pkt(struct diag_pkt_header_t *pkt_header, unsigned char *req_buf, int req_len, - int tag) + int tag, int pkt_header_len) { - uint8_t cmd_code, subsys_id, i, goto_download = 0; + uint8_t cmd_code = 0, subsys_id = 0, i, goto_download = 0; uint8_t header_len = sizeof(struct diag_dci_pkt_header_t); - uint16_t ss_cmd_code; + uint16_t ss_cmd_code = 0; uint32_t write_len = 0; unsigned char *dest_buf = driver->apps_dci_buf; unsigned char *payload_ptr = driver->apps_dci_buf + header_len; struct diag_dci_pkt_header_t dci_header; - if (!pkt_header || !req_buf || req_len <= 0 || tag < 0) + if (!pkt_header || !req_buf || req_len <= 0 || tag < 0 || + pkt_header_len <= 0) return -EIO; - cmd_code = pkt_header->cmd_code; - subsys_id = pkt_header->subsys_id; - ss_cmd_code = pkt_header->subsys_cmd_code; + if (pkt_header_len >= (sizeof(uint8_t))) + cmd_code = pkt_header->cmd_code; + if (pkt_header_len >= (2 * sizeof(uint8_t))) + subsys_id = pkt_header->subsys_id; + if (pkt_header_len >= (3 * sizeof(uint8_t))) + ss_cmd_code = pkt_header->subsys_cmd_code; if (cmd_code == DIAG_CMD_DOWNLOAD) { *payload_ptr = DIAG_CMD_DOWNLOAD; @@ -1935,7 +1954,7 @@ static int diag_dci_process_apps_pkt(struct diag_pkt_header_t *pkt_header, static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) { int ret = DIAG_DCI_TABLE_ERR; - int common_cmd = 0; + int common_cmd = 0, header_len = 0; struct diag_pkt_header_t *header = NULL; unsigned char *temp = buf; unsigned char *req_buf = NULL; @@ -1951,8 +1970,7 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) if (!buf) return -EIO; - if (len < (sizeof(struct dci_pkt_req_t) + - sizeof(struct diag_pkt_header_t)) || + if (len < sizeof(struct dci_pkt_req_t) || len > DCI_REQ_BUF_SIZE) { pr_err("diag: dci: Invalid length %d len in %s", len, __func__); return -EIO; @@ -1963,13 +1981,6 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) read_len += sizeof(struct dci_pkt_req_t); req_len -= sizeof(struct dci_pkt_req_t); req_buf = temp; /* Start of the Request */ - header = (struct diag_pkt_header_t *)temp; - read_len += sizeof(struct diag_pkt_header_t); - if (read_len >= DCI_REQ_BUF_SIZE) { - pr_err("diag: dci: In %s, invalid read_len: %d\n", __func__, - read_len); - return -EIO; - } mutex_lock(&driver->dci_mutex); dci_entry = diag_dci_get_client_entry(req_hdr.client_id); @@ -1980,11 +1991,40 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) return DIAG_DCI_NO_REG; } + header = (void *)temp; + header_len = len - sizeof(struct dci_pkt_req_t); + if (header_len <= 0) { + mutex_unlock(&driver->dci_mutex); + return -EIO; + } + if (header_len >= sizeof(uint8_t)) { + header->cmd_code = (uint16_t)(*(uint8_t *)temp); + read_len += sizeof(uint8_t); + } + if (header_len >= (2 * sizeof(uint8_t))) { + temp += sizeof(uint8_t); + header->subsys_id = (uint16_t)(*(uint8_t *)temp); + read_len += sizeof(uint8_t); + } + if (header_len == (3 * sizeof(uint8_t))) { + temp += sizeof(uint8_t); + header->subsys_cmd_code = (uint16_t)(*(uint8_t *)temp); + read_len += sizeof(uint8_t); + } else if (header_len >= + (2 * sizeof(uint8_t)) + sizeof(uint16_t)) { + temp += sizeof(uint8_t); + header->subsys_cmd_code = (uint16_t)(*(uint16_t *)temp); + read_len += sizeof(uint16_t); + } + if (read_len > DCI_REQ_BUF_SIZE) { + pr_err("diag: dci: In %s, invalid read_len: %d\n", __func__, + read_len); + mutex_unlock(&driver->dci_mutex); + return -EIO; + } + /* Check if the command is allowed on DCI */ - if (diag_dci_filter_commands(header)) { - pr_debug("diag: command not supported %d %d %d", - header->cmd_code, header->subsys_id, - header->subsys_cmd_code); + if (diag_dci_filter_commands(header, header_len)) { mutex_unlock(&driver->dci_mutex); return DIAG_DCI_SEND_DATA_FAIL; } @@ -2038,14 +2078,18 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) /* Check if it is a dedicated Apps command */ ret = diag_dci_process_apps_pkt(header, req_buf, req_len, - req_entry->tag); + req_entry->tag, header_len); if ((ret == DIAG_DCI_NO_ERROR && !common_cmd) || ret < 0) return ret; - reg_entry.cmd_code = header->cmd_code; - reg_entry.subsys_id = header->subsys_id; - reg_entry.cmd_code_hi = header->subsys_cmd_code; - reg_entry.cmd_code_lo = header->subsys_cmd_code; + if (header_len >= (sizeof(uint8_t))) + reg_entry.cmd_code = header->cmd_code; + if (header_len >= (2 * sizeof(uint8_t))) + reg_entry.subsys_id = header->subsys_id; + if (header_len >= (3 * sizeof(uint8_t))) { + reg_entry.cmd_code_hi = header->subsys_cmd_code; + reg_entry.cmd_code_lo = header->subsys_cmd_code; + } mutex_lock(&driver->cmd_reg_mutex); temp_entry = diag_cmd_search(®_entry, ALL_PROC); From 130c3606929c0323b8225df135db7d41c0804583 Mon Sep 17 00:00:00 2001 From: Raja Mallik Date: Mon, 22 Jul 2019 12:21:54 +0530 Subject: [PATCH 205/281] Merge remote-tracking branch 'dev/msm-4.14' into msm-4.9 07/03 * commit '8819f223628c45a1934349cff8e7c7e2f27190c0': msm: camera: sensor: Add check to know if device acquired msm: camera: isp: remove the check for bpp msm: camera: jpeg: Check the HW state before accessing register msm: camera: isp: Enabling critical logs to improve debugging msm: camera: cpas: Avoid array underflow during client registration msm: camera: isp: Halt device with the command parsed msm: camera: core: Fix context release timing issue msm: camera: mem: print error value msm: camera: isp: Update the context hw events dump msm: camera: smmu: Set smmu non fatal flag true msm: camera: isp: Buffer size validation at IFE Change-Id: Iee23d9b045065e8a5569c3ad7355333d2825d3a3 Signed-off-by: Raja Mallik --- .../camera_v3/cam_core/cam_context_utils.c | 18 +- .../msm/camera_v3/cam_cpas/cam_cpas_hw.c | 7 + .../msm/camera_v3/cam_isp/cam_isp_context.c | 326 +++++++++++------- .../msm/camera_v3/cam_isp/cam_isp_context.h | 58 ++-- .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 4 +- .../hw_utils/cam_isp_packet_parser.c | 19 + .../jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c | 33 ++ .../cam_sensor/cam_sensor_core.c | 10 + .../msm/camera_v3/cam_smmu/cam_smmu_api.c | 2 +- .../msm/camera_v3/cam_sync/cam_sync.c | 32 ++ .../msm/camera_v3/cam_sync/cam_sync_api.h | 11 +- .../msm/camera_v3/cam_utils/cam_packet_util.c | 112 ++++++ .../msm/camera_v3/cam_utils/cam_packet_util.h | 16 + 13 files changed, 501 insertions(+), 147 deletions(-) diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c index 7600cbb77cee..11bad5dd4647 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c @@ -461,6 +461,17 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, "[%s][%d] : Moving req[%llu] from free_list to pending_list", ctx->dev_name, ctx->ctx_id, req->request_id); + for (j = 0; j < req->num_in_map_entries; j++) { + rc = cam_sync_check_valid( + req->in_map_entries[j].sync_id); + if (rc) { + CAM_ERR(CAM_CTXT, + "invalid in map sync object %d", + req->in_map_entries[j].sync_id); + goto put_ref; + } + } + for (j = 0; j < req->num_in_map_entries; j++) { cam_context_getref(ctx); rc = cam_sync_register_callback( @@ -482,7 +493,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, ctx->dev_name, ctx->ctx_id, req->request_id); - goto put_ctx_ref; + cam_context_putref(ctx); + goto put_ref; + } CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d", req->in_map_entries[j].sync_id, rc); @@ -491,9 +504,6 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, } return rc; -put_ctx_ref: - for (--j; j >= 0; j--) - cam_context_putref(ctx); put_ref: for (--i; i >= 0; i--) { rc = cam_sync_put_obj_ref(req->out_map_entries[i].sync_id); diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c index 4276b356da73..a68032cf6c19 100644 --- a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c +++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c @@ -1234,6 +1234,13 @@ static int cam_cpas_hw_register_client(struct cam_hw_info *cpas_hw, rc = cam_common_util_get_string_index(soc_private->client_name, soc_private->num_clients, client_name, &client_indx); + if (rc) { + CAM_ERR(CAM_CPAS, "No match found for client %s", + client_name); + mutex_unlock(&cpas_hw->hw_mutex); + return rc; + } + mutex_lock(&cpas_core->client_mutex[client_indx]); if (rc || !CAM_CPAS_CLIENT_VALID(client_indx) || diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c index 57375c4ad50f..1eb7389b2516 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c @@ -38,18 +38,26 @@ static int cam_isp_context_dump_active_request(void *data, unsigned long iova, static void __cam_isp_ctx_update_state_monitor_array( struct cam_isp_context *ctx_isp, - enum cam_isp_state_change_trigger trigger_type, - uint32_t req_id) + enum cam_isp_hw_event_type hw_event, + enum cam_isp_ctx_activated_substate curr_state, + enum cam_isp_ctx_activated_substate next_state) { int iterator = 0; iterator = INC_STATE_MONITOR_HEAD(&ctx_isp->state_monitor_head); ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state = - ctx_isp->substate_activated; - ctx_isp->cam_isp_ctx_state_monitor[iterator].trigger = - trigger_type; - ctx_isp->cam_isp_ctx_state_monitor[iterator].req_id = - req_id; + curr_state; + ctx_isp->cam_isp_ctx_state_monitor[iterator].next_state = + next_state; + ctx_isp->cam_isp_ctx_state_monitor[iterator].hw_event = + hw_event; + ctx_isp->cam_isp_ctx_state_monitor[iterator].last_reported_id = + ctx_isp->req_info.reported_req_id; + ctx_isp->cam_isp_ctx_state_monitor[iterator].last_applied_req_id = + ctx_isp->req_info.last_applied_req_id; + ctx_isp->cam_isp_ctx_state_monitor[iterator].frame_id = + ctx_isp->frame_id; + ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp = jiffies_to_msecs(jiffies); } @@ -79,17 +87,17 @@ static const char *__cam_isp_hw_evt_val_to_type( uint32_t evt_id) { switch (evt_id) { - case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR: + case CAM_ISP_HW_EVENT_ERROR: return "ERROR"; - case CAM_ISP_STATE_CHANGE_TRIGGER_SOF: + case CAM_ISP_HW_EVENT_SOF: return "SOF"; - case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE: + case CAM_ISP_HW_EVENT_REG_UPDATE: return "REG_UPDATE"; - case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH: + case CAM_ISP_HW_EVENT_EPOCH: return "EPOCH"; - case CAM_ISP_STATE_CHANGE_TRIGGER_EOF: + case CAM_ISP_HW_EVENT_EOF: return "EOF"; - case CAM_ISP_STATE_CHANGE_TRIGGER_DONE: + case CAM_ISP_HW_EVENT_DONE: return "DONE"; default: return "CAM_ISP_EVENT_INVALID"; @@ -97,29 +105,58 @@ static const char *__cam_isp_hw_evt_val_to_type( } static void __cam_isp_ctx_dump_state_monitor_array( - struct cam_isp_context *ctx_isp) + struct cam_isp_context *ctx_isp, bool log_rate_limit) { int i = 0; uint64_t state_head = 0; uint64_t index; + struct cam_isp_context_state_monitor *ctx_monitor; state_head = atomic64_read(&ctx_isp->state_monitor_head); - CAM_ERR_RATE_LIMIT(CAM_ISP, - "Dumping state information for preceding requests"); + + ctx_monitor = ctx_isp->cam_isp_ctx_state_monitor; + + if (log_rate_limit) + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "Dumping state information for preceding requests"); + else + CAM_INFO(CAM_ISP, + "Dumping state information for preceding requests"); for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0; i--) { index = (((state_head - i) + CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) % CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES); - CAM_ERR_RATE_LIMIT(CAM_ISP, - "time[0x%llx] req_id[%u] state[%s] evt_type[%s]", - ctx_isp->cam_isp_ctx_state_monitor[index].evt_time_stamp, - ctx_isp->cam_isp_ctx_state_monitor[index].req_id, - __cam_isp_ctx_substate_val_to_type( - ctx_isp->cam_isp_ctx_state_monitor[index].curr_state), - __cam_isp_hw_evt_val_to_type( - ctx_isp->cam_isp_ctx_state_monitor[index].trigger)); + + if (log_rate_limit) { + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "time[%lld] last reported req_id[%lld] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]", + ctx_monitor[index].evt_time_stamp, + ctx_monitor[index].last_reported_id, + ctx_monitor[index].frame_id, + ctx_monitor[index].last_applied_req_id, + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].curr_state), + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].next_state), + __cam_isp_hw_evt_val_to_type( + ctx_monitor[index].hw_event)); + + } else { + CAM_INFO(CAM_ISP, + "time[%lld] last reported req_id[%lld] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]", + ctx_monitor[index].evt_time_stamp, + ctx_monitor[index].last_reported_id, + ctx_monitor[index].frame_id, + ctx_monitor[index].last_applied_req_id, + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].curr_state), + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].next_state), + __cam_isp_hw_evt_val_to_type( + ctx_monitor[index].hw_event)); + } } } @@ -403,7 +440,7 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( struct cam_context *ctx = ctx_isp->base; if (list_empty(&ctx->active_req_list)) { - CAM_DBG(CAM_ISP, "Buf done with no active request!"); + CAM_WARN(CAM_ISP, "Buf done with no active request!"); goto end; } @@ -508,6 +545,10 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( CAM_DBG(CAM_REQ, "Move active request %lld to pending list(cnt = %d) [bubble recovery], ctx %u", req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); + __cam_isp_ctx_update_state_monitor_array(ctx_isp, + CAM_ISP_HW_EVENT_DONE, + ctx_isp->substate_activated, + ctx_isp->substate_activated); } else { list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); @@ -515,12 +556,16 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( CAM_DBG(CAM_REQ, "Move active request %lld to free list(cnt = %d) [all fences done], ctx %u", req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); + ctx_isp->req_info.last_bufdone_req_id = req->request_id; + ctx_isp->req_info.last_bufdone_time_stamp = + jiffies_to_msecs(jiffies); + __cam_isp_ctx_update_state_monitor_array(ctx_isp, + CAM_ISP_HW_EVENT_DONE, + ctx_isp->substate_activated, + ctx_isp->substate_activated); } end: - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_DONE, - ctx_isp->base->req_list->request_id); return rc; } @@ -665,9 +710,12 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( } list_for_each_entry(req, &ctx->active_req_list, list) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > + ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); break; } } @@ -675,6 +723,17 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( if (ctx_isp->substate_activated == CAM_ISP_CTX_ACTIVATED_BUBBLE) request_id = 0; + if (request_id && ctx_isp->req_info.reported_req_id && + ((request_id - ctx_isp->req_info.reported_req_id) > + 1)){ + CAM_INFO(CAM_ISP, + "ctx:%d curr req id: %lld last reported id:%lld", + ctx->ctx_id, request_id, + ctx_isp->req_info.reported_req_id); + + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); + } + __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); } else { @@ -742,8 +801,7 @@ static int __cam_isp_ctx_sof_in_activated_state( ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->boot_timestamp = sof_event_data->boot_time; - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id); + CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u", ctx_isp->frame_id, ctx_isp->sof_timestamp_val, ctx->ctx_id); @@ -778,11 +836,7 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, CAM_ERR(CAM_ISP, "receive rup in unexpected state"); } - if (req != NULL) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, - req->request_id); - } + end: return rc; } @@ -800,7 +854,8 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, * If no wait req in epoch, this is an error case. * The recovery is to go back to sof state */ - CAM_ERR(CAM_ISP, "No wait request"); + CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; /* Send SOF event as empty frame*/ @@ -815,7 +870,9 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; - CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); + CAM_INFO(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld", + ctx->ctx_id, req_isp->bubble_report, req->request_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; @@ -842,9 +899,11 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, list_del_init(&req->list); list_add_tail(&req->list, &ctx->active_req_list); - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); } __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); @@ -853,15 +912,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: - if (request_id == 0) { - req = list_last_entry(&ctx->active_req_list, - struct cam_ctx_request, list); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); - } else { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, request_id); - } + return 0; } @@ -884,7 +935,6 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp, int rc = 0; struct cam_context *ctx = ctx_isp->base; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; - struct cam_ctx_request *req; if (!evt_data) { CAM_ERR(CAM_ISP, "in valid sof event data"); @@ -900,12 +950,6 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp, else CAM_DBG(CAM_ISP, "Still need to wait for the buf done"); - req = list_last_entry(&ctx->active_req_list, - struct cam_ctx_request, list); - if (req) - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, - ctx->req_list->request_id); CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); @@ -952,7 +996,8 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( * If no pending req in epoch, this is an error case. * Just go back to the bubble state. */ - CAM_ERR(CAM_ISP, "No pending request."); + CAM_ERR(CAM_ISP, "ctx:%d No pending request.", ctx->ctx_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); @@ -964,6 +1009,9 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; + CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld", + ctx->ctx_id, req_isp->bubble_report, req->request_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { @@ -992,9 +1040,11 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( list_add_tail(&req->list, &ctx->active_req_list); if (!req_isp->bubble_report) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); } else @@ -1007,11 +1057,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: - req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request, - list); - if (req) - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); + return 0; } @@ -1023,9 +1069,7 @@ static int __cam_isp_ctx_buf_done_in_bubble_applied( (struct cam_isp_hw_done_event_data *) evt_data; rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_DONE, - ctx_isp->base->req_list->request_id); + return rc; } @@ -1083,9 +1127,6 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, if (error_event_data->enable_reg_dump) cam_isp_ctx_dump_req(req_isp); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, req_to_dump->request_id); - list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) { req_isp = (struct cam_isp_ctx_req *) req->req_priv; @@ -1176,14 +1217,15 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, end: do { if (list_empty(&ctx->pending_req_list)) { - error_request_id = ctx_isp->last_applied_req_id + 1; + error_request_id = + ctx_isp->req_info.last_applied_req_id + 1; req_isp = NULL; break; } req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, list); req_isp = (struct cam_isp_ctx_req *) req->req_priv; - error_request_id = ctx_isp->last_applied_req_id; + error_request_id = ctx_isp->req_info.last_applied_req_id; if (req_isp->bubble_report) { req_to_report = req; @@ -1201,7 +1243,8 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); - } while (req->request_id < ctx_isp->last_applied_req_id); + } while (req->request_id < + ctx_isp->req_info.last_applied_req_id); if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { notify.link_hdl = ctx->link_hdl; @@ -1240,8 +1283,8 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, V4L_EVENT_CAM_REQ_MGR_EVENT)) CAM_ERR(CAM_ISP, "Error in notifying the error time for req id:%lld ctx %u", - ctx_isp->last_applied_req_id, - ctx->ctx_id); + ctx_isp->req_info.last_applied_req_id, + ctx->ctx_id); } ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HW_ERROR; } else { @@ -1278,8 +1321,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state( ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->boot_timestamp = sof_event_data->boot_time; - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id); + CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx", ctx_isp->frame_id, ctx_isp->sof_timestamp_val); @@ -1300,9 +1342,12 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state( } list_for_each_entry(req, &ctx->active_req_list, list) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > + ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); break; } } @@ -1343,8 +1388,10 @@ static int __cam_isp_ctx_fs2_buf_done(struct cam_isp_context *ctx_isp, CAM_DBG(CAM_ISP, "No request, move to SOF"); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; - if (ctx_isp->reported_req_id < curr_req_id) { - ctx_isp->reported_req_id = curr_req_id; + if (ctx_isp->req_info.reported_req_id < curr_req_id) { + ctx_isp->req_info.reported_req_id = curr_req_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); __cam_isp_ctx_send_sof_timestamp(ctx_isp, curr_req_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); @@ -1402,11 +1449,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp, CAM_ERR(CAM_ISP, "receive rup in unexpected state"); } - if (req != NULL) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, - req->request_id); - } + end: return rc; } @@ -1451,9 +1494,12 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger && ctx_isp->active_req_cnt <= 2) { list_for_each_entry(req, &ctx->active_req_list, list) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > + ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); break; } } @@ -1478,11 +1524,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: - if (req != NULL && !rc) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, - req->request_id); - } + return rc; } @@ -1729,19 +1771,19 @@ static int __cam_isp_ctx_apply_req_in_activated_state( } else { spin_lock_bh(&ctx->lock); ctx_isp->substate_activated = next_state; - ctx_isp->last_applied_req_id = apply->request_id; + ctx_isp->req_info.last_applied_req_id = + apply->request_id; + ctx_isp->req_info.last_applied_time_stamp = + jiffies_to_msecs(jiffies); list_del_init(&req->list); list_add_tail(&req->list, &ctx->wait_req_list); CAM_DBG(CAM_ISP, "new substate state %d, applied req %lld", - next_state, ctx_isp->last_applied_req_id); + next_state, + ctx_isp->req_info.last_applied_req_id); spin_unlock_bh(&ctx->lock); } end: - if (ctx_isp != NULL) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, - ctx->req_list->request_id); - } + return rc; } @@ -1875,6 +1917,23 @@ static int __cam_isp_ctx_flush_req_in_top_state( CAM_DBG(CAM_ISP, "try to flush pending list"); spin_lock_bh(&ctx->lock); rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req); + + if (!list_empty(&ctx->active_req_list)) { + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "ctx:%d last applied id:%lld, reported req id:%lld, buf done id:%lld", + ctx->ctx_id, + ctx_isp->req_info.last_applied_req_id, + ctx_isp->req_info.reported_req_id, + ctx_isp->req_info.last_bufdone_req_id); + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "current time:%u last apply time:%lld, reported req time:%lld, buf done time:%lld", + jiffies_to_msecs(jiffies), + ctx_isp->req_info.last_applied_time_stamp, + ctx_isp->req_info.last_reported_id_time_stamp, + ctx_isp->req_info.last_bufdone_time_stamp); + + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); + } spin_unlock_bh(&ctx->lock); atomic_set(&ctx_isp->process_bubble, 0); @@ -2133,8 +2192,10 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; + CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld", + ctx->ctx_id, req_isp->bubble_report, req->request_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); - CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; @@ -2161,9 +2222,11 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied( req->request_id, ctx_isp->active_req_cnt); if (!req_isp->bubble_report) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); } else @@ -2305,8 +2368,11 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( } else { CAM_ERR(CAM_ISP, "Can not notify SOF to CRM"); } - if (request_id) - ctx_isp->reported_req_id = request_id; + if (request_id) { + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); + } __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); @@ -2481,9 +2547,14 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx, ctx->last_flush_req = 0; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; ctx_isp->hw_acquired = false; ctx_isp->init_received = false; + ctx_isp->req_info.reported_req_id = 0; + ctx_isp->req_info.last_applied_req_id = 0; + ctx_isp->req_info.last_bufdone_req_id = 0; + ctx_isp->req_info.last_applied_time_stamp = 0; + ctx_isp->req_info.last_bufdone_time_stamp = 0; + ctx_isp->req_info.last_reported_id_time_stamp = 0; /* * Ideally, we should never have any active request here. @@ -2538,11 +2609,16 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx, ctx->last_flush_req = 0; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; ctx_isp->hw_acquired = false; ctx_isp->init_received = false; ctx_isp->rdi_only_context = false; ctx_isp->split_acquire = false; + ctx_isp->req_info.reported_req_id = 0; + ctx_isp->req_info.last_applied_req_id = 0; + ctx_isp->req_info.last_bufdone_req_id = 0; + ctx_isp->req_info.last_applied_time_stamp = 0; + ctx_isp->req_info.last_bufdone_time_stamp = 0; + ctx_isp->req_info.last_reported_id_time_stamp = 0; /* * Ideally, we should never have any active request here. @@ -3169,7 +3245,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, atomic_set(&ctx_isp->process_bubble, 0); ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; + ctx_isp->req_info.reported_req_id = 0; ctx_isp->substate_activated = ctx_isp->rdi_only_context ? CAM_ISP_CTX_ACTIVATED_APPLIED : (req_isp->num_fence_map_out) ? CAM_ISP_CTX_ACTIVATED_EPOCH : @@ -3301,7 +3377,13 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( } ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; + ctx_isp->req_info.reported_req_id = 0; + ctx_isp->req_info.last_applied_req_id = 0; + ctx_isp->req_info.last_bufdone_req_id = 0; + ctx_isp->req_info.last_applied_time_stamp = 0; + ctx_isp->req_info.last_bufdone_time_stamp = 0; + ctx_isp->req_info.last_reported_id_time_stamp = 0; + atomic_set(&ctx_isp->process_bubble, 0); CAM_DBG(CAM_ISP, "Stop device success next state %d on ctx %u", @@ -3478,8 +3560,9 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx, rc = ctx_ops->crm_ops.apply_req(ctx, apply); } else { CAM_ERR_RATE_LIMIT(CAM_ISP, - "No handle function in activated substate %d", - ctx_isp->substate_activated); + "Ctx:%d No handle function in activated substate %d", + ctx->ctx_id, ctx_isp->substate_activated); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); rc = -EFAULT; } @@ -3500,22 +3583,27 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context, struct cam_context *ctx = (struct cam_context *)context; struct cam_isp_context *ctx_isp = (struct cam_isp_context *)ctx->ctx_priv; + enum cam_isp_ctx_activated_substate curr_state; spin_lock(&ctx->lock); trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id, __cam_isp_ctx_get_event_ts(evt_id, evt_data)); + curr_state = ctx_isp->substate_activated; CAM_DBG(CAM_ISP, "Enter: State %d, Substate %d, evt id %d", ctx->state, ctx_isp->substate_activated, evt_id); irq_ops = &ctx_isp->substate_machine_irq[ctx_isp->substate_activated]; if (irq_ops->irq_ops[evt_id]) { rc = irq_ops->irq_ops[evt_id](ctx_isp, evt_data); } else { - CAM_DBG(CAM_ISP, "No handle function for substate %d", - ctx_isp->substate_activated); - __cam_isp_ctx_dump_state_monitor_array(ctx_isp); + CAM_INFO(CAM_ISP, "Ctx:%d No handle function for substate %d", + ctx->ctx_id, ctx_isp->substate_activated); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); } + if (evt_id != CAM_ISP_HW_EVENT_DONE) + __cam_isp_ctx_update_state_monitor_array(ctx_isp, evt_id, + curr_state, ctx_isp->substate_activated); CAM_DBG(CAM_ISP, "Exit: State %d Substate %d", ctx->state, ctx_isp->substate_activated); @@ -3677,7 +3765,13 @@ int cam_isp_context_init(struct cam_isp_context *ctx, ctx->base = ctx_base; ctx->frame_id = 0; ctx->active_req_cnt = 0; - ctx->reported_req_id = 0; + ctx->req_info.reported_req_id = 0; + ctx->req_info.last_applied_req_id = 0; + ctx->req_info.last_bufdone_req_id = 0; + ctx->req_info.last_applied_time_stamp = 0; + ctx->req_info.last_bufdone_time_stamp = 0; + ctx->req_info.last_reported_id_time_stamp = 0; + ctx->hw_ctx = NULL; ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; ctx->substate_machine = cam_isp_ctx_activated_state_machine; diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h index 4954f2034144..bec84a85391c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h @@ -61,20 +61,6 @@ enum cam_isp_ctx_activated_substate { CAM_ISP_CTX_ACTIVATED_MAX, }; -/** - * enum cam_isp_state_change_trigger - Different types of ISP events - * - */ -enum cam_isp_state_change_trigger { - CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, - CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, - CAM_ISP_STATE_CHANGE_TRIGGER_EOF, - CAM_ISP_STATE_CHANGE_TRIGGER_DONE, - CAM_ISP_STATE_CHANGE_TRIGGER_MAX -}; - /** * struct cam_isp_ctx_irq_ops - Function table for handling IRQ callbacks * @@ -125,19 +111,46 @@ struct cam_isp_ctx_req { * debug purposes * *@curr_state: Current sub state that received req - *@req_type: Event type of incoming req - *@req_id: Request id - *@evt_time_stamp Current time stamp + *@next_state: Next sub state that received req + *@hw_event: Hw Event type of incoming req + *@last_reported_id: Last_reported_id to userspace + *@last_applied_req_id Last applied request id to hardware + *@frame_id: Current Frame id + *@evt_time_stamp Current time stamp of this event logged * */ struct cam_isp_context_state_monitor { enum cam_isp_ctx_activated_substate curr_state; - enum cam_isp_state_change_trigger trigger; - uint32_t req_id; + enum cam_isp_ctx_activated_substate next_state; + enum cam_isp_hw_event_type hw_event; + int64_t last_reported_id; + int64_t last_applied_req_id; int64_t frame_id; uint64_t evt_time_stamp; }; +/** + * struct cam_isp_context_req_id_info - ISP context request id + * information for last applied, reported and bufdone. + * + *@last_applied_req_id: Last applied request id + *@last_bufdone_req_id: Last bufdone request id + *@reported_req_id: Last reported request id to userspace + *@last_applied_time_stamp: Last applied request time stamp information + *@last_bufdone_time_stamp Last bufdone request time stamp information + *@last_reported_id_time_stamp: Last reported request time stamp information + * + */ + +struct cam_isp_context_req_id_info { + int64_t last_applied_req_id; + int64_t last_bufdone_req_id; + int64_t reported_req_id; + int64_t last_applied_time_stamp; + int64_t last_bufdone_time_stamp; + int64_t last_reported_id_time_stamp; + +}; /** * struct cam_isp_context - ISP context object * @@ -154,11 +167,11 @@ struct cam_isp_context_state_monitor { * @sof_timestamp_val: Captured time stamp value at sof hw event * @boot_timestamp: Boot time stamp for a given req_id * @active_req_cnt: Counter for the active request - * @reported_req_id: Last reported request id * @subscribe_event: The irq event mask that CRM subscribes to, IFE * will invoke CRM cb at those event. - * @last_applied_req_id: Last applied request id * @state_monitor_head: Write index to the state monitoring array + * @req_info Request id information about last applied, + * reported and buf done * @cam_isp_ctx_state_monitor: State monitoring array * @rdi_only_context: Get context type information. * true, if context is rdi only context @@ -183,12 +196,11 @@ struct cam_isp_context { uint64_t sof_timestamp_val; uint64_t boot_timestamp; int32_t active_req_cnt; - int64_t reported_req_id; uint32_t subscribe_event; - int64_t last_applied_req_id; atomic64_t state_monitor_head; struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES]; + struct cam_isp_context_req_id_info req_info; bool rdi_only_context; bool hw_acquired; bool init_received; diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index fe3d2f12a6e2..9b4839261c3e 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -2637,7 +2637,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) /* Stop the master CSID path first */ cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid, - master_base_idx, CAM_CSID_HALT_AT_FRAME_BOUNDARY); + master_base_idx, csid_halt_type); /* stop rest of the CSID paths */ for (i = 0; i < ctx->num_base; i++) { @@ -2647,7 +2647,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) ctx->base[i].idx, i, master_base_idx); cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid, - ctx->base[i].idx, CAM_CSID_HALT_AT_FRAME_BOUNDARY); + ctx->base[i].idx, csid_halt_type); } CAM_DBG(CAM_ISP, "Stopping master CID idx %d", master_base_idx); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index 0b3c3874a704..5efab9f289dd 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -467,6 +467,7 @@ int cam_isp_add_io_buffers( int32_t hdl; int mmu_hdl; bool mode, is_buf_secure; + uint64_t req_id; io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *) &prepare->packet->payload + @@ -475,6 +476,7 @@ int cam_isp_add_io_buffers( num_in_buf = 0; io_cfg_used_bytes = 0; prepare->pf_data->packet = prepare->packet; + req_id = prepare->packet->header.request_id; /* Max one hw entries required for each base */ if (prepare->num_hw_update_entries + 1 >= @@ -622,6 +624,23 @@ int cam_isp_add_io_buffers( return rc; } + if (j == 0) { + rc = cam_packet_validate_plane_size( + &io_cfg[i], + plane_id, + size); + if (rc) { + CAM_ERR(CAM_ISP, + "Invalid buffer size, port 0x%x plane %d req_id %llu format %d memh 0x%x", + io_cfg[i].resource_type, + plane_id, + req_id, + io_cfg[i].format, + io_cfg[i].mem_handle[plane_id]); + return -EINVAL; + } + } + /* need to update with offset */ io_addr[plane_id] += io_cfg[i].offsets[plane_id]; diff --git a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c index 52907cd6803e..225f859674f1 100644 --- a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c @@ -91,6 +91,9 @@ int cam_jpeg_enc_init_hw(void *device_priv, CAM_ERR(CAM_JPEG, "soc enable is failed %d", rc); goto soc_failed; } + spin_lock(&jpeg_enc_dev->hw_lock); + jpeg_enc_dev->hw_state = CAM_HW_STATE_POWER_UP; + spin_unlock(&jpeg_enc_dev->hw_lock); mutex_unlock(&core_info->core_mutex); @@ -140,6 +143,9 @@ int cam_jpeg_enc_deinit_hw(void *device_priv, return -EFAULT; } + spin_lock(&jpeg_enc_dev->hw_lock); + jpeg_enc_dev->hw_state = CAM_HW_STATE_POWER_DOWN; + spin_unlock(&jpeg_enc_dev->hw_lock); rc = cam_jpeg_enc_disable_soc_resources(soc_info); if (rc) CAM_ERR(CAM_JPEG, "soc disable failed %d", rc); @@ -173,12 +179,19 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data) hw_info = core_info->jpeg_enc_hw_info; mem_base = soc_info->reg_map[0].mem_base; + spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + return -EINVAL; + } irq_status = cam_io_r_mb(mem_base + core_info->jpeg_enc_hw_info->reg_offset.int_status); cam_io_w_mb(irq_status, soc_info->reg_map[0].mem_base + core_info->jpeg_enc_hw_info->reg_offset.int_clr); + spin_unlock(&jpeg_enc_dev->hw_lock); CAM_DBG(CAM_JPEG, "irq_num %d irq_status = %x , core_state %d", irq_num, irq_status, core_info->core_state); @@ -268,6 +281,12 @@ int cam_jpeg_enc_reset_hw(void *data, mutex_lock(&core_info->core_mutex); spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + mutex_unlock(&core_info->core_mutex); + return -EINVAL; + } if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) { CAM_ERR(CAM_JPEG, "alrady resetting"); spin_unlock(&jpeg_enc_dev->hw_lock); @@ -319,10 +338,18 @@ int cam_jpeg_enc_start_hw(void *data, hw_info = core_info->jpeg_enc_hw_info; mem_base = soc_info->reg_map[0].mem_base; + spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + return -EINVAL; + } if (core_info->core_state != CAM_JPEG_ENC_CORE_READY) { CAM_ERR(CAM_JPEG, "Error not ready"); + spin_unlock(&jpeg_enc_dev->hw_lock); return -EINVAL; } + spin_unlock(&jpeg_enc_dev->hw_lock); cam_io_w_mb(hw_info->reg_val.hw_cmd_start, mem_base + hw_info->reg_offset.hw_cmd); @@ -352,6 +379,12 @@ int cam_jpeg_enc_stop_hw(void *data, mutex_lock(&core_info->core_mutex); spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + mutex_unlock(&core_info->core_mutex); + return -EINVAL; + } if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) { CAM_ERR(CAM_JPEG, "alrady stopping"); spin_unlock(&jpeg_enc_dev->hw_lock); diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c index a2a738d85714..94bc611a9120 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -927,6 +927,16 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, } break; case CAM_CONFIG_DEV: { + if (s_ctrl->sensor_state < CAM_SENSOR_ACQUIRE) { + rc = -EINVAL; + CAM_ERR(CAM_SENSOR, + "sensor_id:[0x%x] not acquired to configure [%d] ", + s_ctrl->sensordata->slave_info.sensor_id, + s_ctrl->sensor_state + ); + goto release_mutex; + } + rc = cam_sensor_i2c_pkt_parse(s_ctrl, arg); if (rc < 0) { CAM_ERR(CAM_SENSOR, "Failed i2c pkt parse: %d", rc); diff --git a/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c index 626473f8769a..77a7204cfe55 100644 --- a/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c +++ b/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c @@ -191,7 +191,7 @@ static struct cam_iommu_cb_set iommu_cb_set; static struct dentry *smmu_dentry; -static bool smmu_fatal_flag; +static bool smmu_fatal_flag = true; static enum dma_data_direction cam_smmu_translate_dir( enum cam_smmu_map_dir dir); diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c index d4487efbf090..93d39e3c360a 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c +++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c @@ -288,6 +288,7 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj) int rc; long idx = 0; bool bit; + int i = 0; if (!sync_obj || !merged_obj) { CAM_ERR(CAM_SYNC, "Invalid pointer(s)"); @@ -305,6 +306,14 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj) return -EINVAL; } + for (i = 0; i < num_objs; i++) { + rc = cam_sync_check_valid(sync_obj[i]); + if (rc) { + CAM_ERR(CAM_SYNC, "Sync_obj[%d] %d valid check fail", + i, sync_obj[i]); + return rc; + } + } do { idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS); if (idx >= CAM_SYNC_MAX_OBJS) @@ -376,6 +385,29 @@ int cam_sync_destroy(int32_t sync_obj) return cam_sync_deinit_object(sync_dev->sync_table, sync_obj); } +int cam_sync_check_valid(int32_t sync_obj) +{ + struct sync_table_row *row = NULL; + + if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0) + return -EINVAL; + + row = sync_dev->sync_table + sync_obj; + + if (!test_bit(sync_obj, sync_dev->bitmap)) { + CAM_ERR(CAM_SYNC, "Error: Released sync obj received %d", + sync_obj); + return -EINVAL; + } + + if (row->state == CAM_SYNC_STATE_INVALID) { + CAM_ERR(CAM_SYNC, + "Error: accessing an uninitialized sync obj = %d", + sync_obj); + return -EINVAL; + } + return 0; +} int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms) { unsigned long timeleft; diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h index c735d51fe462..f2f67cb3eb7b 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h +++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -147,5 +147,14 @@ int cam_sync_destroy(int32_t sync_obj); */ int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms); +/** + * @brief: Check if sync object is valid + * + * @param sync_obj: int referencing the sync object to be checked + * + * @return 0 upon success, -EINVAL if sync object is in bad state or arguments + * are invalid + */ +int cam_sync_check_valid(int32_t sync_obj); #endif /* __CAM_SYNC_API_H__ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c index 0f910c9e8273..3708c212d57b 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c @@ -353,3 +353,115 @@ int cam_packet_util_process_generic_cmd_buffer( return rc; } + +int32_t cam_packet_validate_plane_size( + struct cam_buf_io_cfg *io_cfg, + int plane_index, + size_t size) +{ + int rc = 0; + uint32_t kmd_plane_size = 0; + uint32_t plane_stride = 0; + uint32_t slice_height = 0; + uint32_t metadata_size = 0; + uint32_t format = io_cfg->format; + uint32_t plane_pixel_size = 0; + + if (plane_index < CAM_PACKET_MAX_PLANES) { + plane_stride = io_cfg->planes[plane_index].plane_stride; + slice_height = io_cfg->planes[plane_index].slice_height; + } + + if (!(plane_stride && slice_height)) { + CAM_ERR(CAM_ISP, + "Invalid values from UMD stride %d, slice height %d", + plane_stride, + slice_height); + return -EINVAL; + } + + switch (format) { + case CAM_FORMAT_MIPI_RAW_6: + case CAM_FORMAT_MIPI_RAW_8: + kmd_plane_size = ((plane_stride * slice_height) + 16 - 1) + / 16 * 16; + break; + case CAM_FORMAT_MIPI_RAW_10: + if (plane_stride % 4 == 0) + kmd_plane_size = ((plane_stride * slice_height) + + 16 - 1) / 16 * 16; + break; + case CAM_FORMAT_MIPI_RAW_12: + if (plane_stride % 2 == 0) + kmd_plane_size = ((plane_stride * slice_height) + + 16 - 1) / 16 * 16; + break; + case CAM_FORMAT_MIPI_RAW_14: + if (plane_stride % 4 == 0) + kmd_plane_size = plane_stride * slice_height * 7 / 4; + break; + case CAM_FORMAT_PLAIN16_8: + case CAM_FORMAT_PLAIN16_10: + case CAM_FORMAT_PLAIN16_12: + case CAM_FORMAT_PLAIN16_14: + case CAM_FORMAT_PLAIN16_16: + case CAM_FORMAT_PLAIN64: + kmd_plane_size = plane_stride * slice_height; + break; + case CAM_FORMAT_NV21: + case CAM_FORMAT_NV12: + if (plane_index < CAM_PACKET_MAX_PLANES) + kmd_plane_size = plane_stride * slice_height; + break; + case CAM_FORMAT_PD10: + if (plane_index < CAM_PACKET_MAX_PLANES) + kmd_plane_size = plane_stride * slice_height; + break; + case CAM_FORMAT_UBWC_NV12: + case CAM_FORMAT_UBWC_NV12_4R: + case CAM_FORMAT_UBWC_TP10: + metadata_size = io_cfg->planes[plane_index].meta_size; + plane_pixel_size = ((plane_stride * slice_height) + + (4096 - 1)) & ~((uint32_t) 4096 - 1); + kmd_plane_size = metadata_size + plane_pixel_size; + break; + case CAM_FORMAT_UBWC_P010: + case CAM_FORMAT_PLAIN32_20: + case CAM_FORMAT_TP10: + case CAM_FORMAT_YUV422: + case CAM_FORMAT_PD8: + case CAM_FORMAT_PLAIN128: + case CAM_FORMAT_ARGB: + case CAM_FORMAT_ARGB_10: + case CAM_FORMAT_ARGB_12: + case CAM_FORMAT_ARGB_14: + case CAM_FORMAT_MIPI_RAW_16: + case CAM_FORMAT_MIPI_RAW_20: + case CAM_FORMAT_QTI_RAW_8: + case CAM_FORMAT_QTI_RAW_10: + case CAM_FORMAT_QTI_RAW_12: + case CAM_FORMAT_QTI_RAW_14: + case CAM_FORMAT_PLAIN8: + case CAM_FORMAT_PLAIN8_SWAP: + case CAM_FORMAT_PLAIN8_10: + case CAM_FORMAT_PLAIN8_10_SWAP: + kmd_plane_size = plane_stride * slice_height; + break; + default: + kmd_plane_size = plane_stride * slice_height; + break; + } + if (!kmd_plane_size || + kmd_plane_size > (size - io_cfg->offsets[plane_index])) { + CAM_ERR(CAM_ISP, + "kmd size: %d umd size: %zu width: %d height: %d stride: %d sliceheight: %d ", + kmd_plane_size, + size, + io_cfg->planes[plane_index].width, + io_cfg->planes[plane_index].height, + plane_stride, + slice_height); + return -EINVAL; + } + return rc; +} diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h index 33c07ad89f4e..e49968e6a291 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h @@ -135,4 +135,20 @@ int cam_packet_util_process_generic_cmd_buffer( struct cam_cmd_buf_desc *cmd_buf, cam_packet_generic_blob_handler blob_handler_cb, void *user_data); +/** + * cam_packet_validate_plane_size() + * + * @brief: Utility function to calculate and validate size of buffer + * required for a format. + * @io_cfg: Contains IO config info + * @plane_index Plane index for which size is to be calculated + * + * @return: Size of buffer + * + */ +int32_t cam_packet_validate_plane_size( + struct cam_buf_io_cfg *io_cfg, + int plane_index, + size_t size); + #endif /* _CAM_PACKET_UTIL_H_ */ From 67a159f9e391f236e0f5f0d2058292f5dca64495 Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Tue, 2 Jul 2019 15:22:17 +0530 Subject: [PATCH 206/281] ARM: dts: msm: Enable ipa-auto config for sa415m target End point config of ipa for auto use case is different from stand alone. Enable auto config via PL specific DTSI file which will be picked from CDT programming. Change-Id: Ie7a4a90e4618773ace8b56ea1c12a13c23e26587 Signed-off-by: Mohammed Javid --- arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts | 2 ++ arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts | 5 +++++ arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts index c2a447b300bb..10ee58cc58a0 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts +++ b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts @@ -31,6 +31,8 @@ &ipa_hw { qcom,use-ipa-in-mhi-mode; + qcom,ipa-config-is-auto; + qcom,mhi-event-ring-id-limits = <9 13>; /* start and end */ }; &cnss_pcie { diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts index 1cf3a55a09b8..70e2849d482e 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts +++ b/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts @@ -20,3 +20,8 @@ "qcom,sdxpoorwills", "qcom,ccard"; qcom,board-id = <25 2>, <25 0x102>; }; + +&ipa_hw { + qcom,ipa-config-is-auto; +}; + diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts index 802e831930fa..ffbc8de76fb1 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts +++ b/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts @@ -29,3 +29,8 @@ &mss_mem { reg = <0x86400000 0x9300000>; }; + +&ipa_hw { + qcom,ipa-config-is-auto; +}; + From d636e0c7eba60523af4c607cbab8befe08b1ff81 Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Thu, 13 Jun 2019 16:16:59 +0530 Subject: [PATCH 207/281] msm: ipa: Add IOCTL support to get ep_pair info For QMI dpm port to open, control manager needs to know about usb/mhi ep details corresponding to RMNET and RMNET_CV2X tethering. Ipa driver is the one has all ep info at one place. So, provide IOCTL interface to get ep_pair info. Change-Id: Ia5ec0df955ef7794ca992129dab538f65af36211 Signed-off-by: Mohammed Javid --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 235 ++++++++++++++++++++++++++ include/uapi/linux/msm_ipa.h | 46 ++++- 2 files changed, 280 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 6de07dc79c59..153751903b91 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -624,6 +624,185 @@ static void ipa3_gsb_msg_free_cb(void *buff, u32 len, u32 type) kfree(buff); } +static void ipa3_get_usb_ep_info( + struct ipa_ioc_get_ep_info *ep_info, + struct ipa_ep_pair_info *pair_info + ) +{ + int ep_index = -1, i; + + ep_info->num_ep_pairs = 0; + for (i = 0; i < ep_info->max_ep_pairs; i++) { + pair_info[i].consumer_pipe_num = -1; + pair_info[i].producer_pipe_num = -1; + pair_info[i].ep_id = -1; + } + + ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD); + + if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) { + pair_info[ep_info->num_ep_pairs].consumer_pipe_num = ep_index; + ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB_CONS); + if ((ep_index != -1) && (ipa3_ctx->ep[ep_index].valid)) { + pair_info[ep_info->num_ep_pairs].producer_pipe_num = + ep_index; + pair_info[ep_info->num_ep_pairs].ep_id = + IPA_USB0_EP_ID; + + IPADBG("ep_pair_info consumer_pipe_num %d", + pair_info[ep_info->num_ep_pairs]. + consumer_pipe_num); + IPADBG(" producer_pipe_num %d ep_id %d\n", + pair_info[ep_info->num_ep_pairs]. + producer_pipe_num, + pair_info[ep_info->num_ep_pairs].ep_id); + ep_info->num_ep_pairs++; + } else { + pair_info[ep_info->num_ep_pairs].consumer_pipe_num = -1; + IPADBG("ep_pair_info consumer_pipe_num %d", + pair_info[ep_info->num_ep_pairs]. + consumer_pipe_num); + IPADBG(" producer_pipe_num %d ep_id %d\n", + pair_info[ep_info->num_ep_pairs]. + producer_pipe_num, + pair_info[ep_info->num_ep_pairs].ep_id); + } + } + + ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB2_PROD); + + if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) { + pair_info[ep_info->num_ep_pairs].consumer_pipe_num = ep_index; + ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB2_CONS); + if ((ep_index != -1) && (ipa3_ctx->ep[ep_index].valid)) { + pair_info[ep_info->num_ep_pairs].producer_pipe_num = + ep_index; + pair_info[ep_info->num_ep_pairs].ep_id = + IPA_USB1_EP_ID; + + IPADBG("ep_pair_info consumer_pipe_num %d", + pair_info[ep_info->num_ep_pairs]. + consumer_pipe_num); + IPADBG(" producer_pipe_num %d ep_id %d\n", + pair_info[ep_info->num_ep_pairs]. + producer_pipe_num, + pair_info[ep_info->num_ep_pairs].ep_id); + ep_info->num_ep_pairs++; + } else { + pair_info[ep_info->num_ep_pairs].consumer_pipe_num = -1; + IPADBG("ep_pair_info consumer_pipe_num %d", + pair_info[ep_info->num_ep_pairs]. + consumer_pipe_num); + IPADBG(" producer_pipe_num %d ep_id %d\n", + pair_info[ep_info->num_ep_pairs]. + producer_pipe_num, + pair_info[ep_info->num_ep_pairs].ep_id); + } + } +} + +static void ipa3_get_pcie_ep_info( + struct ipa_ioc_get_ep_info *ep_info, + struct ipa_ep_pair_info *pair_info + ) +{ + int ep_index = -1, i; + + ep_info->num_ep_pairs = 0; + for (i = 0; i < ep_info->max_ep_pairs; i++) { + pair_info[i].consumer_pipe_num = -1; + pair_info[i].producer_pipe_num = -1; + pair_info[i].ep_id = -1; + } + + ep_index = ipa3_get_ep_mapping(IPA_CLIENT_MHI_PROD); + + if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) { + pair_info[ep_info->num_ep_pairs].consumer_pipe_num = ep_index; + ep_index = ipa3_get_ep_mapping(IPA_CLIENT_MHI_CONS); + if ((ep_index != -1) && (ipa3_ctx->ep[ep_index].valid)) { + pair_info[ep_info->num_ep_pairs].producer_pipe_num = + ep_index; + pair_info[ep_info->num_ep_pairs].ep_id = + IPA_PCIE0_EP_ID; + + IPADBG("ep_pair_info consumer_pipe_num %d", + pair_info[ep_info->num_ep_pairs]. + consumer_pipe_num); + IPADBG(" producer_pipe_num %d ep_id %d\n", + pair_info[ep_info->num_ep_pairs]. + producer_pipe_num, + pair_info[ep_info->num_ep_pairs].ep_id); + ep_info->num_ep_pairs++; + } else { + pair_info[ep_info->num_ep_pairs].consumer_pipe_num = -1; + IPADBG("ep_pair_info consumer_pipe_num %d", + pair_info[ep_info->num_ep_pairs]. + consumer_pipe_num); + IPADBG(" producer_pipe_num %d ep_id %d\n", + pair_info[ep_info->num_ep_pairs]. + producer_pipe_num, + pair_info[ep_info->num_ep_pairs].ep_id); + } + } + + ep_index = ipa3_get_ep_mapping(IPA_CLIENT_MHI2_PROD); + + if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) { + pair_info[ep_info->num_ep_pairs].consumer_pipe_num = ep_index; + ep_index = ipa3_get_ep_mapping(IPA_CLIENT_MHI2_CONS); + if ((ep_index != -1) && (ipa3_ctx->ep[ep_index].valid)) { + pair_info[ep_info->num_ep_pairs].producer_pipe_num = + ep_index; + pair_info[ep_info->num_ep_pairs].ep_id = + IPA_PCIE1_EP_ID; + + IPADBG("ep_pair_info consumer_pipe_num %d", + pair_info[ep_info->num_ep_pairs]. + consumer_pipe_num); + IPADBG(" producer_pipe_num %d ep_id %d\n", + pair_info[ep_info->num_ep_pairs]. + producer_pipe_num, + pair_info[ep_info->num_ep_pairs].ep_id); + ep_info->num_ep_pairs++; + } else { + pair_info[ep_info->num_ep_pairs].consumer_pipe_num = -1; + IPADBG("ep_pair_info consumer_pipe_num %d", + pair_info[ep_info->num_ep_pairs]. + consumer_pipe_num); + IPADBG(" producer_pipe_num %d ep_id %d\n", + pair_info[ep_info->num_ep_pairs]. + producer_pipe_num, + pair_info[ep_info->num_ep_pairs].ep_id); + } + } +} + + +static int ipa3_get_ep_info(struct ipa_ioc_get_ep_info *ep_info, + u8 *param) +{ + int ret = 0; + struct ipa_ep_pair_info *pair_info = (struct ipa_ep_pair_info *)param; + + switch (ep_info->ep_type) { + case IPA_DATA_EP_TYP_HSUSB: + ipa3_get_usb_ep_info(ep_info, pair_info); + break; + + case IPA_DATA_EP_TYP_PCIE: + ipa3_get_pcie_ep_info(ep_info, pair_info); + break; + + default: + IPAERR_RL("Undefined ep_type %d\n", ep_info->ep_type); + ret = -EFAULT; + break; + } + + return ret; +} + static int ipa3_send_gsb_msg(unsigned long usr_param, uint8_t msg_type) { int retval; @@ -689,8 +868,10 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct ipa_ioc_rm_dependency rm_depend; struct ipa_ioc_nat_dma_cmd *table_dma_cmd; struct ipa_ioc_get_vlan_mode vlan_mode; + struct ipa_ioc_get_ep_info ep_info; size_t sz; int pre_entry; + unsigned long uptr = 0; IPADBG("cmd=%x nr=%d\n", cmd, _IOC_NR(cmd)); @@ -1878,6 +2059,60 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; + case IPA_IOC_GET_PHERIPHERAL_EP_INFO: + IPADBG("Got IPA_IOC_GET_EP_INFO\n"); + if (copy_from_user(&ep_info, (const void __user *)arg, + sizeof(struct ipa_ioc_get_ep_info))) { + IPAERR_RL("copy_from_user fails\n"); + retval = -EFAULT; + break; + } + + if (ep_info.max_ep_pairs != QUERY_MAX_EP_PAIRS) + IPAERR_RL("unexpected max_ep_pairs %d\n", + ep_info.max_ep_pairs); + + if (ep_info.ep_pair_size != + (QUERY_MAX_EP_PAIRS * sizeof(struct ipa_ep_pair_info))) + IPAERR_RL("unexpected ep_pair_size %d\n", + ep_info.max_ep_pairs); + + uptr = ep_info.info; + if (unlikely(!uptr)) { + IPAERR_RL("unexpected NULL info\n"); + retval = -EFAULT; + break; + } + + param = kzalloc(ep_info.ep_pair_size, GFP_KERNEL); + if (!param) { + IPAERR_RL("kzalloc fails\n"); + retval = -ENOMEM; + break; + } + + retval = ipa3_get_ep_info(&ep_info, param); + if (retval < 0) { + IPAERR("ipa3_get_ep_info failed\n"); + retval = -EFAULT; + break; + } + + if (copy_to_user((void __user *)uptr, param, + ep_info.ep_pair_size)) { + IPAERR_RL("copy_to_user fails\n"); + retval = -EFAULT; + break; + } + + if (copy_to_user((void __user *)arg, &ep_info, + sizeof(struct ipa_ioc_get_ep_info))) { + IPAERR_RL("copy_to_user fails\n"); + retval = -EFAULT; + break; + } + break; + default: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return -ENOTTY; diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h index e64942af11d4..3c810c2ceccf 100644 --- a/include/uapi/linux/msm_ipa.h +++ b/include/uapi/linux/msm_ipa.h @@ -107,7 +107,7 @@ #define IPA_IOCTL_DEL_BRIDGE_VLAN_MAPPING 60 #define IPA_IOCTL_GSB_CONNECT 61 #define IPA_IOCTL_GSB_DISCONNECT 62 - +#define IPA_IOCTL_GET_PHERIPHERAL_EP_INFO 63 /** @@ -1750,6 +1750,46 @@ struct ipa_ioc_gsb_info { char name[IPA_RESOURCE_NAME_MAX]; }; +#define QUERY_MAX_EP_PAIRS 2 + +#define IPA_USB0_EP_ID 11 +#define IPA_USB1_EP_ID 12 + +#define IPA_PCIE0_EP_ID 21 +#define IPA_PCIE1_EP_ID 22 + +enum ipa_peripheral_ep_type { + IPA_DATA_EP_TYP_RESERVED = 0, + IPA_DATA_EP_TYP_HSIC = 1, + IPA_DATA_EP_TYP_HSUSB = 2, + IPA_DATA_EP_TYP_PCIE = 3, + IPA_DATA_EP_TYP_EMBEDDED = 4, + IPA_DATA_EP_TYP_BAM_DMUX, +}; + +struct ipa_ep_pair_info { + uint32_t consumer_pipe_num; + uint32_t producer_pipe_num; + uint32_t ep_id; +}; + +/** + * struct ipa_ioc_get_ep_info - flt/rt counter id query + * @ep_type: type USB/PCIE - i/p param + * @max_ep_pairs: max number of ep_pairs (constant), + (QUERY_MAX_EP_PAIRS) + * @num_ep_pairs: number of ep_pairs - o/p param + * @ep_pair_size: sizeof(ipa_ep_pair_info) * max_ep_pairs + * @info: structure contains ep pair info + */ +struct ipa_ioc_get_ep_info { + enum ipa_peripheral_ep_type ep_type; + uint8_t max_ep_pairs; + uint8_t num_ep_pairs; + uint32_t ep_pair_size; + uintptr_t info; +}; + /** * struct ipa_msg_meta - Format of the message meta-data. * @msg_type: the type of the message @@ -2191,6 +2231,10 @@ struct ipa_ioc_bridge_vlan_mapping_info { IPA_IOCTL_GSB_DISCONNECT, \ struct ipa_ioc_gsb_info) +#define IPA_IOC_GET_PHERIPHERAL_EP_INFO _IOWR(IPA_IOC_MAGIC, \ + IPA_IOCTL_GET_PHERIPHERAL_EP_INFO, \ + struct ipa_ioc_get_ep_info) + /* * unique magic number of the Tethering bridge ioctls */ From 04acf0f5dec152550e67b7c8c05545cfe0bebfc4 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Fri, 26 Jul 2019 16:09:32 +0530 Subject: [PATCH 208/281] iio: qcom-rradc: Add batt_id delay property for RRADC Add DT property to set batt_id hardware settling delay time. Change-Id: I3ca6078d45efdfcec38027586fc5a740aa03f698 Signed-off-by: Jishnu Prakash --- .../bindings/iio/adc/qcom-rradc.txt | 4 +++ drivers/iio/adc/qcom-rradc.c | 34 +++++++++++++++---- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/qcom-rradc.txt b/Documentation/devicetree/bindings/iio/adc/qcom-rradc.txt index 1ab49edfe30c..240c6d82deb0 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom-rradc.txt +++ b/Documentation/devicetree/bindings/iio/adc/qcom-rradc.txt @@ -45,6 +45,10 @@ Optional property: - qcom,pmic-revid : Phandle pointing to the revision peripheral node. Use it to query the PMIC fabrication ID for applying the appropriate temperature compensation parameters. +- qcom,batt-id-delay-ms : + Value type: + Definition: Used to specify HW settling time in MS for measuring BATT_ID. + Possible values are: 0, 1, 4, 12, 20, 40, 60, 80. Example: /* RRADC node */ diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c index 6c86d7df5502..1bb10832bd2e 100644 --- a/drivers/iio/adc/qcom-rradc.c +++ b/drivers/iio/adc/qcom-rradc.c @@ -199,7 +199,8 @@ #define FG_RR_TP_REV_VERSION2 29 #define FG_RR_TP_REV_VERSION3 32 -#define BATT_ID_SETTLE_DELAY_80_MS 0xE0 +#define BATT_ID_SETTLE_SHIFT 5 +#define RRADC_BATT_ID_DELAY_MAX 8 /* * The channel number is not a physical index in hardware, @@ -231,6 +232,7 @@ struct rradc_chip { struct mutex lock; struct regmap *regmap; u16 base; + int batt_id_delay; struct iio_chan_spec *iio_chans; unsigned int nchannels; struct rradc_chan_prop *chan_props; @@ -258,6 +260,8 @@ struct rradc_chan_prop { u16 adc_code, int *result); }; +static const int batt_id_delays[] = {0, 1, 4, 12, 20, 40, 60, 80}; + static int rradc_masked_write(struct rradc_chip *rr_adc, u16 offset, u8 mask, u8 val) { @@ -855,7 +859,7 @@ static int rradc_enable_batt_id_channel(struct rradc_chip *chip, bool enable) static int rradc_do_batt_id_conversion(struct rradc_chip *chip, struct rradc_chan_prop *prop, u16 *data, u8 *buf) { - int rc = 0, ret = 0; + int rc = 0, ret = 0, batt_id_delay; rc = rradc_enable_batt_id_channel(chip, true); if (rc < 0) { @@ -863,11 +867,12 @@ static int rradc_do_batt_id_conversion(struct rradc_chip *chip, return rc; } - rc = rradc_masked_write(chip, FG_ADC_RR_BATT_ID_CFG, - BATT_ID_SETTLE_DELAY_80_MS, BATT_ID_SETTLE_DELAY_80_MS); - if (rc < 0) { - pr_err("BATT_ID settling time config failed:%d\n", rc); - ret = rc; + if (chip->batt_id_delay != -EINVAL) { + batt_id_delay = chip->batt_id_delay << BATT_ID_SETTLE_SHIFT; + rc = rradc_masked_write(chip, FG_ADC_RR_BATT_ID_CFG, + batt_id_delay, batt_id_delay); + if (rc < 0) + pr_err("BATT_ID settling time config failed:%d\n", rc); } rc = rradc_masked_write(chip, FG_ADC_RR_BATT_ID_TRIGGER, @@ -1138,6 +1143,21 @@ static int rradc_get_dt_data(struct rradc_chip *chip, struct device_node *node) return rc; } + chip->batt_id_delay = -EINVAL; + + rc = of_property_read_u32(node, "qcom,batt-id-delay-ms", + &chip->batt_id_delay); + if (!rc) { + for (i = 0; i < RRADC_BATT_ID_DELAY_MAX; i++) { + if (chip->batt_id_delay == batt_id_delays[i]) + break; + } + if (i == RRADC_BATT_ID_DELAY_MAX) + pr_err("Invalid batt_id_delay, rc=%d\n", rc); + else + chip->batt_id_delay = i; + } + chip->base = base; chip->revid_dev_node = of_parse_phandle(node, "qcom,pmic-revid", 0); if (chip->revid_dev_node) { From 859a9cecc0c0c4cd40be0b43a26bb4e6e2784cfa Mon Sep 17 00:00:00 2001 From: Sumalatha Malothu Date: Mon, 22 Jul 2019 13:47:49 +0530 Subject: [PATCH 209/281] msm:camera:isp: Fix array index bound checks Added check for max array index Change-Id: I4f8a4b559c83c04577cd58376526668d29b6b723 Signed-off-by: Sumalatha Malothu --- .../media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c index b5a6f44f20fa..c237ad23b753 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, 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 @@ -1215,7 +1215,7 @@ static void msm_isp_update_rdi_output_count( for (i = 0; i < stream_cfg_cmd->num_streams; i++) { if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) - > MAX_NUM_STREAM) + >= MAX_NUM_STREAM) return; stream_info = &axi_data->stream_info[ From fc3c517347cb0b2bd11089cade43f66f8ef5a90d Mon Sep 17 00:00:00 2001 From: Srinivasarao P Date: Fri, 19 Jul 2019 17:49:43 +0530 Subject: [PATCH 210/281] defconfig: msm: Enable CONFIG_DM_BOW for SDM845 Enable DM-BOW for Android userdata check point feature. Change-Id: I5c87e963b8080155243c6adc8eedca1740d54df3 Signed-off-by: Srinivasarao P --- arch/arm64/configs/sdm845-perf_defconfig | 1 + arch/arm64/configs/sdm845_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index 693a08590a04..af5b1cb46d2d 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -273,6 +273,7 @@ CONFIG_DM_REQ_CRYPT=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index 4dbeda2ac5fe..c2bd7bef6270 100755 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -281,6 +281,7 @@ CONFIG_DM_REQ_CRYPT=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y From ae6c1081dd2bf5f0720b4bfc0a2a2792ad5ec957 Mon Sep 17 00:00:00 2001 From: Naitik Bharadiya Date: Mon, 29 Jul 2019 12:19:47 +0530 Subject: [PATCH 211/281] defconfig: change BLK_DEV_LOOP_MIN_COUNT's value for SDM710 and SDM845 Change BLK_DEV_LOOP_MIN_COUNT's value from 8 to 16 for SDM710 and SDM845. Change-Id: I81ae95c13ebc6018bdb174cd66c86350cd1e2697 Signed-off-by: Naitik Bharadiya --- arch/arm64/configs/sdm670-perf_defconfig | 1 + arch/arm64/configs/sdm670_defconfig | 1 + arch/arm64/configs/sdm845-perf_defconfig | 1 + arch/arm64/configs/sdm845_defconfig | 1 + 4 files changed, 4 insertions(+) diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig index d75479ee755f..9056d8dece8a 100755 --- a/arch/arm64/configs/sdm670-perf_defconfig +++ b/arch/arm64/configs/sdm670-perf_defconfig @@ -249,6 +249,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig index 1eea89124a53..dd68a6c8f962 100755 --- a/arch/arm64/configs/sdm670_defconfig +++ b/arch/arm64/configs/sdm670_defconfig @@ -258,6 +258,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index 1ec275b3b8e3..d22561000889 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -250,6 +250,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index 1a39bca0bd78..4760809a1094 100644 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -256,6 +256,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y From 22b54441ad31845701ad25ddf330eb5f746dab50 Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Mon, 1 Jul 2019 03:43:21 +0530 Subject: [PATCH 212/281] ipa: Add support in ipa-usb driver for rmnet_cv2x Only one RmNET instance is supported till now, so there was a check to not to support additonal protocol in ipa usb driver. With respect to auto use case requirement we need to support two rmnet instance, newly added rmnet_cv2x along with legacy rmnet. Modify code to support additional rmnet_cv2x teth interface with respect to protocol, pm states. Change-Id: I83984de859919a395f1115c8e2a37004d01f0688 Signed-off-by: Mohammed Javid --- .../platform/msm/ipa/ipa_clients/ipa_usb.c | 277 ++++++++++++++++-- drivers/platform/msm/ipa/ipa_v3/ipa.c | 3 + drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 2 + drivers/platform/msm/ipa/ipa_v3/teth_bridge.c | 61 +++- include/linux/ipa.h | 3 +- include/linux/ipa_usb.h | 10 +- 6 files changed, 310 insertions(+), 46 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c index 704308f0878b..eccdeab45aa7 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019 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 @@ -144,13 +144,15 @@ enum ipa3_usb_state { enum ipa3_usb_transport_type { IPA_USB_TRANSPORT_TETH, IPA_USB_TRANSPORT_DPL, + IPA_USB_TRANSPORT_TETH_2, IPA_USB_TRANSPORT_MAX }; /* Get transport type from tethering protocol */ #define IPA3_USB_GET_TTYPE(__teth_prot) \ (((__teth_prot) == IPA_USB_DIAG) ? \ - IPA_USB_TRANSPORT_DPL : IPA_USB_TRANSPORT_TETH) + IPA_USB_TRANSPORT_DPL : (((__teth_prot) == IPA_USB_RMNET_CV2X) ? \ + IPA_USB_TRANSPORT_TETH_2 : IPA_USB_TRANSPORT_TETH)) /* Does the given transport type is DPL? */ #define IPA3_USB_IS_TTYPE_DPL(__ttype) \ @@ -186,7 +188,7 @@ struct ipa3_usb_context { struct ipa3_usb_teth_prot_context teth_prot_ctx[IPA_USB_MAX_TETH_PROT_SIZE]; int num_init_prot; /* without dpl */ - struct teth_bridge_init_params teth_bridge_params; + struct teth_bridge_init_params teth_bridge_params[IPA_TETH_BRIDGE_MAX]; struct completion dev_ready_comp; u32 qmi_req_id; spinlock_t state_lock; @@ -198,6 +200,7 @@ struct ipa3_usb_context { struct dentry *dfile_state_info; struct dentry *dent; struct ipa3_usb_smmu_reg_map smmu_reg_map; + struct ipa3_usb_smmu_reg_map smmu_reg_map_dummy; }; enum ipa3_usb_op { @@ -704,6 +707,8 @@ static char *ipa3_usb_teth_prot_to_string(enum ipa_usb_teth_prot teth_prot) case IPA_USB_RMNET: case IPA_USB_MBIM: return "teth_bridge"; + case IPA_USB_RMNET_CV2X: + return "teth_bridge_cv2x"; case IPA_USB_DIAG: return "dpl"; default: @@ -719,6 +724,8 @@ static char *ipa3_usb_teth_bridge_prot_to_string( switch (teth_prot) { case IPA_USB_RMNET: return "rmnet"; + case IPA_USB_RMNET_CV2X: + return "rmnet_cv2x"; case IPA_USB_MBIM: return "mbim"; default: @@ -728,11 +735,18 @@ static char *ipa3_usb_teth_bridge_prot_to_string( return "unsupported"; } -static int ipa3_usb_init_teth_bridge(void) +static int ipa3_usb_init_teth_bridge(enum ipa_usb_teth_prot teth_prot) { int result; - result = teth_bridge_init(&ipa3_usb_ctx->teth_bridge_params); + if (teth_prot == IPA_USB_RMNET_CV2X) + result = + teth_bridge_init( + &ipa3_usb_ctx->teth_bridge_params[IPA_TETH_BRIDGE_2]); + else + result = + teth_bridge_init( + &ipa3_usb_ctx->teth_bridge_params[IPA_TETH_BRIDGE_1]); if (result) { IPA_USB_ERR("Failed to initialize teth_bridge.\n"); return result; @@ -746,15 +760,26 @@ static int ipa3_usb_register_pm(enum ipa3_usb_transport_type ttype) struct ipa3_usb_transport_type_ctx *ttype_ctx = &ipa3_usb_ctx->ttype_ctx[ttype]; int result; + enum ipa_client_type consumer; + + /* + * One PM resource for teth1, + * One PM resource for teth2 (CV2X), + * One for DPL, + */ - /* there is one PM resource for teth and one for DPL */ - if (!IPA3_USB_IS_TTYPE_DPL(ttype) && ipa3_usb_ctx->num_init_prot > 0) + if (!IPA3_USB_IS_TTYPE_DPL(ttype) && (ipa3_usb_ctx->num_init_prot > 0) + && (ttype != IPA_USB_TRANSPORT_TETH_2)) return 0; memset(&ttype_ctx->pm_ctx.reg_params, 0, sizeof(ttype_ctx->pm_ctx.reg_params)); - ttype_ctx->pm_ctx.reg_params.name = (ttype == IPA_USB_TRANSPORT_DPL) ? - "USB DPL" : "USB"; + ttype_ctx->pm_ctx.reg_params.name = + (ttype == IPA_USB_TRANSPORT_DPL) ? + "USB DPL" : + (ttype == IPA_USB_TRANSPORT_TETH_2) ? + "USB2" : "USB"; + ttype_ctx->pm_ctx.reg_params.callback = ipa3_usb_pm_cb; ttype_ctx->pm_ctx.reg_params.user_data = ttype_ctx; ttype_ctx->pm_ctx.reg_params.group = IPA_PM_GROUP_DEFAULT; @@ -766,9 +791,12 @@ static int ipa3_usb_register_pm(enum ipa3_usb_transport_type ttype) goto fail_pm_reg; } + consumer = (ttype == IPA_USB_TRANSPORT_DPL) ? + IPA_CLIENT_USB_DPL_CONS : + (ttype == IPA_USB_TRANSPORT_TETH_2) ? + IPA_CLIENT_USB2_CONS : IPA_CLIENT_USB_CONS; result = ipa_pm_associate_ipa_cons_to_client(ttype_ctx->pm_ctx.hdl, - (ttype == IPA_USB_TRANSPORT_DPL) ? - IPA_CLIENT_USB_DPL_CONS : IPA_CLIENT_USB_CONS); + consumer); if (result) { IPA_USB_ERR("fail to associate cons with PM %d\n", result); goto fail_pm_cons; @@ -994,9 +1022,11 @@ int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, goto bad_params; } ipa3_usb_ctx->teth_prot_ctx[teth_prot].user_data = user_data; - result = ipa3_usb_init_teth_bridge(); + + result = ipa3_usb_init_teth_bridge(teth_prot); if (result) goto teth_prot_init_fail; + ipa3_usb_ctx->teth_prot_ctx[teth_prot].state = IPA_USB_TETH_PROT_INITIALIZED; ipa3_usb_ctx->num_init_prot++; @@ -1004,6 +1034,26 @@ int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, ipa3_usb_teth_prot_to_string(teth_prot), ipa3_usb_teth_bridge_prot_to_string(teth_prot)); break; + case IPA_USB_RMNET_CV2X: + if (ipa3_usb_ctx->teth_prot_ctx[teth_prot].state != + IPA_USB_TETH_PROT_INVALID) { + IPA_USB_DBG("%s already initialized\n", + ipa3_usb_teth_prot_to_string(teth_prot)); + result = -EPERM; + goto bad_params; + } + ipa3_usb_ctx->teth_prot_ctx[teth_prot].user_data = user_data; + + result = ipa3_usb_init_teth_bridge(teth_prot); + if (result) + goto teth_prot_init_fail; + + ipa3_usb_ctx->teth_prot_ctx[teth_prot].state = + IPA_USB_TETH_PROT_INITIALIZED; + IPA_USB_DBG("initialized %s %s\n", + ipa3_usb_teth_prot_to_string(teth_prot), + ipa3_usb_teth_bridge_prot_to_string(teth_prot)); + break; case IPA_USB_DIAG: if (ipa3_usb_ctx->teth_prot_ctx[teth_prot].state != IPA_USB_TETH_PROT_INVALID) { @@ -1031,7 +1081,8 @@ int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, teth_prot_init_fail: if ((IPA3_USB_IS_TTYPE_DPL(ttype)) - || (ipa3_usb_ctx->num_init_prot == 0)) { + || (ipa3_usb_ctx->num_init_prot == 0) + || (teth_prot == IPA_USB_RMNET_CV2X)) { if (ipa_pm_is_used()) { ipa3_usb_deregister_pm(ttype); } else { @@ -1114,6 +1165,7 @@ static bool ipa3_usb_check_chan_params(struct ipa_usb_xdci_chan_params *params) } break; case IPA_USB_RMNET: + case IPA_USB_RMNET_CV2X: case IPA_USB_MBIM: if (ipa3_usb_ctx->teth_prot_ctx[params->teth_prot].state == IPA_USB_TETH_PROT_INVALID) { @@ -1131,6 +1183,102 @@ static bool ipa3_usb_check_chan_params(struct ipa_usb_xdci_chan_params *params) return true; } +/* + * ipa3_usb_smmu_map_dummy: Does the same job of ipa3_usb_smmu_map_xdci_channel. + * API to map geventcount dummy addr, which will be provided + * to GSI from USB to handle sw path. Where USB driver will take + * care of replenishing desc to ipa hw. This dummy gevntcount addr + * cannot be in same page as other, since other are actual usb hw addr. + * We map this dummy addr to AP smmu context, so that there will + * not be any NOC issue when IPA/GSI tries to access it. + */ +static int ipa3_usb_smmu_map_dummy( + struct ipa_usb_xdci_chan_params *params, + bool map + ) +{ + int result = 0; + u32 gevntcount_r = rounddown(params->gevntcount_low_addr, PAGE_SIZE); + u32 xfer_scratch_r = + rounddown(params->xfer_scratch.depcmd_low_addr, PAGE_SIZE); + + if ((ipa3_usb_ctx->smmu_reg_map.addr != xfer_scratch_r) && + (ipa3_usb_ctx->smmu_reg_map.cnt != 0)) { + IPA_USB_ERR("No support more than 1 page map for USB regs"); + WARN_ON(1); + return -EINVAL; + } + + if (map) { + if (ipa3_usb_ctx->smmu_reg_map_dummy.cnt == 0) { + ipa3_usb_ctx->smmu_reg_map_dummy.addr = gevntcount_r; + result = ipa3_smmu_map_peer_reg( + ipa3_usb_ctx->smmu_reg_map_dummy.addr, true, + IPA_SMMU_CB_AP); + if (result) { + IPA_USB_ERR("failed to map USB regs %d\n", + result); + return result; + } + + if (ipa3_usb_ctx->smmu_reg_map.cnt == 0) { + ipa3_usb_ctx->smmu_reg_map.addr = + xfer_scratch_r; + result = ipa3_smmu_map_peer_reg( + ipa3_usb_ctx->smmu_reg_map.addr, true, + IPA_SMMU_CB_AP); + if (result) { + IPA_USB_ERR( + "failed to map USB regs %d\n", + result); + return result; + } + } + ipa3_usb_ctx->smmu_reg_map.cnt++; + ipa3_usb_ctx->smmu_reg_map_dummy.cnt++; + } + } else { + if (gevntcount_r != ipa3_usb_ctx->smmu_reg_map_dummy.addr) { + IPA_USB_ERR( + "No support for unmap different reg\n"); + return -EINVAL; + } + + if (ipa3_usb_ctx->smmu_reg_map_dummy.cnt == 1) { + result = ipa3_smmu_map_peer_reg( + ipa3_usb_ctx->smmu_reg_map_dummy.addr, false, + IPA_SMMU_CB_AP); + if (result) { + IPA_USB_ERR("failed to unmap USB regs %d\n", + result); + return result; + } + + if (ipa3_usb_ctx->smmu_reg_map.cnt == 1) { + if (xfer_scratch_r != + ipa3_usb_ctx->smmu_reg_map.addr) { + IPA_USB_ERR( + "No support for un map different reg\n"); + return -EINVAL; + } + + result = ipa3_smmu_map_peer_reg( + ipa3_usb_ctx->smmu_reg_map.addr, false, + IPA_SMMU_CB_AP); + if (result) { + IPA_USB_ERR( + "failed to unmap USB regs %d\n", + result); + return result; + } + } + ipa3_usb_ctx->smmu_reg_map.cnt--; + ipa3_usb_ctx->smmu_reg_map_dummy.cnt--; + } + } + return result; +} + static int ipa3_usb_smmu_map_xdci_channel( struct ipa_usb_xdci_chan_params *params, bool map) { @@ -1139,13 +1287,22 @@ static int ipa3_usb_smmu_map_xdci_channel( u32 xfer_scratch_r = rounddown(params->xfer_scratch.depcmd_low_addr, PAGE_SIZE); - if (gevntcount_r != xfer_scratch_r) { + if ((gevntcount_r != xfer_scratch_r) && + (params->is_sw_path == false)) { IPA_USB_ERR("No support more than 1 page map for USB regs\n"); WARN_ON(1); return -EINVAL; } - if (map) { + if (params->is_sw_path == true) { + result = ipa3_usb_smmu_map_dummy(params, map); + if (result) { + IPA_USB_ERR("failed to %s USB regs %d\n", + (map == true)?"map":"unmap", + result); + return result; + } + } else if (map) { if (ipa3_usb_ctx->smmu_reg_map.cnt == 0) { ipa3_usb_ctx->smmu_reg_map.addr = gevntcount_r; result = ipa3_smmu_map_peer_reg( @@ -1184,7 +1341,6 @@ static int ipa3_usb_smmu_map_xdci_channel( ipa3_usb_ctx->smmu_reg_map.cnt--; } - result = ipa3_smmu_map_peer_buff(params->xfer_ring_base_addr_iova, params->xfer_ring_len, map, params->sgt_xfer_rings, IPA_SMMU_CB_AP); @@ -1266,11 +1422,25 @@ static int ipa3_usb_request_xdci_channel( case IPA_USB_RMNET: case IPA_USB_MBIM: chan_params.priv = - ipa3_usb_ctx->teth_bridge_params.private_data; + ipa3_usb_ctx->teth_bridge_params[IPA_TETH_BRIDGE_1]. + private_data; chan_params.notify = - ipa3_usb_ctx->teth_bridge_params.usb_notify_cb; + ipa3_usb_ctx->teth_bridge_params[IPA_TETH_BRIDGE_1]. + usb_notify_cb; chan_params.skip_ep_cfg = - ipa3_usb_ctx->teth_bridge_params.skip_ep_cfg; + ipa3_usb_ctx->teth_bridge_params[IPA_TETH_BRIDGE_1]. + skip_ep_cfg; + break; + case IPA_USB_RMNET_CV2X: + chan_params.priv = + ipa3_usb_ctx->teth_bridge_params[IPA_TETH_BRIDGE_2]. + private_data; + chan_params.notify = + ipa3_usb_ctx->teth_bridge_params[IPA_TETH_BRIDGE_2]. + usb_notify_cb; + chan_params.skip_ep_cfg = + ipa3_usb_ctx->teth_bridge_params[IPA_TETH_BRIDGE_2]. + skip_ep_cfg; break; case IPA_USB_DIAG: chan_params.priv = NULL; @@ -1571,6 +1741,16 @@ static int ipa3_usb_connect_dpl(void) return 0; } +static int ipa3_get_tethering_mode(enum ipa_usb_teth_prot teth_prot) +{ + if (teth_prot == IPA_USB_RMNET) + return TETH_TETHERING_MODE_RMNET; + else if (teth_prot == IPA_USB_RMNET_CV2X) + return TETH_TETHERING_MODE_RMNET_2; + else + return TETH_TETHERING_MODE_MBIM; +} + static int ipa3_usb_connect_teth_prot(enum ipa_usb_teth_prot teth_prot) { int result; @@ -1639,6 +1819,7 @@ static int ipa3_usb_connect_teth_prot(enum ipa_usb_teth_prot teth_prot) ipa3_usb_teth_prot_to_string(teth_prot)); break; case IPA_USB_RMNET: + case IPA_USB_RMNET_CV2X: case IPA_USB_MBIM: if (ipa3_usb_ctx->teth_prot_ctx[teth_prot].state == IPA_USB_TETH_PROT_CONNECTED) { @@ -1646,7 +1827,8 @@ static int ipa3_usb_connect_teth_prot(enum ipa_usb_teth_prot teth_prot) ipa3_usb_teth_prot_to_string(teth_prot)); break; } - result = ipa3_usb_init_teth_bridge(); + + result = ipa3_usb_init_teth_bridge(teth_prot); if (result) return result; @@ -1658,14 +1840,19 @@ static int ipa3_usb_connect_teth_prot(enum ipa_usb_teth_prot teth_prot) teth_bridge_params.usb_ipa_pipe_hdl = teth_conn_params->usb_to_ipa_clnt_hdl; teth_bridge_params.tethering_mode = - (teth_prot == IPA_USB_RMNET) ? - (TETH_TETHERING_MODE_RMNET):(TETH_TETHERING_MODE_MBIM); - teth_bridge_params.client_type = IPA_CLIENT_USB_PROD; + ipa3_get_tethering_mode(teth_prot); + + if (teth_prot == IPA_USB_RMNET_CV2X) + teth_bridge_params.client_type = IPA_CLIENT_USB2_PROD; + else + teth_bridge_params.client_type = IPA_CLIENT_USB_PROD; + result = ipa3_usb_connect_teth_bridge(&teth_bridge_params); if (result) { ipa3_usb_ctx->ttype_ctx[ttype].user_data = NULL; return result; } + ipa3_usb_ctx->teth_prot_ctx[teth_prot].state = IPA_USB_TETH_PROT_CONNECTED; ipa3_usb_notify_do(ttype, IPA_USB_DEVICE_READY); @@ -1704,11 +1891,15 @@ static int ipa3_usb_connect_teth_prot(enum ipa_usb_teth_prot teth_prot) return 0; } -static int ipa3_usb_disconnect_teth_bridge(void) +static int ipa3_usb_disconnect_teth_bridge(enum ipa_usb_teth_prot teth_prot) { int result; - result = teth_bridge_disconnect(IPA_CLIENT_USB_PROD); + if (teth_prot == IPA_USB_RMNET_CV2X) + result = teth_bridge_disconnect(IPA_CLIENT_USB2_PROD); + else + result = teth_bridge_disconnect(IPA_CLIENT_USB_PROD); + if (result) { IPA_USB_ERR("failed to disconnect teth_bridge.\n"); return result; @@ -1774,6 +1965,7 @@ static int ipa3_usb_disconnect_teth_prot(enum ipa_usb_teth_prot teth_prot) ipa3_usb_teth_prot_to_string(teth_prot)); break; case IPA_USB_RMNET: + case IPA_USB_RMNET_CV2X: case IPA_USB_MBIM: if (ipa3_usb_ctx->teth_prot_ctx[teth_prot].state != IPA_USB_TETH_PROT_CONNECTED) { @@ -1782,7 +1974,8 @@ static int ipa3_usb_disconnect_teth_prot(enum ipa_usb_teth_prot teth_prot) ipa3_usb_teth_bridge_prot_to_string(teth_prot)); return -EPERM; } - result = ipa3_usb_disconnect_teth_bridge(); + + result = ipa3_usb_disconnect_teth_bridge(teth_prot); if (result) break; @@ -1828,8 +2021,7 @@ static int ipa3_usb_xdci_connect_internal( return -EINVAL; } - ttype = (params->teth_prot == IPA_USB_DIAG) ? IPA_USB_TRANSPORT_DPL : - IPA_USB_TRANSPORT_TETH; + ttype = IPA3_USB_GET_TTYPE(params->teth_prot); if (!ipa3_usb_check_legal_op(IPA_USB_OP_CONNECT, ttype)) { IPA_USB_ERR("Illegal operation.\n"); @@ -2013,7 +2205,9 @@ static int ipa3_usb_get_status_dbg_info(struct ipa3_usb_status_dbg_info *status) for (i = 0 ; i < IPA_USB_MAX_TETH_PROT_SIZE ; i++) { if (ipa3_usb_ctx->teth_prot_ctx[i].state == IPA_USB_TETH_PROT_INITIALIZED) { - if ((i == IPA_USB_RMNET) || (i == IPA_USB_MBIM)) + if ((i == IPA_USB_RMNET) || + (i == IPA_USB_MBIM) || + (i == IPA_USB_RMNET_CV2X)) status->inited_prots[status->num_init_prot++] = ipa3_usb_teth_bridge_prot_to_string(i); else @@ -2023,6 +2217,7 @@ static int ipa3_usb_get_status_dbg_info(struct ipa3_usb_status_dbg_info *status) IPA_USB_TETH_PROT_CONNECTED) { switch (i) { case IPA_USB_RMNET: + case IPA_USB_RMNET_CV2X: case IPA_USB_MBIM: status->teth_connected_prot = ipa3_usb_teth_bridge_prot_to_string(i); @@ -2527,6 +2722,24 @@ int ipa_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot) ipa3_usb_teth_prot_to_string(teth_prot), ipa3_usb_teth_bridge_prot_to_string(teth_prot)); break; + case IPA_USB_RMNET_CV2X: + if (ipa3_usb_ctx->teth_prot_ctx[teth_prot].state != + IPA_USB_TETH_PROT_INITIALIZED) { + IPA_USB_ERR("%s (%s) is not initialized\n", + ipa3_usb_teth_prot_to_string(teth_prot), + ipa3_usb_teth_bridge_prot_to_string(teth_prot)); + result = -EINVAL; + goto bad_params; + } + + ipa3_usb_ctx->teth_prot_ctx[teth_prot].user_data = + NULL; + ipa3_usb_ctx->teth_prot_ctx[teth_prot].state = + IPA_USB_TETH_PROT_INVALID; + IPA_USB_DBG("deinitialized %s (%s)\n", + ipa3_usb_teth_prot_to_string(teth_prot), + ipa3_usb_teth_bridge_prot_to_string(teth_prot)); + break; case IPA_USB_DIAG: if (ipa3_usb_ctx->teth_prot_ctx[teth_prot].state != IPA_USB_TETH_PROT_INITIALIZED) { @@ -2549,7 +2762,8 @@ int ipa_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot) } if (IPA3_USB_IS_TTYPE_DPL(ttype) || - (ipa3_usb_ctx->num_init_prot == 0)) { + (ipa3_usb_ctx->num_init_prot == 0) || + (teth_prot == IPA_USB_RMNET_CV2X)) { if (!ipa3_usb_set_state(IPA_USB_INVALID, false, ttype)) IPA_USB_ERR( "failed to change state to invalid\n"); @@ -2976,6 +3190,9 @@ static int __init ipa3_usb_init(void) pm_ctx = &ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_TETH].pm_ctx; pm_ctx->hdl = ~0; pm_ctx->remote_wakeup_work = &ipa3_usb_notify_remote_wakeup_work; + pm_ctx = &ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_TETH_2].pm_ctx; + pm_ctx->hdl = ~0; + pm_ctx->remote_wakeup_work = &ipa3_usb_notify_remote_wakeup_work; pm_ctx = &ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_DPL].pm_ctx; pm_ctx->hdl = ~0; pm_ctx->remote_wakeup_work = &ipa3_usb_dpl_notify_remote_wakeup_work; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 6de07dc79c59..1c3efed38e7f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -2636,6 +2636,9 @@ void ipa3_q6_pre_shutdown_cleanup(void) ipa3_q6_pipe_delay(false); ipa3_set_reset_client_prod_pipe_delay(true, IPA_CLIENT_USB_PROD); + if (ipa3_ctx->ipa_config_is_auto) + ipa3_set_reset_client_prod_pipe_delay(true, + IPA_CLIENT_USB2_PROD); if (ipa3_ctx->ipa_config_is_mhi) ipa3_set_reset_client_prod_pipe_delay(true, IPA_CLIENT_MHI_PROD); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 03b0c726d2f6..090cfa08057f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -2076,6 +2076,7 @@ bool ipa3_should_pipe_be_suspended(enum ipa_client_type client) return false; if (client == IPA_CLIENT_USB_CONS || + client == IPA_CLIENT_USB2_CONS || client == IPA_CLIENT_USB_DPL_CONS || client == IPA_CLIENT_MHI_CONS || client == IPA_CLIENT_HSIC1_CONS || @@ -3856,6 +3857,7 @@ int ipa3_write_qmap_id(struct ipa_ioc_write_qmapid *param_in) meta.qmap_id = param_in->qmap_id; if (param_in->client == IPA_CLIENT_USB_PROD || + param_in->client == IPA_CLIENT_USB2_PROD || param_in->client == IPA_CLIENT_HSIC1_PROD || param_in->client == IPA_CLIENT_ODU_PROD || param_in->client == IPA_CLIENT_ETHERNET_PROD) { diff --git a/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c b/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c index 0f5c61eba55d..566e7bfacc31 100644 --- a/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c +++ b/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2017,2019, 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 @@ -38,6 +38,12 @@ #define TETH_ERR(fmt, args...) \ pr_err(TETH_BRIDGE_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) +enum ipa_num_teth_iface { + IPA_TETH_IFACE_1 = 0, + IPA_TETH_IFACE_2 = 1, + IPA_TETH_IFACE_MAX +}; + /** * struct ipa3_teth_bridge_ctx - Tethering bridge driver context information * @class: kernel class pointer @@ -50,7 +56,7 @@ struct ipa3_teth_bridge_ctx { dev_t dev_num; struct device *dev; struct cdev cdev; - u32 modem_pm_hdl; + u32 modem_pm_hdl[IPA_TETH_IFACE_MAX]; }; static struct ipa3_teth_bridge_ctx *ipa3_teth_ctx; @@ -120,21 +126,32 @@ int ipa3_teth_bridge_init(struct teth_bridge_init_params *params) int ipa3_teth_bridge_disconnect(enum ipa_client_type client) { int res = 0; + int *pm_hdl = NULL; TETH_DBG_FUNC_ENTRY(); if (ipa_pm_is_used()) { - res = ipa_pm_deactivate_sync(ipa3_teth_ctx->modem_pm_hdl); + + if (client == IPA_CLIENT_USB2_PROD) + pm_hdl = &ipa3_teth_ctx->modem_pm_hdl[IPA_TETH_IFACE_2]; + else + pm_hdl = &ipa3_teth_ctx->modem_pm_hdl[IPA_TETH_IFACE_1]; + + res = ipa_pm_deactivate_sync(*pm_hdl); if (res) { TETH_ERR("fail to deactivate modem %d\n", res); return res; } - res = ipa_pm_deregister(ipa3_teth_ctx->modem_pm_hdl); - ipa3_teth_ctx->modem_pm_hdl = ~0; + res = ipa_pm_deregister(*pm_hdl); + *pm_hdl = ~0; } else { - ipa_rm_delete_dependency(IPA_RM_RESOURCE_USB_PROD, - IPA_RM_RESOURCE_Q6_CONS); - ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD, - IPA_RM_RESOURCE_USB_CONS); + if (client == IPA_CLIENT_USB2_PROD) { + TETH_ERR("No support for rm added/validated.\n"); + } else { + ipa_rm_delete_dependency(IPA_RM_RESOURCE_USB_PROD, + IPA_RM_RESOURCE_Q6_CONS); + ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD, + IPA_RM_RESOURCE_USB_CONS); + } } TETH_DBG_FUNC_EXIT(); @@ -154,23 +171,37 @@ int ipa3_teth_bridge_connect(struct teth_bridge_connect_params *connect_params) { int res = 0; struct ipa_pm_register_params reg_params; + u32 *pm = NULL; memset(®_params, 0, sizeof(reg_params)); TETH_DBG_FUNC_ENTRY(); if (ipa_pm_is_used()) { - reg_params.name = "MODEM (USB RMNET)"; + if (connect_params->tethering_mode == + TETH_TETHERING_MODE_RMNET_2) { + reg_params.name = "MODEM (USB RMNET_CV2X)"; + pm = &ipa3_teth_ctx->modem_pm_hdl[IPA_TETH_IFACE_2]; + } else { + reg_params.name = "MODEM (USB RMNET)"; + pm = &ipa3_teth_ctx->modem_pm_hdl[IPA_TETH_IFACE_1]; + } reg_params.group = IPA_PM_GROUP_MODEM; reg_params.skip_clk_vote = true; res = ipa_pm_register(®_params, - &ipa3_teth_ctx->modem_pm_hdl); + pm); if (res) { TETH_ERR("fail to register with PM %d\n", res); return res; } - res = ipa_pm_activate_sync(ipa3_teth_ctx->modem_pm_hdl); + res = ipa_pm_activate_sync(*pm); + goto bail; + } + + if (connect_params->tethering_mode == TETH_TETHERING_MODE_RMNET_2) { + res = -EINVAL; + TETH_ERR("No support for rm added/validated.\n"); goto bail; } @@ -225,7 +256,7 @@ static const struct file_operations ipa3_teth_bridge_drv_fops = { */ int ipa3_teth_bridge_driver_init(void) { - int res; + int res, i; TETH_DBG("Tethering bridge driver init\n"); ipa3_teth_ctx = kzalloc(sizeof(*ipa3_teth_ctx), GFP_KERNEL); @@ -266,7 +297,9 @@ int ipa3_teth_bridge_driver_init(void) goto fail_cdev_add; } - ipa3_teth_ctx->modem_pm_hdl = ~0; + for (i = 0; i < IPA_TETH_IFACE_MAX; i++) + ipa3_teth_ctx->modem_pm_hdl[i] = ~0; + TETH_DBG("Tethering bridge driver init OK\n"); return 0; diff --git a/include/linux/ipa.h b/include/linux/ipa.h index 2c316662670e..b0828a0ddeac 100644 --- a/include/linux/ipa.h +++ b/include/linux/ipa.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 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 @@ -754,6 +754,7 @@ struct ipa_rm_perf_profile { enum teth_tethering_mode { TETH_TETHERING_MODE_RMNET, TETH_TETHERING_MODE_MBIM, + TETH_TETHERING_MODE_RMNET_2, TETH_TETHERING_MODE_MAX, }; diff --git a/include/linux/ipa_usb.h b/include/linux/ipa_usb.h index cceae83ae920..9dbdb9ff32c4 100644 --- a/include/linux/ipa_usb.h +++ b/include/linux/ipa_usb.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 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 @@ -19,9 +19,16 @@ enum ipa_usb_teth_prot { IPA_USB_RMNET = 2, IPA_USB_MBIM = 3, IPA_USB_DIAG = 4, + IPA_USB_RMNET_CV2X = 5, IPA_USB_MAX_TETH_PROT_SIZE }; +enum teth_bridge_params { + IPA_TETH_BRIDGE_1 = 0, + IPA_TETH_BRIDGE_2 = 1, + IPA_TETH_BRIDGE_MAX +}; + /** * ipa_usb_teth_params - parameters for RDNIS/ECM initialization API * @@ -151,6 +158,7 @@ struct ipa_usb_xdci_chan_params { u64 data_buff_base_addr_iova; struct sg_table *sgt_xfer_rings; struct sg_table *sgt_data_buff; + bool is_sw_path; }; /** From d122aedd2e22ad0bd4d5ab1e88e1c2e480594768 Mon Sep 17 00:00:00 2001 From: Xipeng Gu Date: Tue, 6 Aug 2019 16:12:27 +0800 Subject: [PATCH 213/281] ARM: dts: msm: Configure power of panel on Spyro WDP Configure PMI gpio 12 as platform-enable-gpio, delete useless node of panel supply. Change-Id: I2aba036f58911762f4f1522eb72f095f4db88610 Signed-off-by: Xipeng Gu --- .../boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts | 7 +++++-- arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 13 ------------- arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi | 12 ------------ 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts index a32985e6bdb0..6633a017a027 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts @@ -53,10 +53,13 @@ }; &mdss_dsi0 { - /delete-property/ qcom,platform-enable-gpio; - vdd-supply = <&vreg_d322_vdd>; /* 2.8v */ + qcom,platform-enable-gpio = <&pm660_gpios 12 0>; + /delete-property/ vdd-supply; qcom,dsi-pref-prim-pan = <&dsi_truly_rm69090_qvga_cmd>; }; +&dsi_pm660_panel_pwr_supply { + /delete-node/ qcom,panel-supply-entry@0; +}; &pm660_gpios { gpio@cb00 { diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index e9d6c3e0ab4b..83d529bfc106 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -376,19 +376,6 @@ qcom,gpios-disallowed = <1 2 3 5 6 7 8 9 10 11 13>; }; -/* pm660 gpio pinctrl configuration */ -&pm660_gpios { - /* GPIO 12 (DISPLAY_AVDD_EN) */ - vreg_d322 { - vreg_regulator_d322: vreg_regulator-d322 { - pins = "gpio12"; - function = "normal"; - output-enable; - qcom,drive-strength = <2>; - }; - }; -}; - &pm660_vadc { /delete-node/ chan@1d; }; diff --git a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi index 064e662db73e..b4dd41eaef08 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi @@ -358,16 +358,4 @@ regulator-min-microvolt = <2950000>; regulator-max-microvolt = <2950000>; }; - - vreg_d322_vdd: d322-vdd-fixed-regulator { - compatible = "regulator-fixed"; - regulator-name = "d322_vreg"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - startup-delay-us = <400>; - enable-active-high; - gpio = <&pm660_gpios 12 0>; - status = "okay"; - regulator-boot-on; - }; }; From 11168e48d590b48032e4a5cbe8f23d156db96765 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Thu, 1 Aug 2019 15:33:47 +0530 Subject: [PATCH 214/281] ARM: dts: msm: Add dpdm-supply node for sdm429w+PM660 The dpdm-supply node is used to vote the USB regulators before APSD, it guarantees that the D+/- are in High-Z for APSD. Change-Id: I8bc3002e51a18e08b212b13af724480ec48994d8 Signed-off-by: Anirudh Ghayal --- arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi index b432ce4ec14c..907879c5453a 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-pm660.dtsi @@ -403,6 +403,8 @@ qcom,use-extcon; qcom,pd-not-supported; + dpdm-supply = <&usb_otg>; + qcom,chgr@1000 { reg = <0x1000 0x100>; interrupts = From 986ee321863f0d891ba77078f73cf14282fd4067 Mon Sep 17 00:00:00 2001 From: zhaochen Date: Wed, 31 Jul 2019 11:30:30 +0800 Subject: [PATCH 215/281] ARM: dts: msm: remove the unused dts files for sdm429 spyro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sdm429-qrd-spyro-* is instead of sdm429-spyro-qrd-*, so we will remove them. Change-Id: Ib3d0eb88a9eab6509dd836970328b9ba79f01e43 Signed-off-by: zhaochen --- .../dts/qcom/sdm429-qrd-spyro-evt-overlay.dts | 22 - .../boot/dts/qcom/sdm429-qrd-spyro-evt.dts | 24 - .../boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi | 667 ------------------ 3 files changed, 713 deletions(-) delete mode 100644 arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt-overlay.dts delete mode 100644 arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dts delete mode 100644 arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi diff --git a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt-overlay.dts deleted file mode 100644 index a90c4badfe04..000000000000 --- a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt-overlay.dts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2019, 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/; -/plugin/; - -#include "sdm429-qrd-spyro-evt.dtsi" - -/ { - model = "Qualcomm Technologies, Inc. SDM429 QRD Spyro Overlay"; - qcom,board-id = <0xb 6>; -}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dts b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dts deleted file mode 100644 index c9d952d72fff..000000000000 --- a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2019, 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 "sdm429.dtsi" -#include "sdm429-qrd-spyro-evt.dtsi" - -/ { - model = "Qualcomm Technologies, Inc. SDM429 QRD Spyro"; - compatible = "qcom,sdm429-qrd", "qcom,sdm429", "qcom,qrd"; - qcom,board-id = <0xb 6>; - qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; -}; diff --git a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi deleted file mode 100644 index eaa844b372cb..000000000000 --- a/arch/arm64/boot/dts/qcom/sdm429-qrd-spyro-evt.dtsi +++ /dev/null @@ -1,667 +0,0 @@ -/* - * Copyright (c) 2019, 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 "sdm439-qrd.dtsi" -#include "sdm429w-pm660.dtsi" - -&gpio_key_active { - mux { - pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; - function = "gpio"; - }; - - config { - pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; - drive-strength = <2>; - bias-pull-up; - }; -}; - -&gpio_key_suspend { - mux { - pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; - function = "gpio"; - }; - - config { - pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; - drive-strength = <2>; - bias-pull-up; - }; -}; - -&cdc_pdm_lines_act { - mux { - pins = "gpio68", "gpio73", "gpio74"; - function = "cdc_pdm0"; - }; - - config { - pins = "gpio68", "gpio73", "gpio74"; - drive-strength = <16>; - }; -}; - -&cdc_pdm_lines_sus { - mux { - pins = "gpio68", "gpio73", "gpio74"; - function = "cdc_pdm0"; - }; - - config { - pins = "gpio68", "gpio73", "gpio74"; - drive-strength = <2>; - bias-disable; - }; -}; - -&cam_sensor_rear_standby { - /* STANDBY */ - mux { - /delete-property/ pins; - pins = "gpio92"; - function = "gpio"; - }; - - config { - /delete-property/ pins; - pins = "gpio92"; - bias-disable; /* No PULL */ - drive-strength = <2>; /* 2 MA */ - }; -}; - -&cam_sensor_rear_standby_sleep { - /* STANDBY */ - mux { - /delete-property/ pins; - pins = "gpio92"; - function = "gpio"; - }; - - config { - /delete-property/ pins; - pins = "gpio92"; - bias-disable; /* No PULL */ - drive-strength = <2>; /* 2 MA */ - }; -}; - -&cam_sensor_rear_vana { - /* VANA */ - mux { - /delete-property/ pins; - pins = "gpio58"; - function = "gpio"; - }; - - config { - /delete-property/ pins; - pins = "gpio58"; - bias-disable; /* No PULL */ - drive-strength = <2>; /* 2 MA */ - }; -}; - -&cam_sensor_rear_vana_sleep { - /* VANA */ - mux { - /delete-property/ pins; - pins = "gpio58"; - function = "gpio"; - }; - - config { - /delete-property/ pins; - pins = "gpio58"; - bias-disable; /* No PULL */ - drive-strength = <2>; /* 2 MA */ - }; -}; -&mdss_dsi0 { - qcom,dsi-pref-prim-pan = <&dsi_edo_rm67162_qvga_cmd>; - pinctrl-names = "mdss_default", "mdss_sleep"; - pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; - pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; - qcom,platform-te-gpio = <&tlmm 24 0>; - qcom,platform-reset-gpio = <&tlmm 60 0>; - qcom,platform-enable-gpio = <&tlmm 69 0>; -}; - -&dsi_edo_rm67162_qvga_cmd { - /delete-property/ qcom,mdss-dsi-panel-timings; - qcom,mdss-dsi-panel-timings-phy-12nm = [06 05 01 0A 00 03 01 0F]; - qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; - qcom,panel-supply-entries = <&dsi_pm660_panel_pwr_supply>; -}; -&soc { - /delete-node/ qcom,cci@1b0c000; - cci: qcom,cci@1b0c000 { - status = "ok"; - cell-index = <0>; - compatible = "qcom,cci"; - reg = <0x1b0c000 0x4000>; - #address-cells = <1>; - #size-cells = <0>; - reg-names = "cci"; - interrupts = <0 50 0>; - interrupt-names = "cci"; - clocks = <&clock_gcc clk_gcc_camss_ispif_ahb_clk>, - <&clock_gcc clk_cci_clk_src>, - <&clock_gcc clk_gcc_camss_cci_ahb_clk>, - <&clock_gcc clk_gcc_camss_cci_clk>, - <&clock_gcc clk_gcc_camss_ahb_clk>, - <&clock_gcc clk_gcc_camss_top_ahb_clk>; - clock-names = "ispif_ahb_clk", "cci_src_clk", - "cci_ahb_clk", "camss_cci_clk", - "camss_ahb_clk", "camss_top_ahb_clk"; - qcom,clock-rates = <61540000 19200000 0 0 0 0>, - <61540000 37500000 0 0 0 0>; - pinctrl-names = "cci_default", "cci_suspend"; - pinctrl-0 = <&cci0_active &cci1_active>; - pinctrl-1 = <&cci0_suspend &cci1_suspend>; - gpios = <&tlmm 29 0>, - <&tlmm 30 0>, - <&tlmm 31 0>, - <&tlmm 32 0>; - qcom,gpio-tbl-num = <0 1 2 3>; - qcom,gpio-tbl-flags = <1 1 1 1>; - qcom,gpio-tbl-label = "CCI_I2C_DATA0", - "CCI_I2C_CLK0", - "CCI_I2C_DATA1", - "CCI_I2C_CLK1"; - i2c_freq_100Khz: qcom,i2c_standard_mode { - status = "disabled"; - }; - i2c_freq_400Khz: qcom,i2c_fast_mode { - status = "disabled"; - }; - i2c_freq_custom: qcom,i2c_custom_mode { - status = "disabled"; - }; - - i2c_freq_1Mhz: qcom,i2c_fast_plus_mode { - status = "disabled"; - }; - }; -}; - -#include "sdm429w-camera-sensor-spyro.dtsi" - -&i2c_5 { - status = "disabled"; -}; - -&vol_up { - gpios = <&tlmm 35 0x1>; -}; - -&gpio_keys { - function_1: function_1 { - label = "function_1"; - gpios = <&tlmm 127 0x1>; - linux,input-type = <1>; - linux,code = <116>; - debounce-interval = <15>; - linux,can-disable; - gpio-key,wakeup; - }; - - function_2: function_2 { - label = "function_2"; - gpios = <&tlmm 126 0x1>; - linux,input-type = <1>; - linux,code = <117>; - debounce-interval = <15>; - linux,can-disable; - gpio-key,wakeup; - }; -}; - -&soc { - /delete-node/ qcom,spm@b1d2000; - qcom,spm@b1d2000 { - compatible = "qcom,spm-v2"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0xb1d2000 0x1000>; - qcom,name = "system-cci"; - qcom,saw2-ver-reg = <0xfd0>; - qcom,saw2-cfg = <0x14>; - qcom,saw2-spm-dly= <0x3C102800>; - qcom,saw2-spm-ctl = <0xe>; - qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; - qcom,vctl-timeout-us = <500>; - qcom,vctl-port = <0x0>; - qcom,vctl-port-ub = <0x1>; - qcom,pfm-port = <0x2>; - }; - -}; - - -&dsi_hx8399c_hd_vid { - qcom,mdss-dsi-on-command = [ - 39 01 00 00 00 00 04 - b9 ff 83 99 - 39 01 00 00 00 00 02 - d2 88 - 39 01 00 00 00 00 0c - b1 02 04 72 92 01 - 32 aa 11 11 52 57 - 39 01 00 00 00 00 10 - b2 00 80 80 cc 05 07 5a - 11 10 10 00 1e 70 03 d4 - 39 01 00 00 00 00 2d - b4 00 ff 59 59 01 ab 00 - 00 09 00 03 05 00 28 03 - 0b 0d 21 03 02 00 0c a3 - 80 59 59 02 ab 00 00 09 - 00 03 05 00 28 03 0b 0d - 02 00 0c a3 01 - 39 01 00 00 05 00 22 - d3 00 0c 03 03 00 00 10 - 10 00 00 03 00 03 00 08 - 78 08 78 00 00 00 00 00 - 24 02 05 05 03 00 00 00 - 05 40 - 39 01 00 00 05 00 21 - d5 20 20 19 19 18 18 02 - 03 00 01 24 24 18 18 18 - 18 24 24 00 00 00 00 00 - 00 00 00 2f 2f 30 30 31 - 31 - 39 01 00 00 05 00 21 - d6 24 24 18 18 19 19 01 - 00 03 02 24 24 18 18 18 - 18 20 20 40 40 40 40 40 - 40 40 40 2f 2f 30 30 31 - 31 - 39 01 00 00 00 00 02 - bd 00 - 39 01 00 00 00 00 11 - d8 aa aa aa aa aa aa aa - aa aa ba aa aa aa ba aa - aa - 39 01 00 00 00 00 02 - bd 01 - 39 01 00 00 00 00 11 - d8 00 00 00 00 00 00 00 - 00 82 ea aa aa 82 ea aa - aa - 39 01 00 00 00 00 02 - bd 02 - 39 01 00 00 00 00 09 - d8 ff ff c0 3f ff ff c0 - 3f - 39 01 00 00 00 00 02 - bd 00 - 39 01 00 00 05 00 37 - e0 01 21 31 2d 66 6f 7b - 75 7a 81 86 89 8c 90 95 - 97 9a a1 a2 aa 9e ad b0 - 5b 57 63 7a 01 21 31 2d - 66 6f 7b 75 7a 81 86 89 - 8c 90 95 97 9a a1 a2 aa - 9e ad b0 5b 57 63 7a - 39 01 00 00 00 00 03 - b6 7e 7e - 39 01 00 00 00 00 02 - cc 08 - 39 01 00 00 00 00 02 - 35 00 - 39 01 00 00 00 00 02 - dd 03 - 05 01 00 00 78 00 02 11 00 - 05 01 00 00 05 00 02 29 00]; - qcom,mdss-dsi-reset-sequence = <1 2>, <0 5>, <1 10>; - }; - -&firmware { - android { - compatible = "android,firmware"; - vbmeta { - compatible = "android,vbmeta"; - parts = "vbmeta,boot,system,vendor,dtbo,recovery"; - }; - fstab { - compatible = "android,fstab"; - vendor { - compatible = "android,vendor"; - dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor"; - type = "ext4"; - mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait,avb"; - status = "ok"; - }; - system { - compatible = "android,system"; - dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system"; - type = "ext4"; - mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait,avb"; - status = "ok"; - }; - }; - }; -}; - -&i2c_4 { - status = "ok"; - - tsc@24 { - compatible = "cy,cyttsp5_i2c_adapter"; - reg = <0x24>; - - interrupt-parent = <&tlmm>; - interrupts = <65 0x2008>; - cy,adapter_id = "cyttsp5_i2c_adapter"; - vcc_i2c-supply = <&L13A>; - vdd-supply = <&L15A>; - pinctrl-names = "pmx_ts_active", "pmx_ts_suspend", - "pmx_ts_release"; - pinctrl-0 = <&ts_int_active &ts_reset_active>; - pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; - pinctrl-2 = <&ts_release>; - - cy,core { - cy,name = "cyttsp5_core"; - cy,irq_gpio = <65>; - cy,rst_gpio = <64>; - cy,hid_desc_register = <1>; - cy,flags = <4>; - cy,easy_wakeup_gesture = <1>; - cy,btn_keys = <172 139 158 217 114 115 212 116>; - cy,btn_keys-tag = <0>; - - cy,mt { - cy,name = "cyttsp5_mt"; - - cy,inp_dev_name = "cyttsp5_mt"; - cy,flags = <0x28>; - cy,abs = - <0x35 0 320 0 0 - 0x36 0 360 0 0 - 0x3a 0 255 0 0 - 0xffff 0 255 0 0 - 0x39 0 15 0 0 - 0x30 0 255 0 0 - 0x31 0 255 0 0 - 0x34 0xffffff81 127 0 0 - 0x37 0 1 0 0 - 0x3b 0 255 0 0>; - - cy,vkeys_x = <320>; - cy,vkeys_y = <360>; - - cy,virtual_keys = - <158 1360 90 160 180 - 139 1360 270 160 180 - 172 1360 450 160 180 - 217 1360 630 160 180>; - }; - - cy,btn { - cy,name = "cyttsp5_btn"; - - cy,inp_dev_name = "cyttsp5_btn"; - }; - - cy,proximity { - cy,name = "cyttsp5_proximity"; - - cy,inp_dev_name = "cyttsp5_proximity"; - cy,abs = <0x19 0 1 0 0>; - }; - }; - }; - -}; - -&tlmm { - pmx_ts_int_active { - ts_int_active: ts_int_active { - mux { - pins = "gpio65"; - function = "gpio"; - }; - - config { - pins = "gpio65"; - drive-strength = <8>; - bias-pull-up; - }; - }; - }; - - pmx_ts_int_suspend { - ts_int_suspend: ts_int_suspend { - mux { - pins = "gpio65"; - function = "gpio"; - }; - - config { - pins = "gpio65"; - drive-strength = <2>; - bias-pull-down; - }; - }; - }; - - pmx_ts_reset_active { - ts_reset_active: ts_reset_active { - mux { - pins = "gpio64"; - function = "gpio"; - }; - - config { - pins = "gpio64"; - drive-strength = <8>; - bias-pull-up; - }; - }; - }; - - pmx_ts_reset_suspend { - ts_reset_suspend: ts_reset_suspend { - mux { - pins = "gpio64"; - function = "gpio"; - }; - - config { - pins = "gpio64"; - drive-strength = <2>; - bias-pull-down; - }; - }; - }; - - pmx_ts_release { - ts_release: ts_release { - mux { - pins = "gpio65", "gpio64"; - function = "gpio"; - }; - - config { - pins = "gpio65", "gpio64"; - drive-strength = <2>; - bias-pull-down; - }; - }; - }; - - smart_pa_int { - pa_int_default: pa_int_default { - mux { - pins = "gpio73", "gpio73"; - function = "gpio"; - }; - - config { - pins = "gpio73", "gpio73"; - drive-strength = <4>; - bias-disable; - }; - }; - }; - - smart_pa_rst { - pa_rst_default: pa_rst_default { - mux { - pins = "gpio68", "gpio68"; - function = "gpio"; - }; - - config { - pins = "gpio68", "gpio68"; - drive-strength = <4>; - bias-disable; - }; - }; - }; - -}; - -&modem_mem { - reg = <0x0 0x86800000 0x0 0x5000000>; -}; - -&adsp_fw_mem { - reg = <0x0 0x8b800000 0x0 0x1400000>; -}; - -&wcnss_fw_mem { - reg = <0x0 0x8cc00000 0x0 0x700000>; -}; - - -&int_codec { - compatible = "qcom,msm8952-dig-asoc-snd"; - status = "okay"; - qcom,model = "sdm429-qrd-snd-card"; - qcom,msm-ext-pa = "quaternary"; - /delete-property/ qcom,split-a2dp; - asoc-wsa-codec-names; - asoc-wsa-codec-prefixes; - ext_pa_aw8896; - qcom,audio-routing = - "CDC_CONN", "MCLK", - "QUAT_MI2S_RX", "DIGITAL_REGULATOR", - "TX_I2S_CLK", "DIGITAL_REGULATOR", - "DMIC1", "Digital Mic1", - "DMIC2", "Digital Mic2"; - qcom,cdc-dmic-gpios = <&cdc_dmic_gpios>; - qcom,quat-mi2s-gpios = <&cdc_quat_mi2s_gpios>; - qcom,msm-gpios = - "quat_i2s", - "dmic"; - qcom,pinctrl-names = - "all_off", - "quat_i2s_act", - "dmic_act", - "quat_i2s_dmic_act"; - pinctrl-names = - "all_off", - "quat_i2s_act", - "dmic_act", - "quat_i2s_dmic_act"; - pinctrl-0 = <&quat_mi2s_sleep &quat_mi2s_din_sleep - &cdc_dmic0_clk_sus &cdc_dmic0_data_sus>; - pinctrl-1 = <&quat_mi2s_active &quat_mi2s_din_active - &cdc_dmic0_clk_sus &cdc_dmic0_data_sus>; - pinctrl-2 = <&quat_mi2s_sleep &quat_mi2s_din_sleep - &cdc_dmic0_clk_act &cdc_dmic0_data_act>; - pinctrl-3 = <&quat_mi2s_active &quat_mi2s_din_active - &cdc_dmic0_clk_act &cdc_dmic0_data_act>; - /delete-property/qcom,cdc-us-euro-gpios; - /delete-property/qcom,pri-mi2s-gpios; - /delete-property/qcom,cdc-us-eu-gpios; - - - asoc-codec = <&stub_codec>, <&msm_dig_codec>, <&ext_smart_pa>; - asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec", "ext-smart-pa"; -}; - -&soc { - msm_dig_codec: msm_dig_codec { - compatible = "qcom,msm-digital-codec"; - reg = <0xc0f0000 0x0>; - qcom,no-analog-codec; - cdc-vdd-digital-supply = <&pm660_l9>; - qcom,cdc-vdd-digital-voltage = <1800000 1800000>; - qcom,cdc-vdd-digital-current = <10000>; - qcom,cdc-on-demand-supplies = "cdc-vdd-digital"; - }; - - cdc_dmic_gpios: cdc_dmic_pinctrl { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&cdc_dmic0_clk_act &cdc_dmic0_data_act>; - pinctrl-1 = <&cdc_dmic0_clk_sus &cdc_dmic0_data_sus>; - }; - - cdc_quat_mi2s_gpios: msm_cdc_pinctrl_quat { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&quat_mi2s_active &quat_mi2s_din_active>; - pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_din_sleep>; - }; -}; - -&wsa881x_i2c_f { - status = "disabled"; -}; - -&wsa881x_i2c_45 { - status = "disabled"; -}; - -&wsa881x_analog_vi_gpio { - status = "disabled"; -}; - -&wsa881x_analog_clk_gpio { - status = "disabled"; -}; - -&wsa881x_analog_reset_gpio { - status = "disabled"; -}; - -&cdc_us_euro_sw { - status = "disabled"; -}; - -&cdc_pri_mi2s_gpios { - status = "disabled"; -}; - -&cdc_quin_mi2s_gpios { - status = "disabled"; -}; - -&i2c_2 { - ext_smart_pa: aw8896_smartpa@34 { - compatible = "awinic,aw8896_smartpa"; - reg = <0x34>; - reset-gpio = <&tlmm 68 0>; - irq-gpio = <&tlmm 73 0>; - pinctrl-names = "default"; - pinctrl-0 = <&pa_int_default &pa_rst_default>; - status = "okay"; - }; -}; From 043fdc251c44560e45c7fccfb321e52a3286747c Mon Sep 17 00:00:00 2001 From: Junlin Zhang Date: Wed, 7 Aug 2019 11:05:58 +0800 Subject: [PATCH 216/281] bt-power: Check reset-gpio status before calling BT reset When bt-power driver is probed, it calls BT reset because of the value of reset-gpio is high. So it needs to check reset-gpio status before calling BT reset. CRs-Fixed: 2495853 Change-Id: I88569ba4375931f3062afccba5c6699fdda50d3d Signed-off-by: Junlin Zhang --- drivers/bluetooth/bluetooth-power.c | 22 ++++++++++++++++++++-- include/linux/bluetooth-power.h | 5 ++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/bluetooth-power.c b/drivers/bluetooth/bluetooth-power.c index b90bbfe0bdde..650585c2ea44 100644 --- a/drivers/bluetooth/bluetooth-power.c +++ b/drivers/bluetooth/bluetooth-power.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2010, 2013-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2009-2010, 2013-2019 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 @@ -613,6 +613,23 @@ static int bt_power_populate_dt_pinfo(struct platform_device *pdev) return 0; } +static int get_bt_reset_gpio_value(void) +{ + int rc = 0; + int bt_reset_gpio = bt_power_pdata->bt_gpio_sys_rst; + + rc = gpio_request(bt_reset_gpio, "bt_sys_rst_n"); + if (rc) { + BT_PWR_ERR("unable to request gpio %d (%d)\n", + bt_reset_gpio, rc); + return rc; + } + + rc = gpio_get_value(bt_reset_gpio); + gpio_free(bt_power_pdata->bt_gpio_sys_rst); + return rc; +} + static int bt_power_probe(struct platform_device *pdev) { int ret = 0; @@ -659,7 +676,8 @@ static int bt_power_probe(struct platform_device *pdev) btpdev = pdev; if (of_id) { - if (strcmp(of_id->compatible, "qca,qca6174") == 0) { + if ((get_bt_reset_gpio_value() == BT_RESET_GPIO_HIGH_VAL) + && (strcmp(of_id->compatible, "qca,qca6174") == 0)) { bluetooth_toggle_radio(pdev->dev.platform_data, 0); bluetooth_toggle_radio(pdev->dev.platform_data, 1); } diff --git a/include/linux/bluetooth-power.h b/include/linux/bluetooth-power.h index 901dae0a5d08..b4e212820ea1 100644 --- a/include/linux/bluetooth-power.h +++ b/include/linux/bluetooth-power.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, 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 @@ -88,4 +88,7 @@ int get_chipset_version(void); #define BT_CMD_SLIM_TEST 0xbfac #define BT_CMD_PWR_CTRL 0xbfad #define BT_CMD_CHIPSET_VERS 0xbfae + +#define BT_RESET_GPIO_HIGH_VAL 0x1 + #endif /* __LINUX_BLUETOOTH_POWER_H */ From 5230a47c559748b88043dd26b8b24e2f14f47899 Mon Sep 17 00:00:00 2001 From: Bo Zhang Date: Wed, 7 Aug 2019 15:37:01 +0800 Subject: [PATCH 217/281] ARM: dts: msm: Modify SDM429W WDP subtype id to adapt corresponding CDT Modify SDM429W WDP subtype id to adapt corresponding CDT Change-Id: I7dc4d7d3d36369138fd97971e53c3e92d74c5843 Signed-off-by: Bo Zhang --- arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts | 2 +- arch/arm64/boot/dts/qcom/sdm429-spyro-wdp.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts index f70c45834fed..bbbe530246a4 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-wdp-overlay.dts @@ -20,7 +20,7 @@ model = "Qualcomm Technologies, Inc. SDM429 QRD Spyro WDP Overlay"; compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd"; qcom,msm-id = <416 0x0>; - qcom,board-id = <0x01000b 6>; + qcom,board-id = <0x01000b 7>; qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; }; diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-wdp.dts b/arch/arm64/boot/dts/qcom/sdm429-spyro-wdp.dts index dd12d18efa78..b6eedafb5697 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-wdp.dts +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-wdp.dts @@ -19,6 +19,6 @@ model = "Qualcomm Technologies, Inc. SDM429 QRD Spyro WDP"; compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd"; qcom,msm-id = <416 0x0>; - qcom,board-id = <0x01000b 6>; + qcom,board-id = <0x01000b 7>; qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>; }; From 5c95b531184ba95618b264282de2d08f8fdb09dd Mon Sep 17 00:00:00 2001 From: jianzhou Date: Fri, 26 Jul 2019 13:42:32 +0800 Subject: [PATCH 218/281] Revert "mm: memcontrol: fix NULL pointer crash in test_clear_page_writeback()" This reverts commit d4a742865c6b69ef931694745ef54965d7c9966c. LTS android-4.9.183 (a80a7ab) has conflicts with the reverted code. They do the same thing, use LTS solution. Change-Id: If64be3448dc5d4fdc66cb119aa46b52b341da8fd Signed-off-by: jianzhou --- include/linux/memcontrol.h | 33 +++++------------------------ mm/memcontrol.c | 43 +++++++++++--------------------------- mm/page-writeback.c | 14 +++---------- 3 files changed, 20 insertions(+), 70 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index fd77f8303ab9..8b35bdbdc214 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -490,21 +490,9 @@ bool mem_cgroup_oom_synchronize(bool wait); extern int do_swap_account; #endif -struct mem_cgroup *lock_page_memcg(struct page *page); -void __unlock_page_memcg(struct mem_cgroup *memcg); +void lock_page_memcg(struct page *page); void unlock_page_memcg(struct page *page); -static inline void __mem_cgroup_update_page_stat(struct page *page, - struct mem_cgroup *memcg, - enum mem_cgroup_stat_index idx, - int val) -{ - VM_BUG_ON(!(rcu_read_lock_held() || PageLocked(page))); - - if (memcg && memcg->stat) - this_cpu_add(memcg->stat->count[idx], val); -} - /** * mem_cgroup_update_page_stat - update page state statistics * @page: the page @@ -520,12 +508,13 @@ static inline void __mem_cgroup_update_page_stat(struct page *page, * mem_cgroup_update_page_stat(page, state, -1); * unlock_page(page) or unlock_page_memcg(page) */ - static inline void mem_cgroup_update_page_stat(struct page *page, enum mem_cgroup_stat_index idx, int val) { + VM_BUG_ON(!(rcu_read_lock_held() || PageLocked(page))); - __mem_cgroup_update_page_stat(page, page->mem_cgroup, idx, val); + if (page->mem_cgroup) + this_cpu_add(page->mem_cgroup->stat->count[idx], val); } static inline void mem_cgroup_inc_page_stat(struct page *page, @@ -720,12 +709,7 @@ mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) { } -static inline struct mem_cgroup *lock_page_memcg(struct page *page) -{ - return NULL; -} - -static inline void __unlock_page_memcg(struct mem_cgroup *memcg) +static inline void lock_page_memcg(struct page *page) { } @@ -761,13 +745,6 @@ static inline void mem_cgroup_update_page_stat(struct page *page, { } -static inline void __mem_cgroup_update_page_stat(struct page *page, - struct mem_cgroup *memcg, - enum mem_cgroup_stat_index idx, - int nr) -{ -} - static inline void mem_cgroup_inc_page_stat(struct page *page, enum mem_cgroup_stat_index idx) { diff --git a/mm/memcontrol.c b/mm/memcontrol.c index edaa13395813..433b770f0600 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1619,13 +1619,9 @@ bool mem_cgroup_oom_synchronize(bool handle) * @page: the page * * This function protects unlocked LRU pages from being moved to - * another cgroup. - * - * It ensures lifetime of the returned memcg. Caller is responsible - * for the lifetime of the page; __unlock_page_memcg() is available - * when @page might get freed inside the locked section. + * another cgroup and stabilizes their page->mem_cgroup binding. */ -struct mem_cgroup *lock_page_memcg(struct page *page) +void lock_page_memcg(struct page *page) { struct mem_cgroup *memcg; unsigned long flags; @@ -1634,24 +1630,18 @@ struct mem_cgroup *lock_page_memcg(struct page *page) * The RCU lock is held throughout the transaction. The fast * path can get away without acquiring the memcg->move_lock * because page moving starts with an RCU grace period. - * - * The RCU lock also protects the memcg from being freed when - * the page state that is going to change is the only thing - * preventing the page itself from being freed. E.g. writeback - * doesn't hold a page reference and relies on PG_writeback to - * keep off truncation, migration and so forth. - */ + */ rcu_read_lock(); if (mem_cgroup_disabled()) - return NULL; + return; again: memcg = page->mem_cgroup; if (unlikely(!memcg)) - return NULL; + return; if (atomic_read(&memcg->moving_account) <= 0) - return memcg; + return; spin_lock_irqsave(&memcg->move_lock, flags); if (memcg != page->mem_cgroup) { @@ -1667,18 +1657,18 @@ struct mem_cgroup *lock_page_memcg(struct page *page) memcg->move_lock_task = current; memcg->move_lock_flags = flags; - return memcg; + return; } EXPORT_SYMBOL(lock_page_memcg); /** - * __unlock_page_memcg - unlock and unpin a memcg - * @memcg: the memcg - * - * Unlock and unpin a memcg returned by lock_page_memcg(). + * unlock_page_memcg - unlock a page->mem_cgroup binding + * @page: the page */ -void __unlock_page_memcg(struct mem_cgroup *memcg) +void unlock_page_memcg(struct page *page) { + struct mem_cgroup *memcg = page->mem_cgroup; + if (memcg && memcg->move_lock_task == current) { unsigned long flags = memcg->move_lock_flags; @@ -1690,15 +1680,6 @@ void __unlock_page_memcg(struct mem_cgroup *memcg) rcu_read_unlock(); } - -/** - * unlock_page_memcg - unlock a page->mem_cgroup binding - * @page: the page - */ -void unlock_page_memcg(struct page *page) -{ - __unlock_page_memcg(page->mem_cgroup); -} EXPORT_SYMBOL(unlock_page_memcg); /* diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 77bc0881dd1e..7b67968f4396 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -2704,10 +2704,9 @@ EXPORT_SYMBOL(clear_page_dirty_for_io); int test_clear_page_writeback(struct page *page) { struct address_space *mapping = page_mapping(page); - struct mem_cgroup *memcg; int ret; - memcg = lock_page_memcg(page); + lock_page_memcg(page); if (mapping && mapping_use_writeback_tags(mapping)) { struct inode *inode = mapping->host; struct backing_dev_info *bdi = inode_to_bdi(inode); @@ -2735,20 +2734,13 @@ int test_clear_page_writeback(struct page *page) } else { ret = TestClearPageWriteback(page); } - /* - * NOTE: Page might be free now! Writeback doesn't hold a page - * reference on its own, it relies on truncation to wait for - * the clearing of PG_writeback. The below can only access - * page state that is static across allocation cycles. - */ if (ret) { - __mem_cgroup_update_page_stat(page, memcg, - MEM_CGROUP_STAT_WRITEBACK, -1); + mem_cgroup_dec_page_stat(page, MEM_CGROUP_STAT_WRITEBACK); dec_node_page_state(page, NR_WRITEBACK); dec_zone_page_state(page, NR_ZONE_WRITE_PENDING); inc_node_page_state(page, NR_WRITTEN); } - __unlock_page_memcg(memcg); + unlock_page_memcg(page); return ret; } From da65e2d8778e753f6811ab1ba7a0c74ea2b259bf Mon Sep 17 00:00:00 2001 From: Naitik Bharadiya Date: Mon, 29 Jul 2019 12:19:47 +0530 Subject: [PATCH 219/281] defconfig: change BLK_DEV_LOOP_MIN_COUNT's value for SDM710 and SDM845 Change BLK_DEV_LOOP_MIN_COUNT's value from 8 to 16 for SDM710 and SDM845. Change-Id: I81ae95c13ebc6018bdb174cd66c86350cd1e2697 Signed-off-by: Naitik Bharadiya --- arch/arm64/configs/sdm670-perf_defconfig | 1 + arch/arm64/configs/sdm670_defconfig | 1 + arch/arm64/configs/sdm845-perf_defconfig | 1 + arch/arm64/configs/sdm845_defconfig | 1 + 4 files changed, 4 insertions(+) diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig index 58aabffd6c6c..157f2e85e37e 100755 --- a/arch/arm64/configs/sdm670-perf_defconfig +++ b/arch/arm64/configs/sdm670-perf_defconfig @@ -249,6 +249,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig index a9f8f6532276..8c32734b76eb 100755 --- a/arch/arm64/configs/sdm670_defconfig +++ b/arch/arm64/configs/sdm670_defconfig @@ -258,6 +258,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index af5b1cb46d2d..ee7b2080764f 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -250,6 +250,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index c2bd7bef6270..eeb19c738f6c 100755 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -256,6 +256,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y From e14cf9447ebb4328dd9cfcc790a2a8efe3d912b7 Mon Sep 17 00:00:00 2001 From: zhaochen Date: Wed, 7 Aug 2019 18:17:57 +0800 Subject: [PATCH 220/281] ARM: dts: msm: Support 16bit vlevel setting from SAW for sdm429 spyro Update pvc port configuration for sending upper byte of 16bit vlevel for SDM439 spyro EVT device. Change-Id: I97425e6560e3a7ee96b5460c20b77f06d4ad75e3 Signed-off-by: zhaochen --- .../boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi index cc104988b351..04f08623e64b 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi @@ -42,6 +42,24 @@ }; &soc { + /delete-node/ qcom,spm@b1d2000; + qcom,spm@b1d2000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xb1d2000 0x1000>; + qcom,name = "system-cci"; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x14>; + qcom,saw2-spm-dly= <0x3C102800>; + qcom,saw2-spm-ctl = <0xe>; + qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,vctl-timeout-us = <500>; + qcom,vctl-port = <0x0>; + qcom,vctl-port-ub = <0x1>; + qcom,pfm-port = <0x2>; + }; + gpio_keys: gpio_keys { compatible = "gpio-keys"; label = "gpio-keys"; From 972f72089413334004fbba701e1d4a85d59bb318 Mon Sep 17 00:00:00 2001 From: Jim Blackler Date: Fri, 5 Apr 2019 16:25:04 +0100 Subject: [PATCH 221/281] ANDROID: Communicates LMK events to userland where they can be logged Makes a file /proc/lowmemorykiller available for polling by user space. Immediately as a process is killed by lowmemorykiller information about that process is pushed to the file. It contains information about the process at the time it was killed, to be gathered as metrics. The file is expected to be continuously read from. To prevent failure to do so from causing memory to be continuously consumed, after eight processes have been killed, no more events will be logged until the file is read from again. The format is integers separated by spaces: Field 0 pid The identifier of the process. Field 1 uid The UNIX ID of the user the process was running under. Field 2 group_leader_pid The group leader of the process. Field 3 min_flt The number of minor page faults. Field 4 maj_flt The number of minor page faults. Field 5 rss_in_pages The Resident Set Size in pages. Field 6 oom_score_adj The adjusted Out Of Memory score. Field 7 start_time The number of nanoseconds that the process ran for. --New line-- Field 8 taskname The cmd line used to launch the process, truncated to 127 characters, and terminated by a new line. Bug: 130017100 Test: Tested manually Change-Id: I461b191eda9e578b9d2c2d1843b1b81948353a95 Signed-off-by: Jim Blackler Git-commit: 9fd99422748a952a0c01ee9846c5d213a96f23f2 Git-repo: https://android.googlesource.com/kernel/common/ [spathi@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Srinivasarao P --- drivers/staging/android/lowmemorykiller.c | 153 ++++++++++++++++++++++ 1 file changed, 153 insertions(+) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index ecae4c9f8ba8..a1febafbcb5e 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -98,6 +98,157 @@ static unsigned long lowmem_deathpending_timeout; pr_info(x); \ } while (0) + +static DECLARE_WAIT_QUEUE_HEAD(event_wait); +static DEFINE_SPINLOCK(lmk_event_lock); +static struct circ_buf event_buffer; +#define MAX_BUFFERED_EVENTS 8 +#define MAX_TASKNAME 128 + +struct lmk_event { + char taskname[MAX_TASKNAME]; + pid_t pid; + uid_t uid; + pid_t group_leader_pid; + unsigned long min_flt; + unsigned long maj_flt; + unsigned long rss_in_pages; + short oom_score_adj; + short min_score_adj; + unsigned long long start_time; + struct list_head list; +}; + +void handle_lmk_event(struct task_struct *selected, short min_score_adj) +{ + int head; + int tail; + struct lmk_event *events; + struct lmk_event *event; + int res; + long rss_in_pages = -1; + struct mm_struct *mm = get_task_mm(selected); + + if (mm) { + rss_in_pages = get_mm_rss(mm); + mmput(mm); + } + + spin_lock(&lmk_event_lock); + + head = event_buffer.head; + tail = READ_ONCE(event_buffer.tail); + + /* Do not continue to log if no space remains in the buffer. */ + if (CIRC_SPACE(head, tail, MAX_BUFFERED_EVENTS) < 1) { + spin_unlock(&lmk_event_lock); + return; + } + + events = (struct lmk_event *) event_buffer.buf; + event = &events[head]; + + res = get_cmdline(selected, event->taskname, MAX_TASKNAME - 1); + + /* No valid process name means this is definitely not associated with a + * userspace activity. + */ + + if (res <= 0 || res >= MAX_TASKNAME) { + spin_unlock(&lmk_event_lock); + return; + } + + event->taskname[res] = '\0'; + event->pid = selected->pid; + event->uid = from_kuid_munged(current_user_ns(), task_uid(selected)); + if (selected->group_leader) + event->group_leader_pid = selected->group_leader->pid; + else + event->group_leader_pid = -1; + event->min_flt = selected->min_flt; + event->maj_flt = selected->maj_flt; + event->oom_score_adj = selected->signal->oom_score_adj; + event->start_time = nsec_to_clock_t(selected->real_start_time); + event->rss_in_pages = rss_in_pages; + event->min_score_adj = min_score_adj; + + event_buffer.head = (head + 1) & (MAX_BUFFERED_EVENTS - 1); + + spin_unlock(&lmk_event_lock); + + wake_up_interruptible(&event_wait); +} + +static int lmk_event_show(struct seq_file *s, void *unused) +{ + struct lmk_event *events = (struct lmk_event *) event_buffer.buf; + int head; + int tail; + struct lmk_event *event; + + spin_lock(&lmk_event_lock); + + head = event_buffer.head; + tail = event_buffer.tail; + + if (head == tail) { + spin_unlock(&lmk_event_lock); + return -EAGAIN; + } + + event = &events[tail]; + + seq_printf(s, "%lu %lu %lu %lu %lu %lu %hd %hd %llu\n%s\n", + (unsigned long) event->pid, (unsigned long) event->uid, + (unsigned long) event->group_leader_pid, event->min_flt, + event->maj_flt, event->rss_in_pages, event->oom_score_adj, + event->min_score_adj, event->start_time, event->taskname); + + event_buffer.tail = (tail + 1) & (MAX_BUFFERED_EVENTS - 1); + + spin_unlock(&lmk_event_lock); + return 0; +} + +static unsigned int lmk_event_poll(struct file *file, poll_table *wait) +{ + int ret = 0; + + poll_wait(file, &event_wait, wait); + spin_lock(&lmk_event_lock); + if (event_buffer.head != event_buffer.tail) + ret = POLLIN; + spin_unlock(&lmk_event_lock); + return ret; +} + +static int lmk_event_open(struct inode *inode, struct file *file) +{ + return single_open(file, lmk_event_show, inode->i_private); +} + +static const struct file_operations event_file_ops = { + .open = lmk_event_open, + .poll = lmk_event_poll, + .read = seq_read +}; + +static void lmk_event_init(void) +{ + struct proc_dir_entry *entry; + + event_buffer.head = 0; + event_buffer.tail = 0; + event_buffer.buf = kmalloc( + sizeof(struct lmk_event) * MAX_BUFFERED_EVENTS, GFP_KERNEL); + if (!event_buffer.buf) + return; + entry = proc_create("lowmemorykiller", 0, NULL, &event_file_ops); + if (!entry) + pr_err("error creating kernel lmk event file\n"); +} + static unsigned long lowmem_count(struct shrinker *s, struct shrink_control *sc) { @@ -635,6 +786,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) lowmem_deathpending_timeout = jiffies + HZ; rem += selected_tasksize; rcu_read_unlock(); + handle_lmk_event(selected, min_score_adj); /* give the system time to free up the memory */ msleep_interruptible(20); trace_almk_shrink(selected_tasksize, ret, @@ -662,6 +814,7 @@ static int __init lowmem_init(void) { register_shrinker(&lowmem_shrinker); vmpressure_notifier_register(&lmk_vmpr_nb); + lmk_event_init(); return 0; } device_initcall(lowmem_init); From 0d45bd3ddd85f920ee25f3a762f0cac1011208f9 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Mon, 13 May 2019 14:49:44 +0800 Subject: [PATCH 222/281] driver: can: spi: add mcp25xxfd driver mcp25xxfd is a CAN bus controller with SPI interface, which support CAN FD and CAN classic format CAN frame. Change-Id: I208abd9522e5142219690cdbb9d09d9db65be997 Git-commit: d9a2e2f2eff657bce35bfde8c33a8df52214b256 Git-repo: https://github.com/Bytewerk/QuadCAN-FD.git Signed-off-by: Chaojun Wang --- .../bindings/net/can/microchip,mcp25xxfd.txt | 31 + drivers/net/can/spi/Kconfig | 6 + drivers/net/can/spi/Makefile | 1 + drivers/net/can/spi/mcp25xxfd.c | 4513 +++++++++++++++++ 4 files changed, 4551 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/can/microchip,mcp25xxfd.txt create mode 100644 drivers/net/can/spi/mcp25xxfd.c diff --git a/Documentation/devicetree/bindings/net/can/microchip,mcp25xxfd.txt b/Documentation/devicetree/bindings/net/can/microchip,mcp25xxfd.txt new file mode 100644 index 000000000000..716b0a16ecb2 --- /dev/null +++ b/Documentation/devicetree/bindings/net/can/microchip,mcp25xxfd.txt @@ -0,0 +1,31 @@ +* Microchip MCP2517 stand-alone CAN controller device tree bindings + +Required properties: + - compatible: Should be one of the following: + - "microchip,mcp2517fd" for MCP2517fd. + - reg: SPI chip select. + - clocks: The clock feeding the CAN controller. + - interrupt-parent: The parent interrupt controller. + - interrupts: Should contain IRQ line for the CAN controller. + - gpio-controller: Marks the device node as a GPIO controller + +Optional properties: + - vdd-supply: Regulator that powers the CAN controller. + - xceiver-supply: Regulator that powers the CAN transceiver. + - microchip,clock_out_div = <0|1|2|4|10>: Clock output pin divider + 0 = Start of Frame output + default: 10 + - microchip,clock_div2: bool: divide the internal clock by 2 + - gpio_opendrain: bool: enable open-drain for all pins (except cantx) + +Example: + can0: can@1 { + compatible = "microchip,mcp2515"; + reg = <1>; + clocks = <&clk24m>; + interrupt-parent = <&gpio4>; + interrupts = <13 0x8>; + vdd-supply = <®5v0>; + xceiver-supply = <®5v0>; + gpio-controller; + }; diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig index 2e33f3744fca..6a5476aa7214 100644 --- a/drivers/net/can/spi/Kconfig +++ b/drivers/net/can/spi/Kconfig @@ -13,4 +13,10 @@ config QTI_CAN depends on SPI ---help--- Unified driver for QTI CAN controllers. + +config CAN_MCP25XXFD + tristate "Microchip MCP25xxFD SPI CAN controllers" + depends on HAS_DMA + ---help--- + Driver for the Microchip MCP25XXFD SPI FD-CAN controller family. endmenu diff --git a/drivers/net/can/spi/Makefile b/drivers/net/can/spi/Makefile index 64ba86116691..bbb43438dbca 100644 --- a/drivers/net/can/spi/Makefile +++ b/drivers/net/can/spi/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_CAN_MCP251X) += mcp251x.o obj-$(CONFIG_QTI_CAN) += qti-can.o +obj-$(CONFIG_CAN_MCP25XXFD) += mcp25xxfd.o diff --git a/drivers/net/can/spi/mcp25xxfd.c b/drivers/net/can/spi/mcp25xxfd.c new file mode 100644 index 000000000000..12cdf4434d7f --- /dev/null +++ b/drivers/net/can/spi/mcp25xxfd.c @@ -0,0 +1,4513 @@ +/* + * CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface + * + * Copyright 2017 Martin Sperl + * + * SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note + * + * Based on Microchip MCP251x CAN controller driver written by + * David Vrabel, Copyright 2006 Arcom Control Systems Ltd. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "mcp25xxfd" + +/* device description and rational: + * + * the mcp25xxfd is a CanFD controller that also supports can2.0 only + * modes. + * It is connected via spi to the host and requires at minimum a single + * irq line in addition to the SPI lines - it is not mentioned explicitly + * in the documentation but in principle SPI 3-wire should be possible. + * + * The clock connected is typically 4MHz, 20MHz or 40MHz. + * For the 4MHz clock the controller contains 10x PLL circuitry. + * + * The controller itself has 2KB or ECC-SRAM for data. + * It also has 32 FIFOs (of up to 32 CAN-frames). + * There are 4 Fifo types which can get configured: + * * TEF - Transmission Event Fifo - which consumes FIFO 0 + * even if it is not configured + * * Tansmission Queue - for up to 32 Frames. + * this queue reorders CAN frames to get transmitted following the + * typical CAN dominant/recessive rules on the can bus itself. + * This FIFO is optional. + * * TX FIFO: generic TX fifos that can contain arbitrary data + * and which come with a configurable priority for transmission + * It is also possible to have the Controller automatically trigger + * a transfer when a Filter Rule for a RTR frame matches. + * Each of these fifos in principle can get configured for distinct + * dlc sizes (8 thru 64 bytes) + * * RX FIFO: generic RX fifo which is filled via filter-rules. + * Each of these fifos in principle can get configured for distinct + * dlc sizes (8 thru 64 bytes) + * Unfortunately there is no filter rule that would allow triggering + * on different frame sizes, so for all practical purposes the + * RX fifos have to be of the same size (unless one wants to experience + * lost data). + * When a Can Frame is transmitted fromthe TX Queue or an individual + * TX FIFO then a small TEF Frame can get added to the TEF FIFO queue + * to log the Transmission of the frame - this includes ID, Flags + * (including a custom identifier/index) . + * + * The controller provides an optional free running counter with a divider + * for timestamping of RX frames as well as for TEF entries. + * + * Driver Implementation details and rational: + * * The whole driver has been designed to give best performance + * and as little packet loss as possible with 1MHZ Can frames with DLC=0 + * on small/slow devices like the Raspberry Pi 1 + * * This means that some optimizations for full duplex communication + * have been implemented to avoid CPU introduced latencies + * (especially for spi_write_then_read cases) - this only applies to + * 4 wire SPI busses. + * * Due to the fact that the TXQ does reorder Can-Frames we do not make + * use of it to avoid unexpected behaviour (say when running a + * firmware upgrade via Can) + * * this means we use individual TX-fifos with a given priority and + * we have to wait until all the TX fifos have been transmitted before + * we can restart the networking queue to avoid reordering the frames on + * the Can bus itself. + * Still we can transmit a transmit only Duty-cycle of 66% to 90% on the + * Can bus (at 1MHz). + * The scaling factors here are: + * * Can bus speed - lower Speeds increase Duty-cycle + * * SPI Clock Rate - higher speeds increase duty-cycle + * * CPU speed + SPI implementation - reduces latencies between transfers + * * There is a module parameter that allows the modification of the + * number of tx_fifos, which is by default 7. + * * The driver offers some module parameters that allow to control the use + * of some optimizations (prefer reading more data than necessary instead + * of multiple SPI transfers - the idea here is that this way we may + * allow the SPI-controller to use DMA instead of programmed IO to + * limit latencies/number of interrupts) + * When we have to read multiple RX frames in CanFD mode: + * * we allow reading all 64 bytes of payload even if DLC <=8 + * this mode is used in Can2.0 only mode by default and can not get + * disabled (SRAM Reads have to be a multiple of 4 bytes anyway) + * * Releasing/freeing the RX queue requires writing of 1 byte per fifo. + * unfortunately these 32-bit registers are not ajacent to each other, + * so that for 2 consecutive RX Frames instead of writing 1 byte per + * fifo (with protocol overhead of 2 bytes - so a total of 6 bytes in + * 2 transfers) we transmit 13 bytes (with a protocol overhead of 2 - + * so a total of 15 bytes) + * This optimization is only enabled by a module parameter. + * * we use TEF + time stamping to record the transmitted frames + * including their timestamp - we use this to order TX and RX frames + * when submitting them to the network stack. + * * due to the inability to "filter" based on DLC sizes we have to use + * a common FIFO size. This is 8 bytes for Can2.0 and 64 bytes for CanFD. + * * the driver tries to detect the Controller only by reading registers, + * but there are circumstances (e.g. after a crashed driver) where we + * have to "blindly" configure the clock rate to get the controller to + * respond correctly. + * * There is one situation where the controller will require a full POR + * (total power off) to recover from a bad Clock configuration. + * This happens when the wrong clock is configured in the device tree + * (say 4MHz are configured, while 20 or 40MHz are used) + * in such a situation the driver tries to enable the PLL, which will + * never synchronize and the controller becomes unresponsive to further + * spi requests until a POR. + */ + +#define MCP25XXFD_OST_DELAY_MS 3 +#define MCP25XXFD_MIN_CLOCK_FREQUENCY 1000000 +#define MCP25XXFD_MAX_CLOCK_FREQUENCY 40000000 +#define MCP25XXFD_PLL_MULTIPLIER 10 +#define MCP25XXFD_AUTO_PLL_MAX_CLOCK_FREQUENCY \ + (MCP25XXFD_MAX_CLOCK_FREQUENCY / MCP25XXFD_PLL_MULTIPLIER) +#define MCP25XXFD_SCLK_DIVIDER 2 + +#define MCP25XXFD_OSC_POLLING_JIFFIES (HZ / 2) + +#define TX_ECHO_SKB_MAX 32 + +#define INSTRUCTION_RESET 0x0000 +#define INSTRUCTION_READ 0x3000 +#define INSTRUCTION_WRITE 0x2000 +#define INSTRUCTION_READ_CRC 0xB000 +#define INSTRUCTION_WRITE_CRC 0xA000 +#define INSTRUCTION_WRITE_SAVE 0xC000 + +#define ADDRESS_MASK 0x0fff + +#define MCP25XXFD_SFR_BASE(x) (0xE00 + (x)) +#define MCP25XXFD_OSC MCP25XXFD_SFR_BASE(0x00) +# define MCP25XXFD_OSC_PLLEN BIT(0) +# define MCP25XXFD_OSC_OSCDIS BIT(2) +# define MCP25XXFD_OSC_SCLKDIV BIT(4) +# define MCP25XXFD_OSC_CLKODIV_BITS 2 +# define MCP25XXFD_OSC_CLKODIV_SHIFT 5 +# define MCP25XXFD_OSC_CLKODIV_MASK \ + GENMASK(MCP25XXFD_OSC_CLKODIV_SHIFT \ + + MCP25XXFD_OSC_CLKODIV_BITS - 1, \ + MCP25XXFD_OSC_CLKODIV_SHIFT) +# define MCP25XXFD_OSC_CLKODIV_10 3 +# define MCP25XXFD_OSC_CLKODIV_4 2 +# define MCP25XXFD_OSC_CLKODIV_2 1 +# define MCP25XXFD_OSC_CLKODIV_1 0 +# define MCP25XXFD_OSC_PLLRDY BIT(8) +# define MCP25XXFD_OSC_OSCRDY BIT(10) +# define MCP25XXFD_OSC_SCLKRDY BIT(12) +#define MCP25XXFD_IOCON MCP25XXFD_SFR_BASE(0x04) +# define MCP25XXFD_IOCON_TRIS0 BIT(0) +# define MCP25XXFD_IOCON_TRIS1 BIT(1) +# define MCP25XXFD_IOCON_XSTBYEN BIT(6) +# define MCP25XXFD_IOCON_LAT0 BIT(8) +# define MCP25XXFD_IOCON_LAT1 BIT(9) +# define MCP25XXFD_IOCON_GPIO0 BIT(16) +# define MCP25XXFD_IOCON_GPIO1 BIT(17) +# define MCP25XXFD_IOCON_PM0 BIT(24) +# define MCP25XXFD_IOCON_PM1 BIT(25) +# define MCP25XXFD_IOCON_TXCANOD BIT(28) +# define MCP25XXFD_IOCON_SOF BIT(29) +# define MCP25XXFD_IOCON_INTOD BIT(29) +#define MCP25XXFD_CRC MCP25XXFD_SFR_BASE(0x08) +# define MCP25XXFD_CRC_MASK GENMASK(15, 0) +# define MCP25XXFD_CRC_CRCERRIE BIT(16) +# define MCP25XXFD_CRC_FERRIE BIT(17) +# define MCP25XXFD_CRC_CRCERRIF BIT(24) +# define MCP25XXFD_CRC_FERRIF BIT(25) +#define MCP25XXFD_ECCCON MCP25XXFD_SFR_BASE(0x0C) +# define MCP25XXFD_ECCCON_ECCEN BIT(0) +# define MCP25XXFD_ECCCON_SECIE BIT(1) +# define MCP25XXFD_ECCCON_DEDIE BIT(2) +# define MCP25XXFD_ECCCON_PARITY_BITS 6 +# define MCP25XXFD_ECCCON_PARITY_SHIFT 8 +# define MCP25XXFD_ECCCON_PARITY_MASK \ + GENMASK(MCP25XXFD_ECCCON_PARITY_SHIFT \ + + MCP25XXFD_ECCCON_PARITY_BITS - 1, \ + MCP25XXFD_ECCCON_PARITY_SHIFT) +#define MCP25XXFD_ECCSTAT MCP25XXFD_SFR_BASE(0x10) +# define MCP25XXFD_ECCSTAT_SECIF BIT(1) +# define MCP25XXFD_ECCSTAT_DEDIF BIT(2) +# define MCP25XXFD_ECCSTAT_ERRADDR_SHIFT 8 +# define MCP25XXFD_ECCSTAT_ERRADDR_MASK \ + GENMASK(MCP25XXFD_ECCSTAT_ERRADDR_SHIFT + 11, \ + MCP25XXFD_ECCSTAT_ERRADDR_SHIFT) + +#define CAN_SFR_BASE(x) (0x000 + (x)) +#define CAN_CON CAN_SFR_BASE(0x00) +# define CAN_CON_DNCNT_BITS 5 +# define CAN_CON_DNCNT_SHIFT 0 +# define CAN_CON_DNCNT_MASK \ + GENMASK(CAN_CON_DNCNT_SHIFT + CAN_CON_DNCNT_BITS - 1, \ + CAN_CON_DNCNT_SHIFT) +# define CAN_CON_ISOCRCEN BIT(5) +# define CAN_CON_PXEDIS BIT(6) +# define CAN_CON_WAKFIL BIT(8) +# define CAN_CON_WFT_BITS 2 +# define CAN_CON_WFT_SHIFT 9 +# define CAN_CON_WFT_MASK \ + GENMASK(CAN_CON_WFT_SHIFT + CAN_CON_WFT_BITS - 1, \ + CAN_CON_WFT_SHIFT) +# define CAN_CON_BUSY BIT(11) +# define CAN_CON_BRSDIS BIT(12) +# define CAN_CON_RTXAT BIT(16) +# define CAN_CON_ESIGM BIT(17) +# define CAN_CON_SERR2LOM BIT(18) +# define CAN_CON_STEF BIT(19) +# define CAN_CON_TXQEN BIT(20) +# define CAN_CON_OPMODE_BITS 3 +# define CAN_CON_OPMOD_SHIFT 21 +# define CAN_CON_OPMOD_MASK \ + GENMASK(CAN_CON_OPMOD_SHIFT + CAN_CON_OPMODE_BITS - 1, \ + CAN_CON_OPMOD_SHIFT) +# define CAN_CON_REQOP_BITS 3 +# define CAN_CON_REQOP_SHIFT 24 +# define CAN_CON_REQOP_MASK \ + GENMASK(CAN_CON_REQOP_SHIFT + CAN_CON_REQOP_BITS - 1, \ + CAN_CON_REQOP_SHIFT) +# define CAN_CON_MODE_MIXED 0 +# define CAN_CON_MODE_SLEEP 1 +# define CAN_CON_MODE_INTERNAL_LOOPBACK 2 +# define CAN_CON_MODE_LISTENONLY 3 +# define CAN_CON_MODE_CONFIG 4 +# define CAN_CON_MODE_EXTERNAL_LOOPBACK 5 +# define CAN_CON_MODE_CAN2_0 6 +# define CAN_CON_MODE_RESTRICTED 7 +# define CAN_CON_ABAT BIT(27) +# define CAN_CON_TXBWS_BITS 3 +# define CAN_CON_TXBWS_SHIFT 28 +# define CAN_CON_TXBWS_MASK \ + GENMASK(CAN_CON_TXBWS_SHIFT + CAN_CON_TXBWS_BITS - 1, \ + CAN_CON_TXBWS_SHIFT) +# define CAN_CON_DEFAULT \ + (CAN_CON_ISOCRCEN | \ + CAN_CON_PXEDIS | \ + CAN_CON_WAKFIL | \ + (3 << CAN_CON_WFT_SHIFT) | \ + CAN_CON_STEF | \ + CAN_CON_TXQEN | \ + (CAN_CON_MODE_CONFIG << CAN_CON_OPMOD_SHIFT) | \ + (CAN_CON_MODE_CONFIG << CAN_CON_REQOP_SHIFT)) +# define CAN_CON_DEFAULT_MASK \ + (CAN_CON_DNCNT_MASK | \ + CAN_CON_ISOCRCEN | \ + CAN_CON_PXEDIS | \ + CAN_CON_WAKFIL | \ + CAN_CON_WFT_MASK | \ + CAN_CON_BRSDIS | \ + CAN_CON_RTXAT | \ + CAN_CON_ESIGM | \ + CAN_CON_SERR2LOM | \ + CAN_CON_STEF | \ + CAN_CON_TXQEN | \ + CAN_CON_OPMOD_MASK | \ + CAN_CON_REQOP_MASK | \ + CAN_CON_ABAT | \ + CAN_CON_TXBWS_MASK) +#define CAN_NBTCFG CAN_SFR_BASE(0x04) +# define CAN_NBTCFG_SJW_BITS 7 +# define CAN_NBTCFG_SJW_SHIFT 0 +# define CAN_NBTCFG_SJW_MASK \ + GENMASK(CAN_NBTCFG_SJW_SHIFT + CAN_NBTCFG_SJW_BITS - 1, \ + CAN_NBTCFG_SJW_SHIFT) +# define CAN_NBTCFG_TSEG2_BITS 7 +# define CAN_NBTCFG_TSEG2_SHIFT 8 +# define CAN_NBTCFG_TSEG2_MASK \ + GENMASK(CAN_NBTCFG_TSEG2_SHIFT + CAN_NBTCFG_TSEG2_BITS - 1, \ + CAN_NBTCFG_TSEG2_SHIFT) +# define CAN_NBTCFG_TSEG1_BITS 8 +# define CAN_NBTCFG_TSEG1_SHIFT 16 +# define CAN_NBTCFG_TSEG1_MASK \ + GENMASK(CAN_NBTCFG_TSEG1_SHIFT + CAN_NBTCFG_TSEG1_BITS - 1, \ + CAN_NBTCFG_TSEG1_SHIFT) +# define CAN_NBTCFG_BRP_BITS 8 +# define CAN_NBTCFG_BRP_SHIFT 24 +# define CAN_NBTCFG_BRP_MASK \ + GENMASK(CAN_NBTCFG_BRP_SHIFT + CAN_NBTCFG_BRP_BITS - 1, \ + CAN_NBTCFG_BRP_SHIFT) +#define CAN_DBTCFG CAN_SFR_BASE(0x08) +# define CAN_DBTCFG_SJW_BITS 4 +# define CAN_DBTCFG_SJW_SHIFT 0 +# define CAN_DBTCFG_SJW_MASK \ + GENMASK(CAN_DBTCFG_SJW_SHIFT + CAN_DBTCFG_SJW_BITS - 1, \ + CAN_DBTCFG_SJW_SHIFT) +# define CAN_DBTCFG_TSEG2_BITS 4 +# define CAN_DBTCFG_TSEG2_SHIFT 8 +# define CAN_DBTCFG_TSEG2_MASK \ + GENMASK(CAN_DBTCFG_TSEG2_SHIFT + CAN_DBTCFG_TSEG2_BITS - 1, \ + CAN_DBTCFG_TSEG2_SHIFT) +# define CAN_DBTCFG_TSEG1_BITS 5 +# define CAN_DBTCFG_TSEG1_SHIFT 16 +# define CAN_DBTCFG_TSEG1_MASK \ + GENMASK(CAN_DBTCFG_TSEG1_SHIFT + CAN_DBTCFG_TSEG1_BITS - 1, \ + CAN_DBTCFG_TSEG1_SHIFT) +# define CAN_DBTCFG_BRP_BITS 8 +# define CAN_DBTCFG_BRP_SHIFT 24 +# define CAN_DBTCFG_BRP_MASK \ + GENMASK(CAN_DBTCFG_BRP_SHIFT + CAN_DBTCFG_BRP_BITS - 1, \ + CAN_DBTCFG_BRP_SHIFT) +#define CAN_TDC CAN_SFR_BASE(0x0C) +# define CAN_TDC_TDCV_BITS 5 +# define CAN_TDC_TDCV_SHIFT 0 +# define CAN_TDC_TDCV_MASK \ + GENMASK(CAN_TDC_TDCV_SHIFT + CAN_TDC_TDCV_BITS - 1, \ + CAN_TDC_TDCV_SHIFT) +# define CAN_TDC_TDCO_BITS 5 +# define CAN_TDC_TDCO_SHIFT 8 +# define CAN_TDC_TDCO_MASK \ + GENMASK(CAN_TDC_TDCO_SHIFT + CAN_TDC_TDCO_BITS - 1, \ + CAN_TDC_TDCO_SHIFT) +# define CAN_TDC_TDCMOD_BITS 2 +# define CAN_TDC_TDCMOD_SHIFT 16 +# define CAN_TDC_TDCMOD_MASK \ + GENMASK(CAN_TDC_TDCMOD_SHIFT + CAN_TDC_TDCMOD_BITS - 1, \ + CAN_TDC_TDCMOD_SHIFT) +# define CAN_TDC_TDCMOD_DISABLED 0 +# define CAN_TDC_TDCMOD_MANUAL 1 +# define CAN_TDC_TDCMOD_AUTO 2 +# define CAN_TDC_SID11EN BIT(24) +# define CAN_TDC_EDGFLTEN BIT(25) +#define CAN_TBC CAN_SFR_BASE(0x10) +#define CAN_TSCON CAN_SFR_BASE(0x14) +# define CAN_TSCON_TBCPRE_BITS 10 +# define CAN_TSCON_TBCPRE_SHIFT 0 +# define CAN_TSCON_TBCPRE_MASK \ + GENMASK(CAN_TSCON_TBCPRE_SHIFT + CAN_TSCON_TBCPRE_BITS - 1, \ + CAN_TSCON_TBCPRE_SHIFT) +# define CAN_TSCON_TBCEN BIT(16) +# define CAN_TSCON_TSEOF BIT(17) +# define CAN_TSCON_TSRES BIT(18) +#define CAN_VEC CAN_SFR_BASE(0x18) +# define CAN_VEC_ICODE_BITS 7 +# define CAN_VEC_ICODE_SHIFT 0 +# define CAN_VEC_ICODE_MASK \ + GENMASK(CAN_VEC_ICODE_SHIFT + CAN_VEC_ICODE_BITS - 1, \ + CAN_VEC_ICODE_SHIFT) +# define CAN_VEC_FILHIT_BITS 5 +# define CAN_VEC_FILHIT_SHIFT 8 +# define CAN_VEC_FILHIT_MASK \ + GENMASK(CAN_VEC_FILHIT_SHIFT + CAN_VEC_FILHIT_BITS - 1, \ + CAN_VEC_FILHIT_SHIFT) +# define CAN_VEC_TXCODE_BITS 7 +# define CAN_VEC_TXCODE_SHIFT 16 +# define CAN_VEC_TXCODE_MASK \ + GENMASK(CAN_VEC_TXCODE_SHIFT + CAN_VEC_TXCODE_BITS - 1, \ + CAN_VEC_TXCODE_SHIFT) +# define CAN_VEC_RXCODE_BITS 7 +# define CAN_VEC_RXCODE_SHIFT 24 +# define CAN_VEC_RXCODE_MASK \ + GENMASK(CAN_VEC_RXCODE_SHIFT + CAN_VEC_RXCODE_BITS - 1, \ + CAN_VEC_RXCODE_SHIFT) +#define CAN_INT CAN_SFR_BASE(0x1C) +# define CAN_INT_IF_SHIFT 0 +# define CAN_INT_TXIF BIT(0) +# define CAN_INT_RXIF BIT(1) +# define CAN_INT_TBCIF BIT(2) +# define CAN_INT_MODIF BIT(3) +# define CAN_INT_TEFIF BIT(4) +# define CAN_INT_ECCIF BIT(8) +# define CAN_INT_SPICRCIF BIT(9) +# define CAN_INT_TXATIF BIT(10) +# define CAN_INT_RXOVIF BIT(11) +# define CAN_INT_SERRIF BIT(12) +# define CAN_INT_CERRIF BIT(13) +# define CAN_INT_WAKIF BIT(14) +# define CAN_INT_IVMIF BIT(15) +# define CAN_INT_IF_MASK \ + (CAN_INT_TXIF | \ + CAN_INT_RXIF | \ + CAN_INT_TBCIF | \ + CAN_INT_MODIF | \ + CAN_INT_TEFIF | \ + CAN_INT_ECCIF | \ + CAN_INT_SPICRCIF | \ + CAN_INT_TXATIF | \ + CAN_INT_RXOVIF | \ + CAN_INT_CERRIF | \ + CAN_INT_SERRIF | \ + CAN_INT_WAKEIF | \ + CAN_INT_IVMIF) +# define CAN_INT_IE_SHIFT 16 +# define CAN_INT_TXIE (CAN_INT_TXIF << CAN_INT_IE_SHIFT) +# define CAN_INT_RXIE (CAN_INT_RXIF << CAN_INT_IE_SHIFT) +# define CAN_INT_TBCIE (CAN_INT_TBCIF << CAN_INT_IE_SHIFT) +# define CAN_INT_MODIE (CAN_INT_MODIF << CAN_INT_IE_SHIFT) +# define CAN_INT_TEFIE (CAN_INT_TEFIF << CAN_INT_IE_SHIFT) +# define CAN_INT_ECCIE (CAN_INT_ECCIF << CAN_INT_IE_SHIFT) +# define CAN_INT_SPICRCIE \ + (CAN_INT_SPICRCIF << CAN_INT_IE_SHIFT) +# define CAN_INT_TXATIE (CAN_INT_TXATIF << CAN_INT_IE_SHIFT) +# define CAN_INT_RXOVIE (CAN_INT_RXOVIF << CAN_INT_IE_SHIFT) +# define CAN_INT_CERRIE (CAN_INT_CERRIF << CAN_INT_IE_SHIFT) +# define CAN_INT_SERRIE (CAN_INT_SERRIF << CAN_INT_IE_SHIFT) +# define CAN_INT_WAKIE (CAN_INT_WAKIF << CAN_INT_IE_SHIFT) +# define CAN_INT_IVMIE (CAN_INT_IVMIF << CAN_INT_IE_SHIFT) +# define CAN_INT_IE_MASK \ + (CAN_INT_TXIE | \ + CAN_INT_RXIE | \ + CAN_INT_TBCIE | \ + CAN_INT_MODIE | \ + CAN_INT_TEFIE | \ + CAN_INT_ECCIE | \ + CAN_INT_SPICRCIE | \ + CAN_INT_TXATIE | \ + CAN_INT_RXOVIE | \ + CAN_INT_CERRIE | \ + CAN_INT_SERRIE | \ + CAN_INT_WAKEIE | \ + CAN_INT_IVMIE) +#define CAN_RXIF CAN_SFR_BASE(0x20) +#define CAN_TXIF CAN_SFR_BASE(0x24) +#define CAN_RXOVIF CAN_SFR_BASE(0x28) +#define CAN_TXATIF CAN_SFR_BASE(0x2C) +#define CAN_TXREQ CAN_SFR_BASE(0x30) +#define CAN_TREC CAN_SFR_BASE(0x34) +# define CAN_TREC_REC_BITS 8 +# define CAN_TREC_REC_SHIFT 0 +# define CAN_TREC_REC_MASK \ + GENMASK(CAN_TREC_REC_SHIFT + CAN_TREC_REC_BITS - 1, \ + CAN_TREC_REC_SHIFT) +# define CAN_TREC_TEC_BITS 8 +# define CAN_TREC_TEC_SHIFT 8 +# define CAN_TREC_TEC_MASK \ + GENMASK(CAN_TREC_TEC_SHIFT + CAN_TREC_TEC_BITS - 1, \ + CAN_TREC_TEC_SHIFT) +# define CAN_TREC_EWARN BIT(16) +# define CAN_TREC_RXWARN BIT(17) +# define CAN_TREC_TXWARN BIT(18) +# define CAN_TREC_RXBP BIT(19) +# define CAN_TREC_TXBP BIT(20) +# define CAN_TREC_TXBO BIT(21) +#define CAN_BDIAG0 CAN_SFR_BASE(0x38) +# define CAN_BDIAG0_NRERRCNT_BITS 8 +# define CAN_BDIAG0_NRERRCNT_SHIFT 0 +# define CAN_BDIAG0_NRERRCNT_MASK \ + GENMASK(CAN_BDIAG0_NRERRCNT_SHIFT + CAN_BDIAG0_NRERRCNT_BITS - 1, \ + CAN_BDIAG0_NRERRCNT_SHIFT) +# define CAN_BDIAG0_NTERRCNT_BITS 8 +# define CAN_BDIAG0_NTERRCNT_SHIFT 8 +# define CAN_BDIAG0_NTERRCNT_MASK \ + GENMASK(CAN_BDIAG0_NTERRCNT_SHIFT + CAN_BDIAG0_NTERRCNT_BITS - 1, \ + CAN_BDIAG0_NTERRCNT_SHIFT) +# define CAN_BDIAG0_DRERRCNT_BITS 8 +# define CAN_BDIAG0_DRERRCNT_SHIFT 16 +# define CAN_BDIAG0_DRERRCNT_MASK \ + GENMASK(CAN_BDIAG0_DRERRCNT_SHIFT + CAN_BDIAG0_DRERRCNT_BITS - 1, \ + CAN_BDIAG0_DRERRCNT_SHIFT) +# define CAN_BDIAG0_DTERRCNT_BITS 8 +# define CAN_BDIAG0_DTERRCNT_SHIFT 24 +# define CAN_BDIAG0_DTERRCNT_MASK \ + GENMASK(CAN_BDIAG0_DTERRCNT_SHIFT + CAN_BDIAG0_DTERRCNT_BITS - 1, \ + CAN_BDIAG0_DTERRCNT_SHIFT) +#define CAN_BDIAG1 CAN_SFR_BASE(0x3C) +# define CAN_BDIAG1_EFMSGCNT_BITS 16 +# define CAN_BDIAG1_EFMSGCNT_SHIFT 0 +# define CAN_BDIAG1_EFMSGCNT_MASK \ + GENMASK(CAN_BDIAG1_EFMSGCNT_SHIFT + CAN_BDIAG1_EFMSGCNT_BITS - 1, \ + CAN_BDIAG1_EFMSGCNT_SHIFT) +# define CAN_BDIAG1_NBIT0ERR BIT(16) +# define CAN_BDIAG1_NBIT1ERR BIT(17) +# define CAN_BDIAG1_NACKERR BIT(18) +# define CAN_BDIAG1_NSTUFERR BIT(19) +# define CAN_BDIAG1_NFORMERR BIT(20) +# define CAN_BDIAG1_NCRCERR BIT(21) +# define CAN_BDIAG1_TXBOERR BIT(23) +# define CAN_BDIAG1_DBIT0ERR BIT(24) +# define CAN_BDIAG1_DBIT1ERR BIT(25) +# define CAN_BDIAG1_DFORMERR BIT(27) +# define CAN_BDIAG1_DSTUFERR BIT(28) +# define CAN_BDIAG1_DCRCERR BIT(29) +# define CAN_BDIAG1_ESI BIT(30) +# define CAN_BDIAG1_DLCMM BIT(31) +#define CAN_TEFCON CAN_SFR_BASE(0x40) +# define CAN_TEFCON_TEFNEIE BIT(0) +# define CAN_TEFCON_TEFHIE BIT(1) +# define CAN_TEFCON_TEFFIE BIT(2) +# define CAN_TEFCON_TEFOVIE BIT(3) +# define CAN_TEFCON_TEFTSEN BIT(5) +# define CAN_TEFCON_UINC BIT(8) +# define CAN_TEFCON_FRESET BIT(10) +# define CAN_TEFCON_FSIZE_BITS 5 +# define CAN_TEFCON_FSIZE_SHIFT 24 +# define CAN_TEFCON_FSIZE_MASK \ + GENMASK(CAN_TEFCON_FSIZE_SHIFT + CAN_TEFCON_FSIZE_BITS - 1, \ + CAN_TEFCON_FSIZE_SHIFT) +#define CAN_TEFSTA CAN_SFR_BASE(0x44) +# define CAN_TEFSTA_TEFNEIF BIT(0) +# define CAN_TEFSTA_TEFHIF BIT(1) +# define CAN_TEFSTA_TEFFIF BIT(2) +# define CAN_TEFSTA_TEVOVIF BIT(3) +#define CAN_TEFUA CAN_SFR_BASE(0x48) +#define CAN_RESERVED CAN_SFR_BASE(0x4C) +#define CAN_TXQCON CAN_SFR_BASE(0x50) +# define CAN_TXQCON_TXQNIE BIT(0) +# define CAN_TXQCON_TXQEIE BIT(2) +# define CAN_TXQCON_TXATIE BIT(4) +# define CAN_TXQCON_TXEN BIT(7) +# define CAN_TXQCON_UINC BIT(8) +# define CAN_TXQCON_TXREQ BIT(9) +# define CAN_TXQCON_FRESET BIT(10) +# define CAN_TXQCON_TXPRI_BITS 5 +# define CAN_TXQCON_TXPRI_SHIFT 16 +# define CAN_TXQCON_TXPRI_MASK \ + GENMASK(CAN_TXQCON_TXPRI_SHIFT + CAN_TXQCON_TXPRI_BITS - 1, \ + CAN_TXQCON_TXPRI_SHIFT) +# define CAN_TXQCON_TXAT_BITS 2 +# define CAN_TXQCON_TXAT_SHIFT 21 +# define CAN_TXQCON_TXAT_MASK \ + GENMASK(CAN_TXQCON_TXAT_SHIFT + CAN_TXQCON_TXAT_BITS - 1, \ + CAN_TXQCON_TXAT_SHIFT) +# define CAN_TXQCON_FSIZE_BITS 5 +# define CAN_TXQCON_FSIZE_SHIFT 24 +# define CAN_TXQCON_FSIZE_MASK \ + GENMASK(CAN_TXQCON_FSIZE_SHIFT + CAN_TXQCON_FSIZE_BITS - 1, \ + CAN_TXQCON_FSIZE_SHIFT) +# define CAN_TXQCON_PLSIZE_BITS 3 +# define CAN_TXQCON_PLSIZE_SHIFT 29 +# define CAN_TXQCON_PLSIZE_MASK \ + GENMASK(CAN_TXQCON_PLSIZE_SHIFT + CAN_TXQCON_PLSIZE_BITS - 1, \ + CAN_TXQCON_PLSIZE_SHIFT) +# define CAN_TXQCON_PLSIZE_8 0 +# define CAN_TXQCON_PLSIZE_12 1 +# define CAN_TXQCON_PLSIZE_16 2 +# define CAN_TXQCON_PLSIZE_20 3 +# define CAN_TXQCON_PLSIZE_24 4 +# define CAN_TXQCON_PLSIZE_32 5 +# define CAN_TXQCON_PLSIZE_48 6 +# define CAN_TXQCON_PLSIZE_64 7 + +#define CAN_TXQSTA CAN_SFR_BASE(0x54) +# define CAN_TXQSTA_TXQNIF BIT(0) +# define CAN_TXQSTA_TXQEIF BIT(2) +# define CAN_TXQSTA_TXATIF BIT(4) +# define CAN_TXQSTA_TXERR BIT(5) +# define CAN_TXQSTA_TXLARB BIT(6) +# define CAN_TXQSTA_TXABT BIT(7) +# define CAN_TXQSTA_TXQCI_BITS 5 +# define CAN_TXQSTA_TXQCI_SHIFT 8 +# define CAN_TXQSTA_TXQCI_MASK \ + GENMASK(CAN_TXQSTA_TXQCI_SHIFT + CAN_TXQSTA_TXQCI_BITS - 1, \ + CAN_TXQSTA_TXQCI_SHIFT) + +#define CAN_TXQUA CAN_SFR_BASE(0x58) +#define CAN_FIFOCON(x) CAN_SFR_BASE(0x5C + 12 * ((x) - 1)) +#define CAN_FIFOCON_TFNRFNIE BIT(0) +#define CAN_FIFOCON_TFHRFHIE BIT(1) +#define CAN_FIFOCON_TFERFFIE BIT(2) +#define CAN_FIFOCON_RXOVIE BIT(3) +#define CAN_FIFOCON_TXATIE BIT(4) +#define CAN_FIFOCON_RXTSEN BIT(5) +#define CAN_FIFOCON_RTREN BIT(6) +#define CAN_FIFOCON_TXEN BIT(7) +#define CAN_FIFOCON_UINC BIT(8) +#define CAN_FIFOCON_TXREQ BIT(9) +#define CAN_FIFOCON_FRESET BIT(10) +# define CAN_FIFOCON_TXPRI_BITS 5 +# define CAN_FIFOCON_TXPRI_SHIFT 16 +# define CAN_FIFOCON_TXPRI_MASK \ + GENMASK(CAN_FIFOCON_TXPRI_SHIFT + CAN_FIFOCON_TXPRI_BITS - 1, \ + CAN_FIFOCON_TXPRI_SHIFT) +# define CAN_FIFOCON_TXAT_BITS 2 +# define CAN_FIFOCON_TXAT_SHIFT 21 +# define CAN_FIFOCON_TXAT_MASK \ + GENMASK(CAN_FIFOCON_TXAT_SHIFT + CAN_FIFOCON_TXAT_BITS - 1, \ + CAN_FIFOCON_TXAT_SHIFT) +# define CAN_FIFOCON_TXAT_ONE_SHOT 0 +# define CAN_FIFOCON_TXAT_THREE_SHOT 1 +# define CAN_FIFOCON_TXAT_UNLIMITED 2 +# define CAN_FIFOCON_FSIZE_BITS 5 +# define CAN_FIFOCON_FSIZE_SHIFT 24 +# define CAN_FIFOCON_FSIZE_MASK \ + GENMASK(CAN_FIFOCON_FSIZE_SHIFT + CAN_FIFOCON_FSIZE_BITS - 1, \ + CAN_FIFOCON_FSIZE_SHIFT) +# define CAN_FIFOCON_PLSIZE_BITS 3 +# define CAN_FIFOCON_PLSIZE_SHIFT 29 +# define CAN_FIFOCON_PLSIZE_MASK \ + GENMASK(CAN_FIFOCON_PLSIZE_SHIFT + CAN_FIFOCON_PLSIZE_BITS - 1, \ + CAN_FIFOCON_PLSIZE_SHIFT) +#define CAN_FIFOSTA(x) CAN_SFR_BASE(0x60 + 12 * ((x) - 1)) +# define CAN_FIFOSTA_TFNRFNIF BIT(0) +# define CAN_FIFOSTA_TFHRFHIF BIT(1) +# define CAN_FIFOSTA_TFERFFIF BIT(2) +# define CAN_FIFOSTA_RXOVIF BIT(3) +# define CAN_FIFOSTA_TXATIF BIT(4) +# define CAN_FIFOSTA_TXERR BIT(5) +# define CAN_FIFOSTA_TXLARB BIT(6) +# define CAN_FIFOSTA_TXABT BIT(7) +# define CAN_FIFOSTA_FIFOCI_BITS 5 +# define CAN_FIFOSTA_FIFOCI_SHIFT 8 +# define CAN_FIFOSTA_FIFOCI_MASK \ + GENMASK(CAN_FIFOSTA_FIFOCI_SHIFT + CAN_FIFOSTA_FIFOCI_BITS - 1, \ + CAN_FIFOSTA_FIFOCI_SHIFT) +#define CAN_FIFOUA(x) CAN_SFR_BASE(0x64 + 12 * ((x) - 1)) +#define CAN_FLTCON(x) CAN_SFR_BASE(0x1D0 + ((x) & 0x1c)) +# define CAN_FILCON_SHIFT(x) (((x) & 3) * 8) +# define CAN_FILCON_BITS(x) CAN_FILCON_BITS_ +# define CAN_FILCON_BITS_ 4 + /* avoid macro reuse warning, so do not use GENMASK as above */ +# define CAN_FILCON_MASK(x) \ + (GENMASK(CAN_FILCON_BITS_ - 1, 0) << CAN_FILCON_SHIFT(x)) +# define CAN_FIFOCON_FLTEN(x) BIT(7 + CAN_FILCON_SHIFT(x)) +#define CAN_FLTOBJ(x) CAN_SFR_BASE(0x1F0 + 8 * (x)) +# define CAN_FILOBJ_SID_BITS 11 +# define CAN_FILOBJ_SID_SHIFT 0 +# define CAN_FILOBJ_SID_MASK \ + GENMASK(CAN_FILOBJ_SID_SHIFT + CAN_FILOBJ_SID_BITS - 1, \ + CAN_FILOBJ_SID_SHIFT) +# define CAN_FILOBJ_EID_BITS 18 +# define CAN_FILOBJ_EID_SHIFT 12 +# define CAN_FILOBJ_EID_MASK \ + GENMASK(CAN_FILOBJ_EID_SHIFT + CAN_FILOBJ_EID_BITS - 1, \ + CAN_FILOBJ_EID_SHIFT) +# define CAN_FILOBJ_SID11 BIT(29) +# define CAN_FILOBJ_EXIDE BIT(30) +#define CAN_FLTMASK(x) CAN_SFR_BASE(0x1F4 + 8 * (x)) +# define CAN_FILMASK_MSID_BITS 11 +# define CAN_FILMASK_MSID_SHIFT 0 +# define CAN_FILMASK_MSID_MASK \ + GENMASK(CAN_FILMASK_MSID_SHIFT + CAN_FILMASK_MSID_BITS - 1, \ + CAN_FILMASK_MSID_SHIFT) +# define CAN_FILMASK_MEID_BITS 18 +# define CAN_FILMASK_MEID_SHIFT 12 +# define CAN_FILMASK_MEID_MASK \ + GENMASK(CAN_FILMASK_MEID_SHIFT + CAN_FILMASK_MEID_BITS - 1, \ + CAN_FILMASK_MEID_SHIFT) +# define CAN_FILMASK_MSID11 BIT(29) +# define CAN_FILMASK_MIDE BIT(30) + +#define CAN_OBJ_ID_SID_BITS 11 +#define CAN_OBJ_ID_SID_SHIFT 0 +#define CAN_OBJ_ID_SID_MASK \ + GENMASK(CAN_OBJ_ID_SID_SHIFT + CAN_OBJ_ID_SID_BITS - 1, \ + CAN_OBJ_ID_SID_SHIFT) +#define CAN_OBJ_ID_EID_BITS 18 +#define CAN_OBJ_ID_EID_SHIFT 11 +#define CAN_OBJ_ID_EID_MASK \ + GENMASK(CAN_OBJ_ID_EID_SHIFT + CAN_OBJ_ID_EID_BITS - 1, \ + CAN_OBJ_ID_EID_SHIFT) +#define CAN_OBJ_ID_SID_BIT11 BIT(29) + +#define CAN_OBJ_FLAGS_DLC_BITS 4 +#define CAN_OBJ_FLAGS_DLC_SHIFT 0 +#define CAN_OBJ_FLAGS_DLC_MASK \ + GENMASK(CAN_OBJ_FLAGS_DLC_SHIFT + CAN_OBJ_FLAGS_DLC_BITS - 1, \ + CAN_OBJ_FLAGS_DLC_SHIFT) +#define CAN_OBJ_FLAGS_IDE BIT(4) +#define CAN_OBJ_FLAGS_RTR BIT(5) +#define CAN_OBJ_FLAGS_BRS BIT(6) +#define CAN_OBJ_FLAGS_FDF BIT(7) +#define CAN_OBJ_FLAGS_ESI BIT(8) +#define CAN_OBJ_FLAGS_SEQ_BITS 7 +#define CAN_OBJ_FLAGS_SEQ_SHIFT 9 +#define CAN_OBJ_FLAGS_SEQ_MASK \ + GENMASK(CAN_OBJ_FLAGS_SEQ_SHIFT + CAN_OBJ_FLAGS_SEQ_BITS - 1, \ + CAN_OBJ_FLAGS_SEQ_SHIFT) +#define CAN_OBJ_FLAGS_FILHIT_BITS 11 +#define CAN_OBJ_FLAGS_FILHIT_SHIFT 5 +#define CAN_OBJ_FLAGS_FILHIT_MASK \ + GENMASK(CAN_FLAGS_FILHIT_SHIFT + CAN_FLAGS_FILHIT_BITS - 1, \ + CAN_FLAGS_FILHIT_SHIFT) + +#define CAN_OBJ_FLAGS_CUSTOM_ISTEF BIT(31) + +#define MCP25XXFD_BUFFER_TXRX_SIZE 2048 + +static const char * const mcp25xxfd_mode_names[] = { + [CAN_CON_MODE_MIXED] = "can2.0+canfd", + [CAN_CON_MODE_SLEEP] = "sleep", + [CAN_CON_MODE_INTERNAL_LOOPBACK] = "internal loopback", + [CAN_CON_MODE_LISTENONLY] = "listen only", + [CAN_CON_MODE_CONFIG] = "config", + [CAN_CON_MODE_EXTERNAL_LOOPBACK] = "external loopback", + [CAN_CON_MODE_CAN2_0] = "can2.0", + [CAN_CON_MODE_RESTRICTED] = "restricted" +}; + +struct mcp25xxfd_obj { + u32 id; + u32 flags; +}; + +struct mcp25xxfd_obj_tx { + struct mcp25xxfd_obj header; + u32 data[]; +}; + +static void mcp25xxfd_obj_to_le(struct mcp25xxfd_obj *obj) +{ + obj->id = cpu_to_le32(obj->id); + obj->flags = cpu_to_le32(obj->flags); +} + +struct mcp25xxfd_obj_ts { + u32 id; + u32 flags; + u32 ts; +}; + +struct mcp25xxfd_obj_tef { + struct mcp25xxfd_obj_ts header; +}; + +struct mcp25xxfd_obj_rx { + struct mcp25xxfd_obj_ts header; + u8 data[]; +}; + +static void mcp25xxfd_obj_ts_from_le(struct mcp25xxfd_obj_ts *obj) +{ + obj->id = le32_to_cpu(obj->id); + obj->flags = le32_to_cpu(obj->flags); + obj->ts = le32_to_cpu(obj->ts); +} + +#define FIFO_DATA(x) (0x400 + (x)) +#define FIFO_DATA_SIZE 0x800 + +static const struct can_bittiming_const mcp25xxfd_nominal_bittiming_const = { + .name = DEVICE_NAME, + .tseg1_min = 2, + .tseg1_max = BIT(CAN_NBTCFG_TSEG1_BITS), + .tseg2_min = 1, + .tseg2_max = BIT(CAN_NBTCFG_TSEG2_BITS), + .sjw_max = BIT(CAN_NBTCFG_SJW_BITS), + .brp_min = 1, + .brp_max = BIT(CAN_NBTCFG_BRP_BITS), + .brp_inc = 1, +}; + +static const struct can_bittiming_const mcp25xxfd_data_bittiming_const = { + .name = DEVICE_NAME, + .tseg1_min = 1, + .tseg1_max = BIT(CAN_DBTCFG_TSEG1_BITS), + .tseg2_min = 1, + .tseg2_max = BIT(CAN_DBTCFG_TSEG2_BITS), + .sjw_max = BIT(CAN_DBTCFG_SJW_BITS), + .brp_min = 1, + .brp_max = BIT(CAN_DBTCFG_BRP_BITS), + .brp_inc = 1, +}; + +enum mcp25xxfd_model { + CAN_MCP2517FD = 0x2517, +}; + +enum mcp25xxfd_gpio_mode { + gpio_mode_int = 0, + gpio_mode_standby = MCP25XXFD_IOCON_XSTBYEN, + gpio_mode_out_low = MCP25XXFD_IOCON_PM0, + gpio_mode_out_high = MCP25XXFD_IOCON_PM0 | MCP25XXFD_IOCON_LAT0, + gpio_mode_in = MCP25XXFD_IOCON_PM0 | MCP25XXFD_IOCON_TRIS0 +}; + +struct mcp25xxfd_trigger_tx_message { + struct spi_message msg; + struct spi_transfer fill_xfer; + struct spi_transfer trigger_xfer; + int fifo; + char fill_cmd[2]; + char fill_obj[sizeof(struct mcp25xxfd_obj_tx)]; + char fill_data[64]; + char trigger_cmd[2]; + char trigger_data; +}; + +struct mcp25xxfd_read_fifo_info { + struct mcp25xxfd_obj_ts *rxb[32]; + int rx_count; +}; + +struct mcp25xxfd_priv { + struct can_priv can; + struct net_device *net; + struct spi_device *spi; + struct regulator *power; + struct regulator *transceiver; + struct clk *clk; + + struct mutex clk_user_lock; /* lock for enabling/disabling the clock */ + int clk_user_mask; +#define MCP25XXFD_CLK_USER_CAN BIT(0) +#define MCP25XXFD_CLK_USER_GPIO0 BIT(1) +#define MCP25XXFD_CLK_USER_GPIO1 BIT(2) + + struct dentry *debugfs_dir; + +#ifdef CONFIG_GPIOLIB + struct gpio_chip gpio; +#endif + + /* the actual model of the mcp25xxfd */ + enum mcp25xxfd_model model; + + struct { + /* clock configuration */ + bool clock_pll; + bool clock_div2; + int clock_odiv; + + /* GPIO configuration */ + bool gpio_opendrain; + } config; + + /* the distinct spi_speeds to use for spi communication */ + u32 spi_setup_speed_hz; + u32 spi_speed_hz; + + /* fifo info */ + struct { + /* define payload size and mode */ + int payload_size; + u32 payload_mode; + + /* TEF addresses - start, end and current */ + u32 tef_fifos; + u32 tef_address_start; + u32 tef_address_end; + u32 tef_address; + + /* address in mcp25xxfd-Fifo RAM of each fifo */ + u32 fifo_address[32]; + + /* infos on tx-fifos */ + u32 tx_fifos; + u32 tx_fifo_start; + u32 tx_fifo_mask; /* bitmask of which fifo is a tx fifo */ + u32 tx_submitted_mask; + u32 tx_pending_mask; + u32 tx_pending_mask_in_irq; + u32 tx_processed_mask; + + /* info on rx_fifos */ + u32 rx_fifos; + u32 rx_fifo_depth; + u32 rx_fifo_start; + u32 rx_fifo_mask; /* bitmask of which fifo is a rx fifo */ + + /* memory image of FIFO RAM on mcp25xxfd */ + u8 fifo_data[MCP25XXFD_BUFFER_TXRX_SIZE]; + + } fifos; + + /* structure with active fifos that need to get fed to the system */ + struct mcp25xxfd_read_fifo_info queued_fifos; + + /* statistics */ + struct { + /* number of calls to the irq handler */ + u64 irq_calls; + /* number of loops inside the irq handler */ + u64 irq_loops; + + /* interrupt handler state and statistics */ + u32 irq_state; +#define IRQ_STATE_NEVER_RUN 0 +#define IRQ_STATE_RUNNING 1 +#define IRQ_STATE_HANDLED 2 + /* stats on number of rx overflows */ + u64 rx_overflow; + /* statistics of FIFO usage */ + u64 fifo_usage[32]; + + /* message abort counter */ + u64 rx_mab; + u64 tx_mab; + + /* message counter fd */ + u64 rx_fd_count; + u64 tx_fd_count; + + /* message counter fd bit rate switch */ + u64 rx_brs_count; + u64 tx_brs_count; + + /* interrupt counter */ + u64 int_ivm_count; + u64 int_wake_count; + u64 int_cerr_count; + u64 int_serr_count; + u64 int_rxov_count; + u64 int_txat_count; + u64 int_spicrc_count; + u64 int_ecc_count; + u64 int_tef_count; + u64 int_mod_count; + u64 int_tbc_count; + u64 int_rx_count; + u64 int_tx_count; + + /* dlc statistics */ + u64 rx_dlc_usage[16]; + u64 tx_dlc_usage[16]; + } stats; + + /* the current status of the mcp25xxfd */ + struct { + u32 intf; + /* ASSERT(CAN_INT + 4 == CAN_RXIF) */ + u32 rxif; + /* ASSERT(CAN_RXIF + 4 == CAN_TXIF) */ + u32 txif; + /* ASSERT(CAN_TXIF + 4 == CAN_RXOVIF) */ + u32 rxovif; + /* ASSERT(CAN_RXOVIF + 4 == CAN_TXATIF) */ + u32 txatif; + /* ASSERT(CAN_TXATIF + 4 == CAN_TXREQ) */ + u32 txreq; + /* ASSERT(CAN_TXREQ + 4 == CAN_TREC) */ + u32 trec; + /* ASSERT(CAN_TREC + 4 == CAN_BDIAG0) */ + u32 bdiag0; + /* ASSERT(CAN_BDIAG0 + 4 == CAN_BDIAG1) */ + u32 bdiag1; + } status; + + /* configuration registers */ + struct { + u32 osc; + u32 ecccon; + u32 con; + u32 iocon; + u32 tdc; + u32 tscon; + u32 tefcon; + u32 nbtcfg; + u32 dbtcfg; + } regs; + + /* interrupt handler signaling */ + int force_quit; + int after_suspend; +#define AFTER_SUSPEND_UP 1 +#define AFTER_SUSPEND_DOWN 2 +#define AFTER_SUSPEND_POWER 4 +#define AFTER_SUSPEND_RESTART 8 + int restart_tx; + + /* interrupt flags during irq handling */ + u32 bdiag1_clear_mask; + u32 bdiag1_clear_value; + + /* composit error id and dataduring irq handling */ + u32 can_err_id; + u32 can_err_data[8]; + + /* the current mode */ + u32 active_can_mode; + u32 new_state; + + /* status of the tx_queue enabled/disabled */ + u32 tx_queue_status; +#define TX_QUEUE_STATUS_INIT 0 +#define TX_QUEUE_STATUS_RUNNING 1 +#define TX_QUEUE_STATUS_NEEDS_START 2 +#define TX_QUEUE_STATUS_STOPPED 3 + + /* spi-tx/rx buffers for efficient transfers + * used during setup and irq + */ + struct mutex spi_rxtx_lock; + u8 spi_tx[MCP25XXFD_BUFFER_TXRX_SIZE]; + u8 spi_rx[MCP25XXFD_BUFFER_TXRX_SIZE]; + + /* structure for transmit fifo spi_messages */ + struct mcp25xxfd_trigger_tx_message *spi_transmit_fifos; +}; + +/* module parameters */ +bool use_bulk_release_fifos; +module_param(use_bulk_release_fifos, bool, 0664); +MODULE_PARM_DESC(use_bulk_release_fifos, + "Use code that favours longer spi transfers over multiple transfers"); +bool use_complete_fdfifo_read; +module_param(use_complete_fdfifo_read, bool, 0664); +MODULE_PARM_DESC(use_complete_fdfifo_read, + "Use code that favours longer spi transfers over multiple transfers for fd can"); +unsigned int tx_fifos; +module_param(tx_fifos, uint, 0664); +MODULE_PARM_DESC(tx_fifos, + "Number of tx-fifos to configure\n"); +unsigned int bw_sharing_log2bits; +module_param(bw_sharing_log2bits, uint, 0664); +MODULE_PARM_DESC(bw_sharing_log2bits, + "Delay between 2 transmissions in number of arbitration bit times\n"); +bool three_shot; +module_param(three_shot, bool, 0664); +MODULE_PARM_DESC(three_shot, + "Use 3 shots when one-shot is requested"); + +/* spi sync helper */ + +/* wrapper arround spi_sync, that sets speed_hz */ +static int mcp25xxfd_sync_transfer(struct spi_device *spi, + struct spi_transfer *xfer, + unsigned int xfers, + int speed_hz) +{ + int i; + + for (i = 0; i < xfers; i++) + xfer[i].speed_hz = speed_hz; + + return spi_sync_transfer(spi, xfer, xfers); +} + +/* an optimization of spi_write_then_read that merges the transfers */ +static int mcp25xxfd_write_then_read(struct spi_device *spi, + const void *tx_buf, + unsigned int tx_len, + void *rx_buf, + unsigned int rx_len, + int speed_hz) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct spi_transfer xfer[2]; + u8 single_reg_data_tx[6]; + u8 single_reg_data_rx[6]; + int ret; + + memset(xfer, 0, sizeof(xfer)); + + /* when using a halfduplex controller or to big for buffer */ + if ((spi->master->flags & SPI_MASTER_HALF_DUPLEX) || + (tx_len + rx_len > sizeof(priv->spi_tx))) { + xfer[0].tx_buf = tx_buf; + xfer[0].len = tx_len; + + xfer[1].rx_buf = rx_buf; + xfer[1].len = rx_len; + + return mcp25xxfd_sync_transfer(spi, xfer, 2, speed_hz); + } + + /* full duplex optimization */ + xfer[0].len = tx_len + rx_len; + if (xfer[0].len > sizeof(single_reg_data_tx)) { + mutex_lock(&priv->spi_rxtx_lock); + xfer[0].tx_buf = priv->spi_tx; + xfer[0].rx_buf = priv->spi_rx; + } else { + xfer[0].tx_buf = single_reg_data_tx; + xfer[0].rx_buf = single_reg_data_rx; + } + + /* copy and clean */ + memcpy((u8 *)xfer[0].tx_buf, tx_buf, tx_len); + memset((u8 *)xfer[0].tx_buf + tx_len, 0, rx_len); + + ret = mcp25xxfd_sync_transfer(spi, xfer, 1, speed_hz); + if (!ret) + memcpy(rx_buf, xfer[0].rx_buf + tx_len, rx_len); + + if (xfer[0].len > sizeof(single_reg_data_tx)) + mutex_unlock(&priv->spi_rxtx_lock); + + return ret; +} + +/* simple spi_write wrapper with speed_hz */ +static int mcp25xxfd_write(struct spi_device *spi, + const void *tx_buf, + unsigned int tx_len, + int speed_hz) +{ + struct spi_transfer xfer; + + memset(&xfer, 0, sizeof(xfer)); + xfer.tx_buf = tx_buf; + xfer.len = tx_len; + + return mcp25xxfd_sync_transfer(spi, &xfer, 1, speed_hz); +} + +/* spi_sync wrapper similar to spi_write_then_read that optimizes transfers */ +static int mcp25xxfd_write_then_write(struct spi_device *spi, + const void *tx_buf, + unsigned int tx_len, + const void *tx2_buf, + unsigned int tx2_len, + int speed_hz) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct spi_transfer xfer; + u8 single_reg_data[6]; + int ret; + + if (tx_len + tx2_len > MCP25XXFD_BUFFER_TXRX_SIZE) + return -EINVAL; + + memset(&xfer, 0, sizeof(xfer)); + + xfer.len = tx_len + tx2_len; + if (xfer.len > sizeof(single_reg_data)) { + mutex_lock(&priv->spi_rxtx_lock); + xfer.tx_buf = priv->spi_tx; + } else { + xfer.tx_buf = single_reg_data; + } + + memcpy((u8 *)xfer.tx_buf, tx_buf, tx_len); + memcpy((u8 *)xfer.tx_buf + tx_len, tx2_buf, tx2_len); + + ret = mcp25xxfd_sync_transfer(spi, &xfer, 1, speed_hz); + + if (xfer.len > sizeof(single_reg_data)) + mutex_unlock(&priv->spi_rxtx_lock); + + return ret; +} + +/* mcp25xxfd spi command/protocol helper */ + +static void mcp25xxfd_calc_cmd_addr(u16 cmd, u16 addr, u8 *data) +{ + cmd = cmd | (addr & ADDRESS_MASK); + + data[0] = (cmd >> 8) & 0xff; + data[1] = (cmd >> 0) & 0xff; +} + +static int mcp25xxfd_cmd_reset(struct spi_device *spi, u32 speed_hz) +{ + u8 cmd[2]; + + mcp25xxfd_calc_cmd_addr(INSTRUCTION_RESET, 0, cmd); + + /* write the reset command */ + return mcp25xxfd_write(spi, cmd, 2, speed_hz); +} + +/* read multiple bytes, transform some registers */ +static int mcp25xxfd_cmd_readn(struct spi_device *spi, u32 reg, + void *data, int n, u32 speed_hz) +{ + u8 cmd[2]; + int ret; + + mcp25xxfd_calc_cmd_addr(INSTRUCTION_READ, reg, cmd); + + ret = mcp25xxfd_write_then_read(spi, &cmd, 2, data, n, speed_hz); + if (ret) + return ret; + + return 0; +} + +static int mcp25xxfd_convert_to_cpu(u32 *data, int n) +{ + int i; + + for (i = 0; i < n; i++) + data[i] = le32_to_cpu(data[i]); + + return 0; +} + +static int mcp25xxfd_first_byte(u32 mask) +{ + return (mask & 0x0000ffff) ? + ((mask & 0x000000ff) ? 0 : 1) : + ((mask & 0x00ff0000) ? 2 : 3); +} + +static int mcp25xxfd_last_byte(u32 mask) +{ + return (mask & 0xffff0000) ? + ((mask & 0xff000000) ? 3 : 2) : + ((mask & 0x0000ff00) ? 1 : 0); +} + +/* read a register, but we are only interrested in a few bytes */ +static int mcp25xxfd_cmd_read_mask(struct spi_device *spi, u32 reg, + u32 *data, u32 mask, u32 speed_hz) +{ + int first_byte, last_byte, len_byte; + int ret; + + /* check that at least one bit is set */ + if (!mask) + return -EINVAL; + + /* calculate first and last byte used */ + first_byte = mcp25xxfd_first_byte(mask); + last_byte = mcp25xxfd_last_byte(mask); + len_byte = last_byte - first_byte + 1; + + /* do a partial read */ + *data = 0; + ret = mcp25xxfd_cmd_readn(spi, reg + first_byte, + ((void *)data + first_byte), len_byte, + speed_hz); + if (ret) + return ret; + + return mcp25xxfd_convert_to_cpu(data, 1); +} + +static int mcp25xxfd_cmd_read(struct spi_device *spi, u32 reg, u32 *data, + u32 speed_hz) +{ + return mcp25xxfd_cmd_read_mask(spi, reg, data, -1, speed_hz); +} + +/* read a register, but we are only interrested in a few bytes */ +static int mcp25xxfd_cmd_write_mask(struct spi_device *spi, u32 reg, + u32 data, u32 mask, u32 speed_hz) +{ + int first_byte, last_byte, len_byte; + u8 cmd[2]; + + /* check that at least one bit is set */ + if (!mask) + return -EINVAL; + + /* calculate first and last byte used */ + first_byte = mcp25xxfd_first_byte(mask); + last_byte = mcp25xxfd_last_byte(mask); + len_byte = last_byte - first_byte + 1; + + /* prepare buffer */ + mcp25xxfd_calc_cmd_addr(INSTRUCTION_WRITE, reg + first_byte, cmd); + data = cpu_to_le32(data); + + return mcp25xxfd_write_then_write(spi, + cmd, sizeof(cmd), + ((void *)&data + first_byte), + len_byte, + speed_hz); +} + +static int mcp25xxfd_cmd_write(struct spi_device *spi, u32 reg, u32 data, + u32 speed_hz) +{ + return mcp25xxfd_cmd_write_mask(spi, reg, data, -1, speed_hz); +} + +static int mcp25xxfd_cmd_writen(struct spi_device *spi, u32 reg, + void *data, int n, u32 speed_hz) +{ + u8 cmd[2]; + int ret; + + mcp25xxfd_calc_cmd_addr(INSTRUCTION_WRITE, reg, cmd); + + ret = mcp25xxfd_write_then_write(spi, &cmd, 2, data, n, speed_hz); + if (ret) + return ret; + + return 0; +} + +static int mcp25xxfd_clean_sram(struct spi_device *spi, u32 speed_hz) +{ + u8 buffer[256]; + int i; + int ret; + + memset(buffer, 0, sizeof(buffer)); + + for (i = 0; i < FIFO_DATA_SIZE; i += sizeof(buffer)) { + ret = mcp25xxfd_cmd_writen(spi, FIFO_DATA(i), + buffer, sizeof(buffer), + speed_hz); + if (ret) + return ret; + } + + return 0; +} + +/* mcp25xxfd opmode helper functions */ + +static int mcp25xxfd_get_opmode(struct spi_device *spi, + int *mode, + int speed_hz) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int ret; + + /* read the mode */ + ret = mcp25xxfd_cmd_read_mask(spi, + CAN_CON, + &priv->regs.con, + CAN_CON_OPMOD_MASK, + speed_hz); + if (ret) + return ret; + /* calculate the mode */ + *mode = (priv->regs.con & CAN_CON_OPMOD_MASK) >> + CAN_CON_OPMOD_SHIFT; + + /* and assign to active mode as well */ + priv->active_can_mode = *mode; + + return 0; +} + +static int mcp25xxfd_set_opmode(struct spi_device *spi, int mode, + int speed_hz) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 val = priv->regs.con & ~CAN_CON_REQOP_MASK; + + /* regs.con also contains the effective register */ + priv->regs.con = val | + (mode << CAN_CON_REQOP_SHIFT) | + (mode << CAN_CON_OPMOD_SHIFT); + priv->active_can_mode = mode; + + /* if the opmode is sleep then the oscilator will be disabled + * and also not ready + */ + if (mode == CAN_CON_MODE_SLEEP) { + priv->regs.osc &= ~(MCP25XXFD_OSC_OSCRDY | + MCP25XXFD_OSC_PLLRDY | + MCP25XXFD_OSC_SCLKRDY); + priv->regs.osc |= MCP25XXFD_OSC_OSCDIS; + } + + /* but only write the relevant section */ + return mcp25xxfd_cmd_write_mask(spi, CAN_CON, + priv->regs.con, + CAN_CON_REQOP_MASK, + speed_hz); +} + +static int mcp25xxfd_set_normal_opmode(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int mode; + + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) + mode = CAN_CON_MODE_EXTERNAL_LOOPBACK; + else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) + mode = CAN_CON_MODE_LISTENONLY; + else if (priv->can.ctrlmode & CAN_CTRLMODE_FD) + mode = CAN_CON_MODE_MIXED; + else + mode = CAN_CON_MODE_CAN2_0; + + return mcp25xxfd_set_opmode(spi, mode, priv->spi_setup_speed_hz); +} + +/* clock helper */ +static int mcp25xxfd_wake_from_sleep(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 waitfor = MCP25XXFD_OSC_OSCRDY; + u32 mask = waitfor | MCP25XXFD_OSC_OSCDIS; + unsigned long timeout; + int ret; + + /* write clock with OSCDIS cleared*/ + priv->regs.osc &= ~MCP25XXFD_OSC_OSCDIS; + ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_OSC, + priv->regs.osc, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* wait for synced pll/osc/sclk */ + timeout = jiffies + MCP25XXFD_OSC_POLLING_JIFFIES; + while (time_before_eq(jiffies, timeout)) { + ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_OSC, + &priv->regs.osc, + priv->spi_setup_speed_hz); + if (ret) + return ret; + if ((priv->regs.osc & mask) == waitfor) { + priv->active_can_mode = CAN_CON_MODE_CONFIG; + return 0; + } + /* wait some time */ + msleep(100); + } + + dev_err(&spi->dev, + "Clock did not enable within the timeout period\n"); + return -ETIMEDOUT; +} + +static int mcp25xxfd_hw_check_clock(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 val; + int ret; + + /* read the osc register and check if it matches + * what we have on record + */ + ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_OSC, + &val, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + if (val == priv->regs.osc) + return 0; + + /* ignore all those ready bits on second try */ + if ((val & 0xff) == (priv->regs.osc & 0xff)) { + dev_info(&spi->dev, + "The oscillator register value %08x does not match what we expect: %08x - it is still reasonable, but please investigate\n", + val, priv->regs.osc); + return 0; + } + + dev_err(&spi->dev, + "The oscillator register value %08x does not match what we expect: %08x\n", + val, priv->regs.osc); + + return -ENODEV; +} + +static int mcp25xxfd_start_clock(struct spi_device *spi, int requestor_mask) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int ret = 0; + + mutex_lock(&priv->clk_user_lock); + + priv->clk_user_mask |= requestor_mask; + + if (priv->clk_user_mask != requestor_mask) + goto out; + + /* check that the controller clock register + * is what it is supposed to be + */ + ret = mcp25xxfd_hw_check_clock(spi); + if (ret) { + dev_err(&spi->dev, + "Controller clock register in unexpected state"); + goto out; + } + + /* and we start the clock */ + if (!IS_ERR(priv->clk)) + ret = clk_prepare_enable(priv->clk); + + /* we wake from sleep */ + if (priv->active_can_mode == CAN_CON_MODE_SLEEP) + ret = mcp25xxfd_wake_from_sleep(spi); + +out: + mutex_unlock(&priv->clk_user_lock); + + return ret; +} + +static int mcp25xxfd_stop_clock(struct spi_device *spi, int requestor_mask) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + mutex_lock(&priv->clk_user_lock); + + priv->clk_user_mask &= ~requestor_mask; + + if (!priv->clk_user_mask) + goto out; + + /* put us into sleep mode */ + mcp25xxfd_set_opmode(spi, CAN_CON_MODE_SLEEP, + priv->spi_setup_speed_hz); + + /* and we stop the clock */ + if (!IS_ERR(priv->clk)) + clk_disable_unprepare(priv->clk); + +out: + mutex_unlock(&priv->clk_user_lock); + + return 0; +} + +/* mcp25xxfd GPIO helper functions */ +#ifdef CONFIG_GPIOLIB + +enum mcp25xxfd_gpio_pins { + MCP25XXFD_GPIO_GPIO0 = 0, + MCP25XXFD_GPIO_GPIO1 = 1, +}; + +static int mcp25xxfd_gpio_request(struct gpio_chip *chip, + unsigned int offset) +{ + struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); + int clock_requestor = offset ? + MCP25XXFD_CLK_USER_GPIO1 : MCP25XXFD_CLK_USER_GPIO0; + + /* only handle gpio 0/1 */ + if (offset > 1) + return -EINVAL; + + mcp25xxfd_start_clock(priv->spi, clock_requestor); + + return 0; +} + +static void mcp25xxfd_gpio_free(struct gpio_chip *chip, + unsigned int offset) +{ + struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); + int clock_requestor = offset ? + MCP25XXFD_CLK_USER_GPIO1 : MCP25XXFD_CLK_USER_GPIO0; + + /* only handle gpio 0/1 */ + if (offset > 1) + return; + + mcp25xxfd_stop_clock(priv->spi, clock_requestor); +} + +static int mcp25xxfd_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); + u32 mask = (offset) ? MCP25XXFD_IOCON_GPIO1 : MCP25XXFD_IOCON_GPIO0; + int ret; + + /* only handle gpio 0/1 */ + if (offset > 1) + return -EINVAL; + + /* read the relevant gpio Latch */ + ret = mcp25xxfd_cmd_read_mask(priv->spi, MCP25XXFD_IOCON, + &priv->regs.iocon, mask, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* return the match */ + return priv->regs.iocon & mask; +} + +static void mcp25xxfd_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); + u32 mask = (offset) ? MCP25XXFD_IOCON_LAT1 : MCP25XXFD_IOCON_LAT0; + + /* only handle gpio 0/1 */ + if (offset > 1) + return; + + /* update in memory representation with the corresponding value */ + if (value) + priv->regs.iocon |= mask; + else + priv->regs.iocon &= ~mask; + + mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_IOCON, + priv->regs.iocon, mask, + priv->spi_setup_speed_hz); +} + +static int mcp25xxfd_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) +{ + struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); + u32 mask_tri = (offset) ? + MCP25XXFD_IOCON_TRIS1 : MCP25XXFD_IOCON_TRIS0; + u32 mask_stby = (offset) ? + 0 : MCP25XXFD_IOCON_XSTBYEN; + u32 mask_pm = (offset) ? + MCP25XXFD_IOCON_PM1 : MCP25XXFD_IOCON_PM0; + + /* only handle gpio 0/1 */ + if (offset > 1) + return -EINVAL; + + /* set the mask */ + priv->regs.iocon |= mask_tri | mask_pm; + + /* clear stby */ + priv->regs.iocon &= ~mask_stby; + + return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_IOCON, + priv->regs.iocon, + mask_tri | mask_stby | mask_pm, + priv->spi_setup_speed_hz); +} + +static int mcp25xxfd_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); + u32 mask_tri = (offset) ? + MCP25XXFD_IOCON_TRIS1 : MCP25XXFD_IOCON_TRIS0; + u32 mask_lat = (offset) ? + MCP25XXFD_IOCON_LAT1 : MCP25XXFD_IOCON_LAT0; + u32 mask_pm = (offset) ? + MCP25XXFD_IOCON_PM1 : MCP25XXFD_IOCON_PM0; + u32 mask_stby = (offset) ? + 0 : MCP25XXFD_IOCON_XSTBYEN; + + /* only handle gpio 0/1 */ + if (offset > 1) + return -EINVAL; + + /* clear the tristate bit and also clear stby */ + priv->regs.iocon &= ~(mask_tri | mask_stby); + + /* set GPIO mode */ + priv->regs.iocon |= mask_pm; + + /* set the value */ + if (value) + priv->regs.iocon |= mask_lat; + else + priv->regs.iocon &= ~mask_lat; + + return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_IOCON, + priv->regs.iocon, + mask_tri | mask_lat | + mask_pm | mask_stby, + priv->spi_setup_speed_hz); +} + +static int mcp25xxfd_gpio_setup(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + /* gpiochip only handles GPIO0 and GPIO1 */ + priv->gpio.owner = THIS_MODULE; + priv->gpio.parent = &spi->dev; + priv->gpio.label = dev_name(&spi->dev); + priv->gpio.direction_input = mcp25xxfd_gpio_direction_input; + priv->gpio.get = mcp25xxfd_gpio_get; + priv->gpio.direction_output = mcp25xxfd_gpio_direction_output; + priv->gpio.set = mcp25xxfd_gpio_set; + priv->gpio.request = mcp25xxfd_gpio_request; + priv->gpio.free = mcp25xxfd_gpio_free; + priv->gpio.base = -1; + priv->gpio.ngpio = 2; + priv->gpio.can_sleep = 1; + + return devm_gpiochip_add_data(&spi->dev, &priv->gpio, priv); +} + +#else + +static int mcp25xxfd_gpio_setup(struct spi_device *spi) +{ + return 0; +} + +#endif + +/* ideally these would be defined in uapi/linux/can.h */ +#define CAN_EFF_SID_SHIFT (CAN_EFF_ID_BITS - CAN_SFF_ID_BITS) +#define CAN_EFF_SID_BITS CAN_SFF_ID_BITS +#define CAN_EFF_SID_MASK \ + GENMASK(CAN_EFF_SID_SHIFT + CAN_EFF_SID_BITS - 1, \ + CAN_EFF_SID_SHIFT) +#define CAN_EFF_EID_SHIFT 0 +#define CAN_EFF_EID_BITS CAN_EFF_SID_SHIFT +#define CAN_EFF_EID_MASK \ + GENMASK(CAN_EFF_EID_SHIFT + CAN_EFF_EID_BITS - 1, \ + CAN_EFF_EID_SHIFT) + +static void mcp25xxfd_canid_to_mcpid(u32 can_id, u32 *id, u32 *flags) +{ + if (can_id & CAN_EFF_FLAG) { + int sid = (can_id & CAN_EFF_SID_MASK) >> CAN_EFF_SID_SHIFT; + int eid = (can_id & CAN_EFF_EID_MASK) >> CAN_EFF_EID_SHIFT; + *id = (eid << CAN_OBJ_ID_EID_SHIFT) | + (sid << CAN_OBJ_ID_SID_SHIFT); + *flags = CAN_OBJ_FLAGS_IDE; + } else { + *id = can_id & CAN_SFF_MASK; + *flags = 0; + } + + *flags |= (can_id & CAN_RTR_FLAG) ? CAN_OBJ_FLAGS_RTR : 0; +} + +static void mcp25xxfd_mcpid_to_canid(u32 mcpid, u32 mcpflags, u32 *id) +{ + u32 sid = (mcpid & CAN_OBJ_ID_SID_MASK) >> CAN_OBJ_ID_SID_SHIFT; + u32 eid = (mcpid & CAN_OBJ_ID_EID_MASK) >> CAN_OBJ_ID_EID_SHIFT; + + if (mcpflags & CAN_OBJ_FLAGS_IDE) { + *id = (eid << CAN_EFF_EID_SHIFT) | + (sid << CAN_EFF_SID_SHIFT) | + CAN_EFF_FLAG; + } else { + *id = sid; + } + + *id |= (mcpflags & CAN_OBJ_FLAGS_RTR) ? CAN_RTR_FLAG : 0; +} + +static void __mcp25xxfd_stop_queue(struct net_device *net, + unsigned int id) +{ + struct mcp25xxfd_priv *priv = netdev_priv(net); + + if (priv->tx_queue_status >= TX_QUEUE_STATUS_STOPPED) + dev_warn(&priv->spi->dev, + "tx-queue is already stopped by: %i\n", + priv->tx_queue_status); + + priv->tx_queue_status = id ? id : TX_QUEUE_STATUS_STOPPED; + netif_stop_queue(priv->net); +} + +/* helper to identify who is stopping the queue by line number */ +#define mcp25xxfd_stop_queue(spi) \ + __mcp25xxfd_stop_queue(spi, __LINE__) + +static void mcp25xxfd_wake_queue(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + /* nothing should be left pending /in flight now... */ + priv->fifos.tx_pending_mask = 0; + priv->fifos.tx_submitted_mask = 0; + priv->fifos.tx_processed_mask = 0; + priv->tx_queue_status = TX_QUEUE_STATUS_RUNNING; + + /* wake queue now */ + netif_wake_queue(priv->net); +} + +/* CAN transmit related*/ + +static void mcp25xxfd_mark_tx_pending(void *context) +{ + struct mcp25xxfd_trigger_tx_message *txm = context; + struct spi_device *spi = txm->msg.spi; + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + /* only here or in the irq handler this value is changed, + * so there is no race condition and it does not require locking + * serialization happens via spi_pump_message + */ + priv->fifos.tx_pending_mask |= BIT(txm->fifo); +} + +static int mcp25xxfd_fill_spi_transmit_fifos(struct mcp25xxfd_priv *priv) +{ + struct mcp25xxfd_trigger_tx_message *txm; + int i, fifo; + const u32 trigger = CAN_FIFOCON_TXREQ | CAN_FIFOCON_UINC; + const int first_byte = mcp25xxfd_first_byte(trigger); + u32 fifo_address; + + priv->spi_transmit_fifos = kcalloc(priv->fifos.tx_fifos, + sizeof(*priv->spi_transmit_fifos), + GFP_KERNEL | GFP_DMA); + if (!priv->spi_transmit_fifos) + return -ENOMEM; + + for (i = 0; i < priv->fifos.tx_fifos; i++) { + fifo = priv->fifos.tx_fifo_start + i; + txm = &priv->spi_transmit_fifos[i]; + fifo_address = priv->fifos.fifo_address[fifo]; + /* prepare the message */ + spi_message_init(&txm->msg); + txm->msg.complete = mcp25xxfd_mark_tx_pending; + txm->msg.context = txm; + txm->fifo = fifo; + /* the payload itself */ + txm->fill_xfer.speed_hz = priv->spi_speed_hz; + txm->fill_xfer.tx_buf = txm->fill_cmd; + txm->fill_xfer.len = 2; + txm->fill_xfer.cs_change = true; + mcp25xxfd_calc_cmd_addr(INSTRUCTION_WRITE, + FIFO_DATA(fifo_address), + txm->fill_cmd); + spi_message_add_tail(&txm->fill_xfer, &txm->msg); + /* the trigger command */ + txm->trigger_xfer.speed_hz = priv->spi_speed_hz; + txm->trigger_xfer.tx_buf = txm->trigger_cmd; + txm->trigger_xfer.len = 3; + mcp25xxfd_calc_cmd_addr(INSTRUCTION_WRITE, + CAN_FIFOCON(fifo) + first_byte, + txm->trigger_cmd); + txm->trigger_data = trigger >> (8 * first_byte); + spi_message_add_tail(&txm->trigger_xfer, &txm->msg); + } + + return 0; +} + +static int mcp25xxfd_transmit_message_common(struct spi_device *spi, + int fifo, + struct mcp25xxfd_obj_tx *obj, + int len, + u8 *data) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct mcp25xxfd_trigger_tx_message *txm = + &priv->spi_transmit_fifos[fifo - priv->fifos.tx_fifo_start]; + int ret; + + /* add fifo as seq */ + obj->header.flags |= fifo << CAN_OBJ_FLAGS_SEQ_SHIFT; + + /* transform to le32 */ + mcp25xxfd_obj_to_le(&obj->header); + + /* fill in details */ + memcpy(txm->fill_obj, obj, sizeof(struct mcp25xxfd_obj_tx)); + memset(txm->fill_data, 0, priv->fifos.payload_size); + memcpy(txm->fill_data, data, len); + + /* transfers to FIFO RAM has to be multiple of 4 */ + txm->fill_xfer.len = + 2 + sizeof(struct mcp25xxfd_obj_tx) + ALIGN(len, 4); + + /* and transmit asyncroniously */ + ret = spi_async(spi, &txm->msg); + if (ret) + return NETDEV_TX_BUSY; + + return NETDEV_TX_OK; +} + +static int mcp25xxfd_transmit_fdmessage(struct spi_device *spi, int fifo, + struct canfd_frame *frame) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct mcp25xxfd_obj_tx obj; + int dlc = can_len2dlc(frame->len); + u32 flags; + + frame->len = can_dlc2len(dlc); + + mcp25xxfd_canid_to_mcpid(frame->can_id, &obj.header.id, &flags); + + flags |= dlc << CAN_OBJ_FLAGS_DLC_SHIFT; + flags |= (frame->can_id & CAN_EFF_FLAG) ? CAN_OBJ_FLAGS_IDE : 0; + flags |= (frame->can_id & CAN_RTR_FLAG) ? CAN_OBJ_FLAGS_RTR : 0; + if (frame->flags & CANFD_BRS) { + flags |= CAN_OBJ_FLAGS_BRS; + priv->stats.tx_brs_count++; + } + flags |= (frame->flags & CANFD_ESI) ? CAN_OBJ_FLAGS_ESI : 0; + flags |= CAN_OBJ_FLAGS_FDF; + + priv->stats.tx_fd_count++; + priv->stats.tx_dlc_usage[dlc]++; + + obj.header.flags = flags; + + return mcp25xxfd_transmit_message_common(spi, fifo, &obj, + frame->len, frame->data); +} + +static int mcp25xxfd_transmit_message(struct spi_device *spi, int fifo, + struct can_frame *frame) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct mcp25xxfd_obj_tx obj; + u32 flags; + + if (frame->can_dlc > 8) + frame->can_dlc = 8; + + priv->stats.tx_dlc_usage[frame->can_dlc]++; + + mcp25xxfd_canid_to_mcpid(frame->can_id, &obj.header.id, &flags); + + flags |= frame->can_dlc << CAN_OBJ_FLAGS_DLC_SHIFT; + flags |= (frame->can_id & CAN_EFF_FLAG) ? CAN_OBJ_FLAGS_IDE : 0; + flags |= (frame->can_id & CAN_RTR_FLAG) ? CAN_OBJ_FLAGS_RTR : 0; + + obj.header.flags = flags; + + return mcp25xxfd_transmit_message_common(spi, fifo, &obj, + frame->can_dlc, frame->data); +} + +static bool mcp25xxfd_is_last_txfifo(struct spi_device *spi, + int fifo) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + return (fifo == + (priv->fifos.tx_fifo_start + priv->fifos.tx_fifos - 1)); +} + +static netdev_tx_t mcp25xxfd_start_xmit(struct sk_buff *skb, + struct net_device *net) +{ + struct mcp25xxfd_priv *priv = netdev_priv(net); + struct spi_device *spi = priv->spi; + u32 pending_mask; + int fifo; + int ret; + + if (can_dropped_invalid_skb(net, skb)) + return NETDEV_TX_OK; + + if (priv->can.state == CAN_STATE_BUS_OFF) { + mcp25xxfd_stop_queue(priv->net); + return NETDEV_TX_BUSY; + } + + /* get effective mask */ + pending_mask = priv->fifos.tx_pending_mask | + priv->fifos.tx_submitted_mask; + + /* decide on fifo to assign */ + if (pending_mask) + fifo = fls(pending_mask); + else + fifo = priv->fifos.tx_fifo_start; + + /* handle error - this should not happen... */ + if (fifo >= priv->fifos.tx_fifo_start + priv->fifos.tx_fifos) { + dev_err(&spi->dev, + "reached tx-fifo %i, which is not valid\n", + fifo); + return NETDEV_TX_BUSY; + } + + /* if we are the last one, then stop the queue */ + if (mcp25xxfd_is_last_txfifo(spi, fifo)) + mcp25xxfd_stop_queue(priv->net); + + /* mark as submitted */ + priv->fifos.tx_submitted_mask |= BIT(fifo); + priv->stats.fifo_usage[fifo]++; + + /* now process it for real */ + if (can_is_canfd_skb(skb)) + ret = mcp25xxfd_transmit_fdmessage(spi, fifo, + (struct canfd_frame *) + skb->data); + else + ret = mcp25xxfd_transmit_message(spi, fifo, + (struct can_frame *) + skb->data); + + /* keep it for reference until the message really got transmitted */ + if (ret == NETDEV_TX_OK) + can_put_echo_skb(skb, priv->net, fifo); + + return ret; +} + +/* CAN RX Related */ + +static int mcp25xxfd_can_transform_rx_fd(struct spi_device *spi, + struct mcp25xxfd_obj_rx *rx) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct canfd_frame *frame; + struct sk_buff *skb; + u32 flags = rx->header.flags; + int dlc; + + /* allocate the skb buffer */ + skb = alloc_canfd_skb(priv->net, &frame); + if (!skb) { + dev_err(&spi->dev, "cannot allocate RX skb\n"); + priv->net->stats.rx_dropped++; + return -ENOMEM; + } + + mcp25xxfd_mcpid_to_canid(rx->header.id, flags, &frame->can_id); + frame->flags |= (flags & CAN_OBJ_FLAGS_BRS) ? CANFD_BRS : 0; + frame->flags |= (flags & CAN_OBJ_FLAGS_ESI) ? CANFD_ESI : 0; + + dlc = (flags & CAN_OBJ_FLAGS_DLC_MASK) >> CAN_OBJ_FLAGS_DLC_SHIFT; + frame->len = can_dlc2len(dlc); + + memcpy(frame->data, rx->data, frame->len); + + priv->stats.rx_fd_count++; + priv->net->stats.rx_packets++; + priv->net->stats.rx_bytes += frame->len; + if (rx->header.flags & CAN_OBJ_FLAGS_BRS) + priv->stats.rx_brs_count++; + priv->stats.rx_dlc_usage[dlc]++; + + can_led_event(priv->net, CAN_LED_EVENT_RX); + + netif_rx_ni(skb); + + return 0; +} + +static int mcp25xxfd_can_transform_rx_normal(struct spi_device *spi, + struct mcp25xxfd_obj_rx *rx) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct sk_buff *skb; + struct can_frame *frame; + u32 flags = rx->header.flags; + int len; + int dlc; + + /* allocate the skb buffer */ + skb = alloc_can_skb(priv->net, &frame); + if (!skb) { + dev_err(&spi->dev, "cannot allocate RX skb\n"); + priv->net->stats.rx_dropped++; + return -ENOMEM; + } + + mcp25xxfd_mcpid_to_canid(rx->header.id, flags, &frame->can_id); + + dlc = (flags & CAN_OBJ_FLAGS_DLC_MASK) >> CAN_OBJ_FLAGS_DLC_SHIFT; + frame->can_dlc = dlc; + + len = can_dlc2len(frame->can_dlc); + + memcpy(frame->data, rx->data, len); + + priv->net->stats.rx_packets++; + priv->net->stats.rx_bytes += len; + priv->stats.rx_dlc_usage[dlc]++; + + can_led_event(priv->net, CAN_LED_EVENT_RX); + + netif_rx_ni(skb); + + return 0; +} + +static int mcp25xxfd_process_queued_rx(struct spi_device *spi, + struct mcp25xxfd_obj_ts *obj) +{ + struct mcp25xxfd_obj_rx *rx = container_of(obj, + struct mcp25xxfd_obj_rx, + header); + + if (obj->flags & CAN_OBJ_FLAGS_FDF) + return mcp25xxfd_can_transform_rx_fd(spi, rx); + else + return mcp25xxfd_can_transform_rx_normal(spi, rx); +} + +static int mcp25xxfd_normal_release_fifos(struct spi_device *spi, + int start, int end) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int ret; + + /* release each fifo in a separate transfer */ + for (; start < end ; start++) { + ret = mcp25xxfd_cmd_write_mask(spi, CAN_FIFOCON(start), + CAN_FIFOCON_UINC, + CAN_FIFOCON_UINC, + priv->spi_speed_hz); + if (ret) + return ret; + } + + return 0; +} + +/* unfortunately the CAN_FIFOCON are not directly consecutive + * so the optimization of "clearing all in one spi_transfer" + * would produce an overhead of 11 unnecessary bytes/fifo + * - transferring 14 (2 cmd + 12 data) bytes + * instead of just 3 (2 + 1). + * On some slower systems this may still be beneficial, + * but it is not good enough for the generic case. + * On a Raspberry Pi CM the timings for clearing 3 fifos + * (at 12.5MHz SPI clock speed) are: + * * normal: + * * 3 spi transfers + * * 9 bytes total + * * 36.74us from first CS low to last CS high + * * individual CS: 9.14us, 5.74us and 5.16us + * * 77.02us from CS up of fifo transfer to last release CS up + * * bulk: + * * 1 spi transfer + * * 27 bytes total + * * 29.06us CS Low + * * 78.28us from CS up of fifo transfer to last release CS up + * this obviously varies with SPI_clock speed + * - the slower the clock the less efficient the optimization. + * similarly the faster the CPU (and bigger the code cache) the + * less effcient the optimization - the above case is border line. + */ + +#define FIFOCON_SPACING (CAN_FIFOCON(1) - CAN_FIFOCON(0)) +#define FIFOCON_SPACINGW (FIFOCON_SPACING / sizeof(u32)) + +static int mcp25xxfd_bulk_release_fifos(struct spi_device *spi, + int start, int end) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int i; + int ret; + + /* calculate start address and length */ + int fifos = end - start; + int first_byte = mcp25xxfd_first_byte(CAN_FIFOCON_UINC); + int addr = CAN_FIFOCON(start); + int len = 1 + (fifos - 1) * FIFOCON_SPACING; + + /* the worsted case buffer */ + u32 buf[32 * FIFOCON_SPACINGW], base; + + base = (priv->fifos.payload_mode << CAN_FIFOCON_PLSIZE_SHIFT) | + ((priv->fifos.rx_fifo_depth - 1) << CAN_FIFOCON_FSIZE_SHIFT) | + CAN_FIFOCON_RXTSEN | /* RX timestamps */ + CAN_FIFOCON_UINC | + CAN_FIFOCON_TFERFFIE | /* FIFO Full */ + CAN_FIFOCON_TFHRFHIE | /* FIFO Half Full*/ + CAN_FIFOCON_TFNRFNIE; /* FIFO not empty */ + + memset(buf, 0, sizeof(buf)); + for (i = 0; i < end - start ; i++) { + if (i == priv->fifos.rx_fifos - 1) + base |= CAN_FIFOCON_RXOVIE; + buf[FIFOCON_SPACINGW * i] = cpu_to_le32(base); + } + + ret = mcp25xxfd_cmd_writen(spi, addr + first_byte, + (u8 *)buf + first_byte, + len, + priv->spi_speed_hz); + if (ret) + return ret; + + return 0; +} + +/* queued FIFO handling for release to system */ + +static void mcp25xxfd_clear_queued_fifos(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + /* prepare rfi - mostly used for sorting */ + priv->queued_fifos.rx_count = 0; +} + +static void mcp25xxfd_addto_queued_fifos(struct spi_device *spi, + struct mcp25xxfd_obj_ts *obj) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct mcp25xxfd_read_fifo_info *rfi = &priv->queued_fifos; + + /* timestamps must ignore the highest byte, so we shift it, + * so that it still compares correctly + */ + obj->ts <<= 8; + + /* add pointer to queued array-list */ + rfi->rxb[rfi->rx_count] = obj; + rfi->rx_count++; +} + +static int mcp25xxfd_process_queued_tef(struct spi_device *spi, + struct mcp25xxfd_obj_ts *obj) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct mcp25xxfd_obj_tef *tef = container_of(obj, + struct mcp25xxfd_obj_tef, + header); + int dlc = (obj->flags & CAN_OBJ_FLAGS_DLC_MASK) + >> CAN_OBJ_FLAGS_DLC_SHIFT; + int fifo = (tef->header.flags & CAN_OBJ_FLAGS_SEQ_MASK) >> + CAN_OBJ_FLAGS_SEQ_SHIFT; + + /* update counters */ + priv->net->stats.tx_packets++; + priv->net->stats.tx_bytes += can_dlc2len(dlc); + if (obj->flags & CAN_OBJ_FLAGS_FDF) + priv->stats.tx_fd_count++; + if (obj->flags & CAN_OBJ_FLAGS_BRS) + priv->stats.tx_brs_count++; + priv->stats.tx_dlc_usage[dlc]++; + + /* release it */ + can_get_echo_skb(priv->net, fifo); + + can_led_event(priv->net, CAN_LED_EVENT_TX); + + return 0; +} + +static int mcp25xxfd_compare_obj_ts(const void *a, const void *b) +{ + const struct mcp25xxfd_obj_ts * const *rxa = a; + const struct mcp25xxfd_obj_ts * const *rxb = b; + /* using signed here to handle rollover correctly */ + s32 ats = (*rxa)->ts; + s32 bts = (*rxb)->ts; + + if (ats < bts) + return -EINVAL; + if (ats > bts) + return 1; + return 0; +} + +static int mcp25xxfd_process_queued_fifos(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct mcp25xxfd_read_fifo_info *rfi = &priv->queued_fifos; + int i; + int ret; + + /* sort the fifos (rx and TEF) by receive timestamp */ + sort(rfi->rxb, rfi->rx_count, sizeof(struct mcp25xxfd_obj_ts *), + mcp25xxfd_compare_obj_ts, NULL); + + /* process the recived fifos */ + for (i = 0; i < rfi->rx_count ; i++) { + if (rfi->rxb[i]->flags & CAN_OBJ_FLAGS_CUSTOM_ISTEF) + ret = mcp25xxfd_process_queued_tef(spi, rfi->rxb[i]); + else + ret = mcp25xxfd_process_queued_rx(spi, rfi->rxb[i]); + if (ret) + return ret; + } + + /* clear queued fifos */ + mcp25xxfd_clear_queued_fifos(spi); + + return 0; +} + +static int mcp25xxfd_transform_rx(struct spi_device *spi, + struct mcp25xxfd_obj_rx *rx) +{ + int dlc; + + /* transform the data to system byte order */ + mcp25xxfd_obj_ts_from_le(&rx->header); + + /* add the object to the list */ + mcp25xxfd_addto_queued_fifos(spi, &rx->header); + + /* calc length and return it */ + dlc = (rx->header.flags & CAN_OBJ_FLAGS_DLC_MASK) + >> CAN_OBJ_FLAGS_DLC_SHIFT; + return can_dlc2len(dlc); +} + +/* read_fifo implementations + * + * read_fifos is a simple implementation, that: + * * loops all fifos + * * read header + some data-bytes (8) + * * read rest of data-bytes bytes + * * release fifo + * for 3 can frames dlc<=8 to read here we have: + * * 6 spi transfers + * * 75 bytes (= 3 * (2 + 12 + 8) bytes + 3 * 3 bytes) + * for 3 canfd frames dlc>8 to read here we have: + * * 9 spi transfers + * * 81 (= 3 * (2 + 12 + 8 + 2) bytes + 3 * 3 bytes) + 3 * extra payload + * this only transfers the required size of bytes on the spi bus. + * + * bulk_read_fifos is an optimization that is most practical for + * Can2.0 busses, but may also be practical for CanFD busses that + * have a high average payload data size. + * + * It will read all of the fifo data in a single spi_transfer: + * * read all fifos in one go (as long as these are ajacent to each other) + * * loop all fifos + * * release fifo + * for 3 can2.0 frames to read here we have: + * * 4 spi transfers + * * 71 bytes (= 2 + 3 * (12 + 8) bytes + 3 * 3 bytes) + * for 3 canfd frames to read here we have: + * * 4 spi transfers + * * 230 bytes (= 2 + 3 * (12 + 64) bytes) + * obviously this reads way too many bytes for framesizes <=32 bytes, + * but it avoids the overhead on the CPU side and may even trigger + * DMA transfers due to the high byte count, which release CPU cycles. + * + * This optimization will also be efficient for cases where a high + * percentage of canFD frames has a dlc-size > 8. + * This mode is used for Can2.0 configured busses. + * + * For now this option can get forced for CanFD via a module parameter. + * In the future there may be some heuristics that could trigger a usage + * of this mode as well in some circumstances. + * + * Note: there is a second optimization for release fifo as well, + * but it is not as efficient as this optimization for the + * non-CanFD case - see mcp25xxfd_bulk_release_fifos + */ + +static int mcp25xxfd_read_fifos(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int fifo_header_size = sizeof(struct mcp25xxfd_obj_rx); + int fifo_min_payload_size = 8; + int fifo_min_size = fifo_header_size + fifo_min_payload_size; + int fifo_max_payload_size = + ((priv->can.ctrlmode & CAN_CTRLMODE_FD) ? 64 : 8); + u32 mask = priv->status.rxif; + struct mcp25xxfd_obj_rx *rx; + int i, len; + int ret; + u32 fifo_address; + u8 *data; + + /* read all the "open" segments in big chunks */ + for (i = priv->fifos.rx_fifo_start + priv->fifos.rx_fifos - 1; + i >= priv->fifos.rx_fifo_start; + i--) { + if (!(mask & BIT(i))) + continue; + /* the fifo to fill */ + rx = (struct mcp25xxfd_obj_rx *) + (priv->fifos.fifo_data + priv->fifos.fifo_address[i]); + /* read the minimal payload */ + fifo_address = priv->fifos.fifo_address[i]; + ret = mcp25xxfd_cmd_readn(spi, + FIFO_DATA(fifo_address), + rx, + fifo_min_size, + priv->spi_speed_hz); + if (ret) + return ret; + /* process fifo stats and get length */ + len = min_t(int, mcp25xxfd_transform_rx(spi, rx), + fifo_max_payload_size); + + /* read extra payload if needed */ + if (len > fifo_min_payload_size) { + data = &rx->data[fifo_min_payload_size]; + ret = mcp25xxfd_cmd_readn(spi, + FIFO_DATA(fifo_address + + fifo_min_size), + data, + len - fifo_min_payload_size, + priv->spi_speed_hz); + if (ret) + return ret; + } + /* release fifo */ + ret = mcp25xxfd_normal_release_fifos(spi, i, i + 1); + if (ret) + return ret; + /* increment fifo_usage */ + priv->stats.fifo_usage[i]++; + } + + return 0; +} + +static int mcp25xxfd_bulk_read_fifo_range(struct spi_device *spi, + int start, int end) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + const int fifo_header_size = sizeof(struct mcp25xxfd_obj_rx); + const int fifo_max_payload_size = priv->fifos.payload_size; + const int fifo_max_size = fifo_header_size + fifo_max_payload_size; + struct mcp25xxfd_obj_rx *rx; + int i; + int ret; + + /* now we got start and end, so read the range */ + ret = mcp25xxfd_cmd_readn(spi, + FIFO_DATA(priv->fifos.fifo_address[start]), + priv->fifos.fifo_data + + priv->fifos.fifo_address[start], + (end - start) * fifo_max_size, + priv->spi_speed_hz); + if (ret) + return ret; + + /* clear all the fifos in range */ + if (use_bulk_release_fifos) + ret = mcp25xxfd_bulk_release_fifos(spi, start, end); + else + ret = mcp25xxfd_normal_release_fifos(spi, start, end); + if (ret) + return ret; + + /* preprocess data */ + for (i = start; i < end ; i++) { + /* store the fifo to process */ + rx = (struct mcp25xxfd_obj_rx *) + (priv->fifos.fifo_data + priv->fifos.fifo_address[i]); + /* process fifo stats */ + mcp25xxfd_transform_rx(spi, rx); + /* increment usage */ + priv->stats.fifo_usage[i]++; + } + + return 0; +} + +static int mcp25xxfd_bulk_read_fifos(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 mask = priv->status.rxif; + int i, start, end; + int ret; + + /* find blocks of set bits top down */ + for (i = priv->fifos.rx_fifo_start + priv->fifos.rx_fifos - 1; + mask && (i >= priv->fifos.rx_fifo_start); + i--) { + /* if the bit is 0 then continue loop to find a 1 */ + if ((mask & BIT(i)) == 0) + continue; + + /* so we found a non-0 bit - this is start and end */ + start = i; + end = i; + + /* find the first bit set */ + for (; mask & BIT(i); i--) { + mask &= ~BIT(i); + start = i; + } + + /* now process that range */ + ret = mcp25xxfd_bulk_read_fifo_range(spi, start, end + 1); + if (ret) + return ret; + } + + return 0; +} + +static int mcp25xxfd_can_ist_handle_rxif(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 mask = priv->status.rxif; + int ret; + + if (!mask) + return 0; + + /* read all the fifos - for non-fd case use bulk read optimization */ + if (((priv->can.ctrlmode & CAN_CTRLMODE_FD) == 0) || + use_complete_fdfifo_read) + ret = mcp25xxfd_bulk_read_fifos(spi); + else + ret = mcp25xxfd_read_fifos(spi); + + return 0; +} + +static void mcp25xxfd_mark_tx_processed(struct spi_device *spi, + int fifo) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + /* set mask */ + priv->fifos.tx_processed_mask |= BIT(fifo); + + /* check if we should reenable the TX-queue */ + if (mcp25xxfd_is_last_txfifo(spi, fifo)) + priv->tx_queue_status = TX_QUEUE_STATUS_NEEDS_START; +} + +static int mcp25xxfd_can_ist_handle_tefif_handle_single(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct mcp25xxfd_obj_tef *tef; + int fifo; + int ret; + + /* calc address in address space */ + tef = (struct mcp25xxfd_obj_tef *)(priv->fifos.fifo_data + + priv->fifos.tef_address); + + /* read all the object data */ + ret = mcp25xxfd_cmd_readn(spi, + FIFO_DATA(priv->fifos.tef_address), + tef, + /* we do not read the last byte of the ts + * to avoid MAB issiues + */ + sizeof(*tef) - 1, + priv->spi_speed_hz); + /* increment the counter to read next */ + ret = mcp25xxfd_cmd_write_mask(spi, + CAN_TEFCON, + CAN_TEFCON_UINC, + CAN_TEFCON_UINC, + priv->spi_speed_hz); + + /* transform the data to system byte order */ + mcp25xxfd_obj_ts_from_le(&tef->header); + + fifo = (tef->header.flags & CAN_OBJ_FLAGS_SEQ_MASK) >> + CAN_OBJ_FLAGS_SEQ_SHIFT; + + /* submit to queue */ + tef->header.flags |= CAN_OBJ_FLAGS_CUSTOM_ISTEF; + mcp25xxfd_addto_queued_fifos(spi, &tef->header); + + /* increment tef_address with rollover */ + priv->fifos.tef_address += sizeof(*tef); + if (priv->fifos.tef_address > priv->fifos.tef_address_end) + priv->fifos.tef_address = + priv->fifos.tef_address_start; + + /* and mark as processed right now */ + mcp25xxfd_mark_tx_processed(spi, fifo); + + return 0; +} + +static int mcp25xxfd_can_ist_handle_tefif_conservative(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 val[2]; + int ret; + + while (1) { + /* get the current TEFSTA and TEFUA */ + ret = mcp25xxfd_cmd_readn(priv->spi, + CAN_TEFSTA, + val, + 8, + priv->spi_speed_hz); + if (ret) + return ret; + mcp25xxfd_convert_to_cpu(val, 2); + + /* check for interrupt flags */ + if (!(val[0] & CAN_TEFSTA_TEFNEIF)) + return 0; + + if (priv->fifos.tef_address != val[1]) { + dev_err(&spi->dev, + "TEF Address mismatch - read: %04x calculated: %04x\n", + val[1], priv->fifos.tef_address); + priv->fifos.tef_address = val[1]; + } + + ret = mcp25xxfd_can_ist_handle_tefif_handle_single(spi); + if (ret) + return ret; + } + + return 0; +} + +static int mcp25xxfd_can_ist_handle_tefif_count(struct spi_device *spi, + int count) +{ + int i; + int ret; + + /* now clear TEF for each */ + /* TODO: optimize for BULK reads, as we (hopefully) know COUNT */ + for (i = 0; i < count; i++) { + /* handle a single TEF */ + ret = mcp25xxfd_can_ist_handle_tefif_handle_single(spi); + if (ret) + return ret; + } + + return 0; +} + +static int mcp25xxfd_can_ist_handle_tefif(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 pending = priv->fifos.tx_pending_mask_in_irq & + (~priv->fifos.tx_processed_mask); + int count; + + /* calculate the number of fifos that have been processed */ + count = hweight_long(pending); + count -= hweight_long(priv->status.txreq & pending); + + /* in case of unexpected results handle "safely" */ + if (count <= 0) + return mcp25xxfd_can_ist_handle_tefif_conservative(spi); + + return mcp25xxfd_can_ist_handle_tefif_count(spi, count); +} + +static int mcp25xxfd_can_ist_handle_txatif_fifo(struct spi_device *spi, + int fifo) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 val; + int ret; + + /* read fifo status */ + ret = mcp25xxfd_cmd_read(spi, + CAN_FIFOSTA(fifo), + &val, + priv->spi_speed_hz); + if (ret) + return ret; + + /* clear the relevant interrupt flags */ + ret = mcp25xxfd_cmd_write_mask(spi, + CAN_FIFOSTA(fifo), + 0, + CAN_FIFOSTA_TXABT | + CAN_FIFOSTA_TXLARB | + CAN_FIFOSTA_TXERR | + CAN_FIFOSTA_TXATIF, + priv->spi_speed_hz); + + /* for specific cases we could trigger a retransmit + * instead of an abort. + */ + + /* and we release it from the echo_skb buffer + * NOTE: this is one place where packet delivery will not + * be ordered, as we do not have any timing information + * when this occurred + */ + can_get_echo_skb(priv->net, fifo); + + /* but we need to run a bit of cleanup */ + priv->status.txif &= ~BIT(fifo); + priv->net->stats.tx_aborted_errors++; + + /* mark the fifo as processed */ + mcp25xxfd_mark_tx_processed(spi, fifo); + + /* handle all the known cases accordingly - ignoring FIFO full */ + val &= CAN_FIFOSTA_TXABT | + CAN_FIFOSTA_TXLARB | + CAN_FIFOSTA_TXERR; + switch (val) { + case CAN_FIFOSTA_TXERR: + break; + default: + dev_warn_ratelimited(&spi->dev, + "Unknown TX-Fifo abort condition: %08x - stopping tx-queue\n", + val); + break; + } + + return 0; +} + +static int mcp25xxfd_can_ist_handle_txatif(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int i, fifo; + int ret; + + /* process all the fifos with that flag set */ + for (i = 0, fifo = priv->fifos.tx_fifo_start; + i < priv->fifos.tx_fifos; i++, fifo++) { + if (priv->status.txatif & BIT(fifo)) { + ret = mcp25xxfd_can_ist_handle_txatif_fifo(spi, fifo); + if (ret) + return ret; + } + } + + return 0; +} + +static void mcp25xxfd_error_skb(struct net_device *net) +{ + struct mcp25xxfd_priv *priv = netdev_priv(net); + struct sk_buff *skb; + struct can_frame *frame; + + skb = alloc_can_err_skb(net, &frame); + if (skb) { + frame->can_id = priv->can_err_id; + memcpy(frame->data, priv->can_err_data, 8); + netif_rx_ni(skb); + } else { + netdev_err(net, "cannot allocate error skb\n"); + } +} + +static int mcp25xxfd_can_ist_handle_rxovif(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 mask = priv->status.rxovif; + int i; + int ret; + + /* clear all fifos that have an overflow bit set */ + for (i = 0; i < 32; i++) { + if (mask & BIT(i)) { + ret = mcp25xxfd_cmd_write_mask(spi, + CAN_FIFOSTA(i), + 0, + CAN_FIFOSTA_RXOVIF, + priv->spi_speed_hz); + if (ret) + return ret; + /* update statistics */ + priv->net->stats.rx_over_errors++; + priv->net->stats.rx_errors++; + priv->stats.rx_overflow++; + priv->can_err_id |= CAN_ERR_CRTL; + priv->can_err_data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; + } + } + + return 0; +} + +static int mcp25xxfd_can_ist_handle_modif(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int omode = priv->active_can_mode; + int mode; + int ret; + + /* Note that this irq does not get triggered in all situations + * for example SERRIF will move to RESTICTED or LISTENONLY + * but MODIF will not be raised! + */ + + /* get the mode */ + ret = mcp25xxfd_get_opmode(spi, &mode, priv->spi_speed_hz); + if (ret) + return ret; + + /* if we are restricted, then return to "normal" mode */ + if (mode == CAN_CON_MODE_RESTRICTED) + return mcp25xxfd_set_normal_opmode(spi); + + /* the controller itself will transition to sleep, so we ignore it */ + if (mode == CAN_CON_MODE_SLEEP) + return 0; + + /* switches to the same mode as before are also ignored + * - this typically happens if the driver is shortly + * switching to a different mode and then returning to the + * original mode + */ + if (mode == omode) + return 0; + + /* these we need to handle correctly, so warn and give context */ + dev_warn(&spi->dev, + "Controller unexpectedly switched from mode %s(%u) to %s(%u)\n", + mcp25xxfd_mode_names[omode], omode, + mcp25xxfd_mode_names[mode], mode); + + return 0; +} + +static int mcp25xxfd_can_ist_handle_cerrif(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + /* in principle we could also delay reading bdiag registers + * until we get here - it would add some extra delay in the + * error case, but be slightly faster in the "normal" case. + * slightly faster would be saving 8 bytes of spi transfer. + */ + + dev_err_ratelimited(&spi->dev, "CAN Bus error\n"); + priv->can_err_id |= CAN_ERR_BUSERROR; + + if (priv->status.bdiag1 & + (CAN_BDIAG1_DBIT0ERR | CAN_BDIAG1_NBIT0ERR)) { + priv->can_err_id |= CAN_ERR_BUSERROR; + priv->can_err_data[2] |= CAN_ERR_PROT_BIT0; + priv->bdiag1_clear_mask |= CAN_BDIAG1_DBIT0ERR | + CAN_BDIAG1_NBIT0ERR; + } + if (priv->status.bdiag1 & + (CAN_BDIAG1_DBIT1ERR | CAN_BDIAG1_NBIT1ERR)) { + priv->can_err_id |= CAN_ERR_BUSERROR; + priv->can_err_data[2] |= CAN_ERR_PROT_BIT1; + priv->bdiag1_clear_mask |= CAN_BDIAG1_DBIT1ERR | + CAN_BDIAG1_NBIT1ERR; + } + if (priv->status.bdiag1 & + (CAN_BDIAG1_DSTUFERR | CAN_BDIAG1_NSTUFERR)) { + priv->can_err_id |= CAN_ERR_BUSERROR; + priv->can_err_data[2] |= CAN_ERR_PROT_STUFF; + priv->bdiag1_clear_mask |= CAN_BDIAG1_DSTUFERR | + CAN_BDIAG1_NSTUFERR; + } + if (priv->status.bdiag1 & + (CAN_BDIAG1_DFORMERR | CAN_BDIAG1_NFORMERR)) { + priv->can_err_id |= CAN_ERR_BUSERROR; + priv->can_err_data[2] |= CAN_ERR_PROT_FORM; + priv->bdiag1_clear_mask |= CAN_BDIAG1_DFORMERR | + CAN_BDIAG1_NFORMERR; + } + if (priv->status.bdiag1 & CAN_BDIAG1_NACKERR) { + priv->can_err_id |= CAN_ERR_ACK; + priv->bdiag1_clear_mask |= CAN_BDIAG1_NACKERR; + } + + return 0; +} + +static int mcp25xxfd_can_ist_handle_eccif(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int ret; + u32 val; + u32 addr; + + priv->can_err_id |= CAN_ERR_CRTL; + priv->can_err_data[1] |= CAN_ERR_CRTL_UNSPEC; + + /* read ECC status register */ + ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_ECCSTAT, &val, + priv->spi_speed_hz); + if (ret) + return ret; + + addr = (val & MCP25XXFD_ECCSTAT_ERRADDR_MASK) >> + MCP25XXFD_ECCSTAT_ERRADDR_SHIFT; + + dev_err_ratelimited(&spi->dev, + "ECC %s bit error at %03x\n", + (val & MCP25XXFD_ECCSTAT_DEDIF) ? + "double" : "single", + addr); + + return mcp25xxfd_cmd_write(spi, MCP25XXFD_ECCSTAT, 0, + priv->spi_speed_hz); +} + +static int mcp25xxfd_can_ist_handle_serrif_txmab(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + priv->net->stats.tx_fifo_errors++; + priv->net->stats.tx_errors++; + priv->stats.tx_mab++; + + return 0; +} + +static int mcp25xxfd_can_ist_handle_serrif_rxmab(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + priv->net->stats.rx_dropped++; + priv->net->stats.rx_errors++; + priv->stats.rx_mab++; + + return 0; +} + +static int mcp25xxfd_can_ist_handle_serrif(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 clear; + int ret; + + /* clear some interrupts immediately, + * so that we get notified if they happen again + */ + clear = CAN_INT_SERRIF | CAN_INT_MODIF | CAN_INT_IVMIF; + ret = mcp25xxfd_cmd_write_mask(spi, CAN_INT, + priv->status.intf & (~clear), + clear, + priv->spi_speed_hz); + if (ret) + return ret; + + /* Errors here are: + * * Bus Bandwidth Error: when a RX Message Assembly Buffer + * is still full when the next message has already arrived + * the recived message shall be ignored + * * TX MAB Underflow: when a TX Message is invalid + * due to ECC errors or TXMAB underflow + * in this situatioon the system will transition to + * Restricted or Listen Only mode + */ + + priv->can_err_id |= CAN_ERR_CRTL; + priv->can_err_data[1] |= CAN_ERR_CRTL_UNSPEC; + + /* a mode change + invalid message would indicate + * TX MAB Underflow + */ + if ((priv->status.intf & CAN_INT_MODIF) && + (priv->status.intf & CAN_INT_IVMIF)) { + return mcp25xxfd_can_ist_handle_serrif_txmab(spi); + } + + /* for RX there is only the RXIF an indicator + * - surprizingly RX-MAB does not change mode or anything + */ + if (priv->status.intf & CAN_INT_RXIF) + return mcp25xxfd_can_ist_handle_serrif_rxmab(spi); + + /* the final case */ + dev_warn_ratelimited(&spi->dev, + "unidentified system error - intf = %08x\n", + priv->status.intf); + + return 0; +} + +static int mcp25xxfd_can_ist_handle_ivmif(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + /* if we have a systemerror as well, then ignore it */ + if (priv->status.intf & CAN_INT_SERRIF) + return 0; + + /* otherwise it is an RX issue, so account for it here */ + priv->can_err_id |= CAN_ERR_PROT; + priv->can_err_data[2] |= CAN_ERR_PROT_FORM; + priv->net->stats.rx_frame_errors++; + priv->net->stats.rx_errors++; + + return 0; +} + +static int mcp25xxfd_disable_interrupts(struct spi_device *spi, + u32 speed_hz) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + priv->status.intf = 0; + return mcp25xxfd_cmd_write(spi, CAN_INT, 0, speed_hz); +} + +static int mcp25xxfd_enable_interrupts(struct spi_device *spi, + u32 speed_hz) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + priv->status.intf = CAN_INT_TEFIE | + CAN_INT_RXIE | + CAN_INT_MODIE | + CAN_INT_SERRIE | + CAN_INT_IVMIE | + CAN_INT_CERRIE | + CAN_INT_RXOVIE | + CAN_INT_ECCIE; + return mcp25xxfd_cmd_write(spi, CAN_INT, + priv->status.intf, + speed_hz); +} + +static int mcp25xxfd_hw_wake(struct spi_device *spi) +{ + return mcp25xxfd_start_clock(spi, MCP25XXFD_CLK_USER_CAN); +} + +static void mcp25xxfd_hw_sleep(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + /* disable interrupts */ + mcp25xxfd_disable_interrupts(spi, priv->spi_setup_speed_hz); + + /* stop the clocks */ + mcp25xxfd_stop_clock(spi, MCP25XXFD_CLK_USER_CAN); +} + +static int mcp25xxfd_can_ist_handle_status(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + const u32 clear_irq = CAN_INT_TBCIF | + CAN_INT_MODIF | + CAN_INT_SERRIF | + CAN_INT_CERRIF | + CAN_INT_WAKIF | + CAN_INT_IVMIF; + int ret; + + /* clear all the interrupts asap */ + ret = mcp25xxfd_cmd_write_mask(spi, CAN_INT, + priv->status.intf & (~clear_irq), + clear_irq, + priv->spi_speed_hz); + if (ret) + return ret; + + /* interrupt clearing info */ + priv->bdiag1_clear_value = 0; + priv->bdiag1_clear_mask = 0; + priv->can_err_id = 0; + memset(priv->can_err_data, 0, 8); + + /* state changes */ + priv->new_state = priv->can.state; + + /* clear queued fifos */ + mcp25xxfd_clear_queued_fifos(spi); + + /* system error interrupt needs to get handled first + * to get us out of restricted mode + */ + if (priv->status.intf & CAN_INT_SERRIF) { + priv->stats.int_serr_count++; + ret = mcp25xxfd_can_ist_handle_serrif(spi); + if (ret) + return ret; + } + + /* mode change interrupt */ + if (priv->status.intf & CAN_INT_MODIF) { + priv->stats.int_mod_count++; + ret = mcp25xxfd_can_ist_handle_modif(spi); + if (ret) + return ret; + } + + /* handle the rx */ + if (priv->status.intf & CAN_INT_RXIF) { + priv->stats.int_rx_count++; + ret = mcp25xxfd_can_ist_handle_rxif(spi); + if (ret) + return ret; + } + + /* handle aborted TX FIFOs */ + if (priv->status.txatif) { + priv->stats.int_txat_count++; + ret = mcp25xxfd_can_ist_handle_txatif(spi); + if (ret) + return ret; + } + + /* handle the tef */ + if (priv->status.intf & CAN_INT_TEFIF) { + priv->stats.int_tef_count++; + ret = mcp25xxfd_can_ist_handle_tefif(spi); + if (ret) + return ret; + } + + /* process the queued fifos */ + ret = mcp25xxfd_process_queued_fifos(spi); + + /* handle error interrupt flags */ + if (priv->status.rxovif) { + priv->stats.int_rxov_count++; + ret = mcp25xxfd_can_ist_handle_rxovif(spi); + if (ret) + return ret; + } + + /* sram ECC error interrupt */ + if (priv->status.intf & CAN_INT_ECCIF) { + priv->stats.int_ecc_count++; + ret = mcp25xxfd_can_ist_handle_eccif(spi); + if (ret) + return ret; + } + + /* message format interrupt */ + if (priv->status.intf & CAN_INT_IVMIF) { + priv->stats.int_ivm_count++; + ret = mcp25xxfd_can_ist_handle_ivmif(spi); + if (ret) + return ret; + } + + /* handle bus errors in more detail */ + if (priv->status.intf & CAN_INT_CERRIF) { + priv->stats.int_cerr_count++; + ret = mcp25xxfd_can_ist_handle_cerrif(spi); + if (ret) + return ret; + } + + /* Error counter handling */ + if (priv->status.trec & CAN_TREC_TXWARN) { + priv->new_state = CAN_STATE_ERROR_WARNING; + priv->can_err_id |= CAN_ERR_CRTL; + priv->can_err_data[1] |= CAN_ERR_CRTL_TX_WARNING; + } + if (priv->status.trec & CAN_TREC_RXWARN) { + priv->new_state = CAN_STATE_ERROR_WARNING; + priv->can_err_id |= CAN_ERR_CRTL; + priv->can_err_data[1] |= CAN_ERR_CRTL_RX_WARNING; + } + if (priv->status.trec & CAN_TREC_TXBP) { + priv->new_state = CAN_STATE_ERROR_PASSIVE; + priv->can_err_id |= CAN_ERR_CRTL; + priv->can_err_data[1] |= CAN_ERR_CRTL_TX_PASSIVE; + } + if (priv->status.trec & CAN_TREC_RXBP) { + priv->new_state = CAN_STATE_ERROR_PASSIVE; + priv->can_err_id |= CAN_ERR_CRTL; + priv->can_err_data[1] |= CAN_ERR_CRTL_RX_PASSIVE; + } + if (priv->status.trec & CAN_TREC_TXBO) { + priv->new_state = CAN_STATE_BUS_OFF; + priv->can_err_id |= CAN_ERR_BUSOFF; + } + + /* based on the last state state check the new state */ + switch (priv->can.state) { + case CAN_STATE_ERROR_ACTIVE: + if (priv->new_state >= CAN_STATE_ERROR_WARNING && + priv->new_state <= CAN_STATE_BUS_OFF) + priv->can.can_stats.error_warning++; + /* fallthrough */ + case CAN_STATE_ERROR_WARNING: + if (priv->new_state >= CAN_STATE_ERROR_PASSIVE && + priv->new_state <= CAN_STATE_BUS_OFF) + priv->can.can_stats.error_passive++; + break; + default: + break; + } + priv->can.state = priv->new_state; + + /* and send error packet */ + if (priv->can_err_id) + mcp25xxfd_error_skb(priv->net); + + /* handle BUS OFF */ + if (priv->can.state == CAN_STATE_BUS_OFF) { + if (priv->can.restart_ms == 0) { + mcp25xxfd_stop_queue(priv->net); + priv->force_quit = 1; + priv->can.can_stats.bus_off++; + can_bus_off(priv->net); + mcp25xxfd_hw_sleep(spi); + } + } else { + /* restart the tx queue if needed */ + if (priv->fifos.tx_processed_mask == priv->fifos.tx_fifo_mask) + mcp25xxfd_wake_queue(spi); + } + + /* clear bdiag flags */ + if (priv->bdiag1_clear_mask) { + ret = mcp25xxfd_cmd_write_mask(spi, + CAN_BDIAG1, + priv->bdiag1_clear_value, + priv->bdiag1_clear_mask, + priv->spi_speed_hz); + if (ret) + return ret; + } + + return 0; +} + +static irqreturn_t mcp25xxfd_can_ist(int irq, void *dev_id) +{ + struct mcp25xxfd_priv *priv = dev_id; + struct spi_device *spi = priv->spi; + int ret; + + priv->stats.irq_calls++; + priv->stats.irq_state = IRQ_STATE_RUNNING; + + while (!priv->force_quit) { + /* count irq loops */ + priv->stats.irq_loops++; + + /* copy pending to in_irq - any + * updates that happen asyncronously + * are not taken into account here + */ + priv->fifos.tx_pending_mask_in_irq = + priv->fifos.tx_pending_mask; + + /* read interrupt status flags */ + ret = mcp25xxfd_cmd_readn(spi, CAN_INT, + &priv->status, + sizeof(priv->status), + priv->spi_speed_hz); + if (ret) + return ret; + + /* only act if the mask is applied */ + if ((priv->status.intf & + (priv->status.intf >> CAN_INT_IE_SHIFT)) == 0) + break; + + /* handle the status */ + ret = mcp25xxfd_can_ist_handle_status(spi); + if (ret) + return ret; + } + + return IRQ_HANDLED; +} + +static int mcp25xxfd_get_berr_counter(const struct net_device *net, + struct can_berr_counter *bec) +{ + struct mcp25xxfd_priv *priv = netdev_priv(net); + + bec->txerr = (priv->status.trec & CAN_TREC_TEC_MASK) >> + CAN_TREC_TEC_SHIFT; + bec->rxerr = (priv->status.trec & CAN_TREC_REC_MASK) >> + CAN_TREC_REC_SHIFT; + + return 0; +} + +static int mcp25xxfd_power_enable(struct regulator *reg, int enable) +{ + return 0; +} + +static int mcp25xxfd_do_set_mode(struct net_device *net, enum can_mode mode) +{ + switch (mode) { + case CAN_MODE_START: + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int mcp25xxfd_do_set_nominal_bittiming(struct net_device *net) +{ + struct mcp25xxfd_priv *priv = netdev_priv(net); + struct can_bittiming *bt = &priv->can.bittiming; + struct spi_device *spi = priv->spi; + + int sjw = bt->sjw; + int pseg2 = bt->phase_seg2; + int pseg1 = bt->phase_seg1; + int propseg = bt->prop_seg; + int brp = bt->brp; + + int tseg1 = propseg + pseg1; + int tseg2 = pseg2; + + /* calculate nominal bit timing */ + priv->regs.nbtcfg = ((sjw - 1) << CAN_NBTCFG_SJW_SHIFT) | + ((tseg2 - 1) << CAN_NBTCFG_TSEG2_SHIFT) | + ((tseg1 - 1) << CAN_NBTCFG_TSEG1_SHIFT) | + ((brp - 1) << CAN_NBTCFG_BRP_SHIFT); + + return mcp25xxfd_cmd_write(spi, CAN_NBTCFG, + priv->regs.nbtcfg, + priv->spi_setup_speed_hz); +} + +static int mcp25xxfd_do_set_data_bittiming(struct net_device *net) +{ + struct mcp25xxfd_priv *priv = netdev_priv(net); + struct can_bittiming *bt = &priv->can.data_bittiming; + struct spi_device *spi = priv->spi; + + int sjw = bt->sjw; + int pseg2 = bt->phase_seg2; + int pseg1 = bt->phase_seg1; + int propseg = bt->prop_seg; + int brp = bt->brp; + + int tseg1 = propseg + pseg1; + int tseg2 = pseg2; + + int ret; + + /* set up Transmitter delay compensation */ + if (!priv->regs.tdc) + priv->regs.tdc = CAN_TDC_EDGFLTEN | + (CAN_TDC_TDCMOD_AUTO << CAN_TDC_TDCMOD_SHIFT); + ret = mcp25xxfd_cmd_write(spi, CAN_TDC, priv->regs.tdc, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* calculate nominal bit timing */ + priv->regs.dbtcfg = ((sjw - 1) << CAN_DBTCFG_SJW_SHIFT) | + ((tseg2 - 1) << CAN_DBTCFG_TSEG2_SHIFT) | + ((tseg1 - 1) << CAN_DBTCFG_TSEG1_SHIFT) | + ((brp - 1) << CAN_DBTCFG_BRP_SHIFT); + + return mcp25xxfd_cmd_write(spi, CAN_DBTCFG, + priv->regs.dbtcfg, + priv->spi_setup_speed_hz); +} + +static int mcp25xxfd_hw_probe(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int ret; + + /* Wait for oscillator startup timer after power up */ + msleep(MCP25XXFD_OST_DELAY_MS); + + /* send a "blind" reset, hoping we are in Config mode */ + mcp25xxfd_cmd_reset(spi, priv->spi_setup_speed_hz); + + /* Wait for oscillator startup again */ + msleep(MCP25XXFD_OST_DELAY_MS); + + /* check clock register that the clock is ready or disabled */ + ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_OSC, + &priv->regs.osc, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* there can only be one... */ + switch (priv->regs.osc & + (MCP25XXFD_OSC_OSCRDY | MCP25XXFD_OSC_OSCDIS)) { + case MCP25XXFD_OSC_OSCRDY: /* either the clock is ready */ + break; + case MCP25XXFD_OSC_OSCDIS: /* or the clock is disabled */ + /* wakeup sleeping system */ + ret = mcp25xxfd_wake_from_sleep(spi); + if (ret) + return ret; + /* send a reset, hoping we are now in Config mode */ + mcp25xxfd_cmd_reset(spi, priv->spi_setup_speed_hz); + + /* Wait for oscillator startup again */ + msleep(MCP25XXFD_OST_DELAY_MS); + break; + default: + /* otherwise there is no valid device (or in strange state) + * + * if PLL is enabled but not ready, then there may be + * something "fishy" + * this happened during driver development + * (enabling pll, when when on wrong clock), so best warn + * about such a possibility + */ + if ((priv->regs.osc & + (MCP25XXFD_OSC_PLLEN | MCP25XXFD_OSC_PLLRDY)) + == MCP25XXFD_OSC_PLLEN) + dev_err(&spi->dev, + "mcp25xxfd may be in a strange state - a power disconnect may be required\n"); + + return -ENODEV; + } + + /* check if we are in config mode already*/ + + /* read CON register and match */ + ret = mcp25xxfd_cmd_read(spi, CAN_CON, + &priv->regs.con, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* apply mask and check */ + if ((priv->regs.con & CAN_CON_DEFAULT_MASK) == CAN_CON_DEFAULT) { + priv->active_can_mode = CAN_CON_MODE_CONFIG; + return 0; + } + + /* as per datasheet a reset only works in Config Mode + * so as we have in principle no knowledge of the current + * mode that the controller is in we have no safe way + * to detect the device correctly + * hence we need to "blindly" put the controller into + * config mode. + * on the "save" side, the OSC reg has to be valid already, + * so there is a chance we got the controller... + */ + + /* blindly force it into config mode */ + priv->regs.con = CAN_CON_DEFAULT; + priv->active_can_mode = CAN_CON_MODE_CONFIG; + ret = mcp25xxfd_cmd_write(spi, CAN_CON, CAN_CON_DEFAULT, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* delay some time */ + msleep(MCP25XXFD_OST_DELAY_MS); + + /* reset can controller */ + mcp25xxfd_cmd_reset(spi, priv->spi_setup_speed_hz); + + /* delay some time */ + msleep(MCP25XXFD_OST_DELAY_MS); + + /* read CON register and match a final time */ + ret = mcp25xxfd_cmd_read(spi, CAN_CON, + &priv->regs.con, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* apply mask and check */ + if ((priv->regs.con & CAN_CON_DEFAULT_MASK) != CAN_CON_DEFAULT) + return -ENODEV; + + /* just in case: disable interrupts on controller */ + return mcp25xxfd_disable_interrupts(spi, + priv->spi_setup_speed_hz); +} + +static int mcp25xxfd_setup_osc(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + int val = ((priv->config.clock_pll) ? MCP25XXFD_OSC_PLLEN : 0) + | ((priv->config.clock_div2) ? MCP25XXFD_OSC_SCLKDIV : 0); + int waitfor = ((priv->config.clock_pll) ? MCP25XXFD_OSC_PLLRDY : 0) + | ((priv->config.clock_div2) ? MCP25XXFD_OSC_SCLKRDY : 0) + | MCP25XXFD_OSC_OSCRDY; + int ret; + unsigned long timeout; + + /* manage clock_out divider */ + switch (priv->config.clock_odiv) { + case 10: + val |= (MCP25XXFD_OSC_CLKODIV_10) + << MCP25XXFD_OSC_CLKODIV_SHIFT; + break; + case 4: + val |= (MCP25XXFD_OSC_CLKODIV_4) + << MCP25XXFD_OSC_CLKODIV_SHIFT; + break; + case 2: + val |= (MCP25XXFD_OSC_CLKODIV_2) + << MCP25XXFD_OSC_CLKODIV_SHIFT; + break; + case 1: + val |= (MCP25XXFD_OSC_CLKODIV_1) + << MCP25XXFD_OSC_CLKODIV_SHIFT; + break; + case 0: + /* this means implicitly SOF output */ + val |= (MCP25XXFD_OSC_CLKODIV_10) + << MCP25XXFD_OSC_CLKODIV_SHIFT; + break; + default: + dev_err(&spi->dev, + "Unsupported output clock divider %i\n", + priv->config.clock_odiv); + return -EINVAL; + } + + /* write clock */ + ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_OSC, val, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* wait for synced pll/osc/sclk */ + timeout = jiffies + MCP25XXFD_OSC_POLLING_JIFFIES; + while (time_before_eq(jiffies, timeout)) { + ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_OSC, + &priv->regs.osc, + priv->spi_setup_speed_hz); + if (ret) + return ret; + if ((priv->regs.osc & waitfor) == waitfor) + return 0; + } + + dev_err(&spi->dev, + "Clock did not lock within the timeout period\n"); + + /* we timed out */ + return -ENODEV; +} + +static int mcp25xxfd_setup_fifo(struct net_device *net, + struct mcp25xxfd_priv *priv, + struct spi_device *spi) +{ + u32 val, available_memory, tx_memory_used; + int ret; + int i, fifo; + + /* clear all filter */ + for (i = 0; i < 32; i++) { + ret = mcp25xxfd_cmd_write(spi, CAN_FLTOBJ(i), 0, + priv->spi_setup_speed_hz); + if (ret) + return ret; + ret = mcp25xxfd_cmd_write(spi, CAN_FLTMASK(i), 0, + priv->spi_setup_speed_hz); + if (ret) + return ret; + ret = mcp25xxfd_cmd_write_mask(spi, CAN_FLTCON(i), 0, + CAN_FILCON_MASK(i), + priv->spi_setup_speed_hz); + if (ret) + return ret; + } + + /* decide on TEF, tx and rx FIFOS */ + switch (net->mtu) { + case CAN_MTU: + /* note: if we have INT1 connected to a GPIO + * then we could handle this differently and more + * efficiently + */ + + /* mtu is 8 */ + priv->fifos.payload_size = 8; + priv->fifos.payload_mode = CAN_TXQCON_PLSIZE_8; + + /* 7 tx fifos starting at fifo 1 */ + priv->fifos.tx_fifos = 7; + + /* 24 rx fifos with 1 buffers/fifo */ + priv->fifos.rx_fifo_depth = 1; + + break; + case CANFD_MTU: + /* wish there was a way to have hw filters + * that can separate based on length ... + */ + /* MTU is 64 */ + priv->fifos.payload_size = 64; + priv->fifos.payload_mode = CAN_TXQCON_PLSIZE_64; + + /* 7 tx fifos */ + priv->fifos.tx_fifos = 7; + + /* 19 rx fifos with 1 buffer/fifo */ + priv->fifos.rx_fifo_depth = 1; + + break; + default: + return -EINVAL; + } + + /* if defined as a module modify the number of tx_fifos */ + if (tx_fifos) { + dev_info(&spi->dev, + "Using %i tx-fifos as per module parameter\n", + tx_fifos); + priv->fifos.tx_fifos = tx_fifos; + } + + /* check range - we need 1 RX-fifo and one tef-fifo, hence 30 */ + if (priv->fifos.tx_fifos > 30) { + dev_err(&spi->dev, + "There is an absolute maximum of 30 tx-fifos\n"); + return -EINVAL; + } + + tx_memory_used = priv->fifos.tx_fifos * + (sizeof(struct mcp25xxfd_obj_tef) + + sizeof(struct mcp25xxfd_obj_tx) + + priv->fifos.payload_size); + /* check that we are not exceeding memory limits with 1 RX buffer */ + if (tx_memory_used + (sizeof(struct mcp25xxfd_obj_rx) + + priv->fifos.payload_size) > MCP25XXFD_BUFFER_TXRX_SIZE) { + dev_err(&spi->dev, + "Configured %i tx-fifos exceeds available memory already\n", + priv->fifos.tx_fifos); + return -EINVAL; + } + + /* calculate possible amount of RX fifos */ + available_memory = MCP25XXFD_BUFFER_TXRX_SIZE - tx_memory_used; + + priv->fifos.rx_fifos = available_memory / + (sizeof(struct mcp25xxfd_obj_rx) + + priv->fifos.payload_size) / + priv->fifos.rx_fifo_depth; + + /* we only support 31 FIFOS in total (TEF = FIFO0), + * so modify rx accordingly + */ + if (priv->fifos.tx_fifos + priv->fifos.rx_fifos > 31) + priv->fifos.rx_fifos = 31 - priv->fifos.tx_fifos; + + /* calculate effective memory used */ + available_memory -= priv->fifos.rx_fifos * + (sizeof(struct mcp25xxfd_obj_rx) + + priv->fifos.payload_size) * + priv->fifos.rx_fifo_depth; + + /* calcluate tef size */ + priv->fifos.tef_fifos = priv->fifos.tx_fifos; + fifo = available_memory / sizeof(struct mcp25xxfd_obj_tef); + if (fifo > 0) { + priv->fifos.tef_fifos += fifo; + if (priv->fifos.tef_fifos > 32) + priv->fifos.tef_fifos = 32; + } + + /* calculate rx/tx fifo start */ + priv->fifos.rx_fifo_start = 1; + priv->fifos.tx_fifo_start = + priv->fifos.rx_fifo_start + priv->fifos.rx_fifos; + + /* set up TEF SIZE to the number of tx_fifos and IRQ */ + priv->regs.tefcon = CAN_TEFCON_FRESET | + CAN_TEFCON_TEFNEIE | + CAN_TEFCON_TEFTSEN | + ((priv->fifos.tef_fifos - 1) << CAN_TEFCON_FSIZE_SHIFT); + + ret = mcp25xxfd_cmd_write(spi, CAN_TEFCON, + priv->regs.tefcon, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* set up tx fifos */ + val = CAN_FIFOCON_TXEN | + CAN_FIFOCON_TXATIE | /* show up txatie flags in txatif reg */ + CAN_FIFOCON_FRESET | /* reset FIFO */ + (priv->fifos.payload_mode << CAN_FIFOCON_PLSIZE_SHIFT) | + (0 << CAN_FIFOCON_FSIZE_SHIFT); /* 1 FIFO only */ + + if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) + if (three_shot) + val |= CAN_FIFOCON_TXAT_THREE_SHOT << + CAN_FIFOCON_TXAT_SHIFT; + else + val |= CAN_FIFOCON_TXAT_ONE_SHOT << + CAN_FIFOCON_TXAT_SHIFT; + else + val |= CAN_FIFOCON_TXAT_UNLIMITED << + CAN_FIFOCON_TXAT_SHIFT; + + for (i = 0; i < priv->fifos.tx_fifos; i++) { + fifo = priv->fifos.tx_fifo_start + i; + ret = mcp25xxfd_cmd_write(spi, CAN_FIFOCON(fifo), + /* the prioriy needs to be inverted + * we need to run from lowest to + * highest to avoid MAB errors + */ + val | ((31 - fifo) << + CAN_FIFOCON_TXPRI_SHIFT), + priv->spi_setup_speed_hz); + if (ret) + return ret; + priv->fifos.tx_fifo_mask |= BIT(fifo); + } + + /* now set up RX FIFO */ + for (i = 0, + fifo = priv->fifos.rx_fifo_start + priv->fifos.rx_fifos - 1; + i < priv->fifos.rx_fifos; i++, fifo--) { + /* prepare the fifo itself */ + ret = mcp25xxfd_cmd_write(spi, CAN_FIFOCON(fifo), + (priv->fifos.payload_mode << + CAN_FIFOCON_PLSIZE_SHIFT) | + ((priv->fifos.rx_fifo_depth - 1) << + CAN_FIFOCON_FSIZE_SHIFT) | + /* RX timestamps: */ + CAN_FIFOCON_RXTSEN | + /* reset FIFO: */ + CAN_FIFOCON_FRESET | + /* FIFO Full: */ + CAN_FIFOCON_TFERFFIE | + /* FIFO Half Full: */ + CAN_FIFOCON_TFHRFHIE | + /* FIFO not empty: */ + CAN_FIFOCON_TFNRFNIE | + /* on last fifo add overflow flag: */ + ((i == priv->fifos.rx_fifos - 1) ? + CAN_FIFOCON_RXOVIE : 0), + priv->spi_setup_speed_hz); + if (ret) + return ret; + /* prepare the rx filter config: filter i directs to fifo + * FLTMSK and FLTOBJ are 0 already, so they match everything + */ + ret = mcp25xxfd_cmd_write_mask(spi, CAN_FLTCON(i), + CAN_FIFOCON_FLTEN(i) | + (fifo << CAN_FILCON_SHIFT(i)), + CAN_FIFOCON_FLTEN(i) | + CAN_FILCON_MASK(i), + priv->spi_setup_speed_hz); + if (ret) + return ret; + + priv->fifos.rx_fifo_mask |= BIT(fifo); + } + + /* we need to move out of CONFIG mode shortly to get the addresses */ + ret = mcp25xxfd_set_opmode(spi, CAN_CON_MODE_INTERNAL_LOOPBACK, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* for the TEF fifo */ + ret = mcp25xxfd_cmd_read(spi, CAN_TEFUA, &val, + priv->spi_setup_speed_hz); + if (ret) + return ret; + priv->fifos.tef_address = val; + priv->fifos.tef_address_start = val; + priv->fifos.tef_address_end = priv->fifos.tef_address_start + + priv->fifos.tef_fifos * sizeof(struct mcp25xxfd_obj_tef) - + 1; + + /* get all the relevant addresses for the transmit fifos */ + for (i = 0; i < priv->fifos.tx_fifos; i++) { + fifo = priv->fifos.tx_fifo_start + i; + ret = mcp25xxfd_cmd_read(spi, CAN_FIFOUA(fifo), + &val, priv->spi_setup_speed_hz); + if (ret) + return ret; + priv->fifos.fifo_address[fifo] = val; + } + + /* and prepare the spi_messages */ + ret = mcp25xxfd_fill_spi_transmit_fifos(priv); + if (ret) + return ret; + + /* get all the relevant addresses for the rx fifos */ + for (i = 0; i < priv->fifos.rx_fifos; i++) { + fifo = priv->fifos.rx_fifo_start + i; + ret = mcp25xxfd_cmd_read(spi, CAN_FIFOUA(fifo), + &val, priv->spi_setup_speed_hz); + if (ret) + return ret; + priv->fifos.fifo_address[fifo] = val; + } + + /* now get back into config mode */ + ret = mcp25xxfd_set_opmode(spi, CAN_CON_MODE_CONFIG, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + return 0; +} + +static int mcp25xxfd_setup(struct net_device *net, + struct mcp25xxfd_priv *priv, + struct spi_device *spi) +{ + int ret; + + /* set up pll/clock if required */ + ret = mcp25xxfd_setup_osc(spi); + if (ret) + return ret; + + /* set up RAM ECC */ + priv->regs.ecccon = MCP25XXFD_ECCCON_ECCEN | + MCP25XXFD_ECCCON_SECIE | + MCP25XXFD_ECCCON_DEDIE; + ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_ECCCON, + priv->regs.ecccon, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* clean SRAM now that we have ECC enabled + * only this case it is clear that all RAM cels have + * valid ECC bits + */ + ret = mcp25xxfd_clean_sram(spi, priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* time stamp control register - 1ns resolution, but disabled */ + ret = mcp25xxfd_cmd_write(spi, CAN_TBC, 0, + priv->spi_setup_speed_hz); + if (ret) + return ret; + priv->regs.tscon = CAN_TSCON_TBCEN | + ((priv->can.clock.freq / 1000000) + << CAN_TSCON_TBCPRE_SHIFT); + ret = mcp25xxfd_cmd_write(spi, CAN_TSCON, + priv->regs.tscon, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* setup value of con_register */ + priv->regs.con = CAN_CON_STEF /* enable TEF */; + + /* transmission bandwidth sharing bits */ + if (bw_sharing_log2bits > 12) + bw_sharing_log2bits = 12; + priv->regs.con |= bw_sharing_log2bits << CAN_CON_TXBWS_SHIFT; + /* non iso FD mode */ + if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) + priv->regs.con |= CAN_CON_ISOCRCEN; + /* one shot */ + if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) + priv->regs.con |= CAN_CON_RTXAT; + + /* and put us into default mode = CONFIG */ + priv->regs.con |= (CAN_CON_MODE_CONFIG << CAN_CON_REQOP_SHIFT) | + (CAN_CON_MODE_CONFIG << CAN_CON_OPMOD_SHIFT); + /* apply it now - later we will only switch opsmodes... */ + ret = mcp25xxfd_cmd_write(spi, CAN_CON, + priv->regs.con, + priv->spi_setup_speed_hz); + + /* setup fifos - this also puts the system into sleep mode */ + return mcp25xxfd_setup_fifo(net, priv, spi); +} + +static int mcp25xxfd_open(struct net_device *net) +{ + struct mcp25xxfd_priv *priv = netdev_priv(net); + struct spi_device *spi = priv->spi; + int ret; + + //pr_err("mcp25xxfd_open start\n"); + ret = open_candev(net); + if (ret) { + dev_err(&spi->dev, "unable to set initial baudrate!\n"); + return ret; + } + + mcp25xxfd_gpio_direction_output(&priv->gpio, 0, 0); + + mcp25xxfd_power_enable(priv->transceiver, 1); + + priv->force_quit = 0; + + /* clear those statistics */ + memset(&priv->stats, 0, sizeof(priv->stats)); + + ret = request_threaded_irq(spi->irq, NULL, + mcp25xxfd_can_ist, + IRQF_ONESHOT | IRQF_TRIGGER_LOW, + DEVICE_NAME, priv); + if (ret) { + dev_err(&spi->dev, "failed to acquire irq %d - %i\n", + spi->irq, ret); + mcp25xxfd_power_enable(priv->transceiver, 0); + close_candev(net); + return ret; + } + + /* wake from sleep if necessary */ + ret = mcp25xxfd_hw_wake(spi); + if (ret) + goto open_clean; + + ret = mcp25xxfd_setup(net, priv, spi); + if (ret) + goto open_clean; + + mcp25xxfd_do_set_nominal_bittiming(net); + mcp25xxfd_do_set_data_bittiming(net); + + ret = mcp25xxfd_set_normal_opmode(spi); + if (ret) + goto open_clean; + /* setting up default state */ + priv->can.state = CAN_STATE_ERROR_ACTIVE; + + /* only now enable the interrupt on the controller */ + ret = mcp25xxfd_enable_interrupts(spi, + priv->spi_setup_speed_hz); + if (ret) + goto open_clean; + + can_led_event(net, CAN_LED_EVENT_OPEN); + + priv->tx_queue_status = TX_QUEUE_STATUS_RUNNING; + netif_wake_queue(net); + + return 0; + +open_clean: + mcp25xxfd_disable_interrupts(spi, priv->spi_setup_speed_hz); + free_irq(spi->irq, priv); + mcp25xxfd_hw_sleep(spi); + mcp25xxfd_power_enable(priv->transceiver, 0); + close_candev(net); + + return ret; +} + +static void mcp25xxfd_clean(struct net_device *net) +{ + struct mcp25xxfd_priv *priv = netdev_priv(net); + int i; + + for (i = 0; i < priv->fifos.tx_fifos; i++) { + if (priv->fifos.tx_pending_mask & BIT(i)) { + can_free_echo_skb(priv->net, 0); + priv->net->stats.tx_errors++; + } + } + + priv->fifos.tx_pending_mask = 0; +} + +static int mcp25xxfd_stop(struct net_device *net) +{ + struct mcp25xxfd_priv *priv = netdev_priv(net); + struct spi_device *spi = priv->spi; + + close_candev(net); + mcp25xxfd_gpio_direction_output(&priv->gpio, 0, 1); + kfree(priv->spi_transmit_fifos); + priv->spi_transmit_fifos = NULL; + + priv->force_quit = 1; + free_irq(spi->irq, priv); + + /* Disable and clear pending interrupts */ + mcp25xxfd_disable_interrupts(spi, priv->spi_setup_speed_hz); + + mcp25xxfd_clean(net); + + mcp25xxfd_hw_sleep(spi); + + mcp25xxfd_power_enable(priv->transceiver, 0); + + priv->can.state = CAN_STATE_STOPPED; + + can_led_event(net, CAN_LED_EVENT_STOP); + + return 0; +} + +static const struct net_device_ops mcp25xxfd_netdev_ops = { + .ndo_open = mcp25xxfd_open, + .ndo_stop = mcp25xxfd_stop, + .ndo_start_xmit = mcp25xxfd_start_xmit, + .ndo_change_mtu = can_change_mtu, +}; + +static const struct of_device_id mcp25xxfd_of_match[] = { + { + .compatible = "microchip,mcp2517fd", + .data = (void *)CAN_MCP2517FD, + }, + { } +}; +MODULE_DEVICE_TABLE(of, mcp25xxfd_of_match); + +static const struct spi_device_id mcp25xxfd_id_table[] = { + { + .name = "mcp2517fd", + .driver_data = (kernel_ulong_t)CAN_MCP2517FD, + }, + { } +}; +MODULE_DEVICE_TABLE(spi, mcp25xxfd_id_table); + +static int mcp25xxfd_dump_regs(struct seq_file *file, void *offset) +{ + struct spi_device *spi = file->private; + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + u32 data[CAN_TXQUA - CAN_CON + 4]; + int i; + int count; + int ret; + + count = (CAN_TXQUA - CAN_CON) / 4 + 1; + ret = mcp25xxfd_cmd_readn(spi, CAN_CON, data, 4 * count, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + mcp25xxfd_convert_to_cpu((u32 *)data, 4 * count); + + for (i = 0; i < count; i++) { + seq_printf(file, "Reg 0x%03x = 0x%08x\n", + CAN_CON + 4 * i, + ((u32 *)data)[i]); + } + + count = (MCP25XXFD_ECCSTAT - MCP25XXFD_OSC) / 4 + 1; + ret = mcp25xxfd_cmd_readn(spi, MCP25XXFD_OSC, data, 4 * count, + priv->spi_setup_speed_hz); + if (ret) + return ret; + mcp25xxfd_convert_to_cpu((u32 *)data, 4 * count); + + for (i = 0; i < count; i++) { + seq_printf(file, "Reg 0x%03x = 0x%08x\n", + MCP25XXFD_OSC + 4 * i, + ((u32 *)data)[i]); + } + + return 0; +} + +#if defined(CONFIG_DEBUG_FS) +static void mcp25xxfd_debugfs_add(struct mcp25xxfd_priv *priv) +{ + struct dentry *root, *fifousage, *fifoaddr, *rx, *tx, *status, + *regs, *stats, *rxdlc, *txdlc; + char name[32]; + int i; + + /* create the net device name */ + snprintf(name, sizeof(name), DEVICE_NAME "-%s", priv->net->name); + priv->debugfs_dir = debugfs_create_dir(name, NULL); + root = priv->debugfs_dir; + + rx = debugfs_create_dir("rx", root); + tx = debugfs_create_dir("tx", root); + fifoaddr = debugfs_create_dir("fifo_address", root); + status = debugfs_create_dir("status", root); + regs = debugfs_create_dir("regs", root); + stats = debugfs_create_dir("stats", root); + fifousage = debugfs_create_dir("fifo_usage", stats); + rxdlc = debugfs_create_dir("rx_dlc_usage", stats); + txdlc = debugfs_create_dir("tx_dlc_usage", stats); + + /* add spi speed info */ + debugfs_create_u32("spi_setup_speed_hz", 0444, root, + &priv->spi_setup_speed_hz); + debugfs_create_u32("spi_speed_hz", 0444, root, + &priv->spi_speed_hz); + + /* add irq state info */ + debugfs_create_u32("irq_state", 0444, root, &priv->stats.irq_state); + + /* for the clock user mask */ + debugfs_create_u32("clk_user_mask", 0444, root, &priv->clk_user_mask); + + /* add fd statistics */ + debugfs_create_u64("rx_fd_frames", 0444, stats, + &priv->stats.rx_fd_count); + debugfs_create_u64("tx_fd_frames", 0444, stats, + &priv->stats.tx_fd_count); + debugfs_create_u64("rx_brs_frames", 0444, stats, + &priv->stats.rx_brs_count); + debugfs_create_u64("tx_brs_frames", 0444, stats, + &priv->stats.tx_brs_count); + + /* export the status structure */ + debugfs_create_x32("intf", 0444, status, &priv->status.intf); + debugfs_create_x32("rx_if", 0444, status, &priv->status.rxif); + debugfs_create_x32("tx_if", 0444, status, &priv->status.txif); + debugfs_create_x32("rx_ovif", 0444, status, &priv->status.rxovif); + debugfs_create_x32("tx_atif", 0444, status, &priv->status.txatif); + debugfs_create_x32("tx_req", 0444, status, &priv->status.txreq); + debugfs_create_x32("trec", 0444, status, &priv->status.trec); + debugfs_create_x32("bdiag0", 0444, status, &priv->status.bdiag0); + debugfs_create_x32("bdiag1", 0444, status, &priv->status.bdiag1); + + /* some configuration registers */ + debugfs_create_x32("con", 0444, regs, &priv->regs.con); + debugfs_create_x32("ecccon", 0444, regs, &priv->regs.ecccon); + debugfs_create_x32("osc", 0444, regs, &priv->regs.osc); + debugfs_create_x32("iocon", 0444, regs, &priv->regs.iocon); + debugfs_create_x32("tdc", 0774, regs, &priv->regs.tdc); + debugfs_create_x32("tscon", 0444, regs, &priv->regs.tscon); + debugfs_create_x32("nbtcfg", 0444, regs, &priv->regs.nbtcfg); + debugfs_create_x32("dbtcfg", 0444, regs, &priv->regs.dbtcfg); + + /* information on fifos */ + debugfs_create_u32("fifo_start", 0444, rx, + &priv->fifos.rx_fifo_start); + debugfs_create_u32("fifo_count", 0444, rx, + &priv->fifos.rx_fifos); + debugfs_create_x32("fifo_mask", 0444, rx, + &priv->fifos.rx_fifo_mask); + debugfs_create_u64("rx_overflow", 0444, rx, + &priv->stats.rx_overflow); + debugfs_create_u64("rx_mab", 0444, stats, + &priv->stats.rx_mab); + + debugfs_create_u32("fifo_start", 0444, tx, + &priv->fifos.tx_fifo_start); + debugfs_create_u32("fifo_count", 0444, tx, + &priv->fifos.tx_fifos); + debugfs_create_x32("fifo_mask", 0444, tx, + &priv->fifos.tx_fifo_mask); + debugfs_create_x32("fifo_pending", 0444, tx, + &priv->fifos.tx_pending_mask); + debugfs_create_x32("fifo_submitted", 0444, tx, + &priv->fifos.tx_submitted_mask); + debugfs_create_x32("fifo_processed", 0444, tx, + &priv->fifos.tx_processed_mask); + debugfs_create_u32("queue_status", 0444, tx, + &priv->tx_queue_status); + debugfs_create_u64("tx_mab", 0444, stats, + &priv->stats.tx_mab); + + debugfs_create_u32("tef_count", 0444, tx, + &priv->fifos.tef_fifos); + + debugfs_create_u32("fifo_max_payload_size", 0444, root, + &priv->fifos.payload_size); + + /* interrupt statistics */ + debugfs_create_u64("int", 0444, stats, + &priv->stats.irq_calls); + debugfs_create_u64("int_loops", 0444, stats, + &priv->stats.irq_loops); + debugfs_create_u64("int_ivm", 0444, stats, + &priv->stats.int_ivm_count); + debugfs_create_u64("int_wake", 0444, stats, + &priv->stats.int_wake_count); + debugfs_create_u64("int_cerr", 0444, stats, + &priv->stats.int_cerr_count); + debugfs_create_u64("int_serr", 0444, stats, + &priv->stats.int_serr_count); + debugfs_create_u64("int_rxov", 0444, stats, + &priv->stats.int_rxov_count); + debugfs_create_u64("int_txat", 0444, stats, + &priv->stats.int_txat_count); + debugfs_create_u64("int_spicrc", 0444, stats, + &priv->stats.int_spicrc_count); + debugfs_create_u64("int_ecc", 0444, stats, + &priv->stats.int_ecc_count); + debugfs_create_u64("int_tef", 0444, stats, + &priv->stats.int_tef_count); + debugfs_create_u64("int_mod", 0444, stats, + &priv->stats.int_mod_count); + debugfs_create_u64("int_tbc", 0444, stats, + &priv->stats.int_tbc_count); + debugfs_create_u64("int_rx", 0444, stats, + &priv->stats.int_rx_count); + debugfs_create_u64("int_tx", 0444, stats, + &priv->stats.int_tx_count); + + /* dlc statistics */ + for (i = 0; i < 16; i++) { + snprintf(name, sizeof(name), "%02i", i); + debugfs_create_u64(name, 0444, rxdlc, + &priv->stats.rx_dlc_usage[i]); + debugfs_create_u64(name, 0444, txdlc, + &priv->stats.tx_dlc_usage[i]); + } + + /* statistics on fifo buffer usage and address */ + for (i = 1; i < 32; i++) { + snprintf(name, sizeof(name), "%02i", i); + debugfs_create_u64(name, 0444, fifousage, + &priv->stats.fifo_usage[i]); + debugfs_create_u32(name, 0444, fifoaddr, + &priv->fifos.fifo_address[i]); + } + + /* dump the controller registers themselves */ + debugfs_create_devm_seqfile(&priv->spi->dev, "reg_dump", + root, mcp25xxfd_dump_regs); +} + +static void mcp25xxfd_debugfs_remove(struct mcp25xxfd_priv *priv) +{ + debugfs_remove_recursive(priv->debugfs_dir); +} + +#else +static void mcp25xxfd_debugfs_add(struct mcp25xxfd_priv *priv) +{ + return 0; +} + +static void mcp25xxfd_debugfs_remove(struct mcp25xxfd_priv *priv) +{ +} +#endif + +#ifdef CONFIG_OF_DYNAMIC +int mcp25xxfd_of_parse(struct mcp25xxfd_priv *priv) +{ + struct spi_device *spi = priv->spi; + const struct device_node *np = spi->dev.of_node; + u32 val; + int ret; + + priv->config.clock_div2 = + of_property_read_bool(np, "microchip,clock-div2"); + + ret = of_property_read_u32_index(np, "microchip,clock-out-div", + 0, &val); + if (!ret) { + switch (val) { + case 0: + case 1: + case 2: + case 4: + case 10: + priv->config.clock_odiv = val; + break; + default: + dev_err(&spi->dev, + "Invalid value in device tree for microchip,clock_out_div: %u - valid values: 0, 1, 2, 4, 10\n", + val); + return -EINVAL; + } + } + + priv->config.gpio_opendrain = + of_property_read_bool(np, "gpio-open-drain"); + + return 0; +} +#else +int mcp25xxfd_of_parse(struct mcp25xxfd_priv *priv) +{ + return 0; +} +#endif + +static int mcp25xxfd_can_probe(struct spi_device *spi) +{ + const struct of_device_id *of_id = + of_match_device(mcp25xxfd_of_match, &spi->dev); + struct net_device *net; + struct mcp25xxfd_priv *priv; + struct clk *clk; + int ret, freq; + + /* as irq_create_fwspec_mapping() can return 0, check for it */ + if (spi->irq <= 0) { + dev_err(&spi->dev, "no valid irq line defined: irq = %i\n", + spi->irq); + return -EINVAL; + } + + clk = devm_clk_get(&spi->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&spi->dev, + "Can't get Clock source\n"); + return PTR_ERR(clk); + } + freq = clk_get_rate(clk); + if (freq < MCP25XXFD_MIN_CLOCK_FREQUENCY || + freq > MCP25XXFD_MAX_CLOCK_FREQUENCY) { + dev_err(&spi->dev, + "Clock frequency %i is not in range [%i:%i]\n", + freq, + MCP25XXFD_MIN_CLOCK_FREQUENCY, + MCP25XXFD_MAX_CLOCK_FREQUENCY); + return -ERANGE; + } + + /* Allocate can/net device */ + net = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); + if (!net) + return -ENOMEM; + + net->netdev_ops = &mcp25xxfd_netdev_ops; + net->flags |= IFF_ECHO; + + priv = netdev_priv(net); + priv->can.bittiming_const = &mcp25xxfd_nominal_bittiming_const; + priv->can.do_set_bittiming = &mcp25xxfd_do_set_nominal_bittiming; + priv->can.data_bittiming_const = &mcp25xxfd_data_bittiming_const; + priv->can.do_set_data_bittiming = &mcp25xxfd_do_set_data_bittiming; + priv->can.do_set_mode = mcp25xxfd_do_set_mode; + priv->can.do_get_berr_counter = mcp25xxfd_get_berr_counter; + + priv->can.ctrlmode_supported = + CAN_CTRLMODE_FD | + CAN_CTRLMODE_LOOPBACK | + CAN_CTRLMODE_LISTENONLY | + CAN_CTRLMODE_BERR_REPORTING | + CAN_CTRLMODE_FD_NON_ISO | + CAN_CTRLMODE_ONE_SHOT; + + if (of_id) + priv->model = (enum mcp25xxfd_model)of_id->data; + else + priv->model = spi_get_device_id(spi)->driver_data; + + spi_set_drvdata(spi, priv); + priv->spi = spi; + priv->net = net; + priv->clk = clk; + + priv->clk_user_mask = MCP25XXFD_CLK_USER_CAN; + + mutex_init(&priv->clk_user_lock); + mutex_init(&priv->spi_rxtx_lock); + + /* enable the clock and mark as enabled */ + priv->clk_user_mask = MCP25XXFD_CLK_USER_CAN; + ret = clk_prepare_enable(clk); + if (ret) + goto out_free; + + /* Setup GPIO controller */ + ret = mcp25xxfd_gpio_setup(spi); + if (ret) + goto out_clk; + + /* all by default as push/pull */ + priv->config.gpio_opendrain = false; + + /* do not use the SCK clock divider of 2 */ + priv->config.clock_div2 = false; + + /* clock output is divided by 10 */ + priv->config.clock_odiv = 10; + + /* as a first guess we assume we are in CAN_CON_MODE_SLEEP + * this is how we leave the controller when removing ourselves + */ + priv->active_can_mode = CAN_CON_MODE_SLEEP; + + /* if we have a clock that is smaller then 4MHz, then enable the pll */ + priv->config.clock_pll = + (freq <= MCP25XXFD_AUTO_PLL_MAX_CLOCK_FREQUENCY); + + /* check in device tree for overrrides */ + ret = mcp25xxfd_of_parse(priv); + if (ret) + return ret; + + /* decide on real can clock rate */ + priv->can.clock.freq = freq; + if (priv->config.clock_pll) { + priv->can.clock.freq *= MCP25XXFD_PLL_MULTIPLIER; + if (priv->can.clock.freq > MCP25XXFD_MAX_CLOCK_FREQUENCY) { + dev_err(&spi->dev, + "PLL clock frequency %i would exceed limit\n", + priv->can.clock.freq + ); + return -EINVAL; + } + } + if (priv->config.clock_div2) + priv->can.clock.freq /= MCP25XXFD_SCLK_DIVIDER; + + /* calclculate the clock frequencies to use */ + priv->spi_setup_speed_hz = freq / 2; + priv->spi_speed_hz = priv->can.clock.freq / 2; + if (priv->config.clock_div2) { + priv->spi_setup_speed_hz /= MCP25XXFD_SCLK_DIVIDER; + priv->spi_speed_hz /= MCP25XXFD_SCLK_DIVIDER; + } + + if (spi->max_speed_hz) { + priv->spi_setup_speed_hz = min_t(int, + priv->spi_setup_speed_hz, + spi->max_speed_hz); + priv->spi_speed_hz = min_t(int, + priv->spi_speed_hz, + spi->max_speed_hz); + } + /* Configure the SPI bus */ + spi->bits_per_word = 8; + ret = spi_setup(spi); + if (ret) + goto out_clk; + + ret = mcp25xxfd_power_enable(priv->power, 1); + if (ret) + goto out_clk; + + SET_NETDEV_DEV(net, &spi->dev); + + ret = mcp25xxfd_hw_probe(spi); + /* on error retry a second time */ + if (ret == -ENODEV) { + ret = mcp25xxfd_hw_probe(spi); + if (!ret) + dev_info(&spi->dev, + "found device only during retry\n"); + } + if (ret) { + if (ret == -ENODEV) + dev_err(&spi->dev, + "Cannot initialize MCP%x. Wrong wiring?\n", + priv->model); + } + + /* setting up GPIO+INT as PUSHPULL , TXCAN PUSH/PULL, no Standby */ + priv->regs.iocon = 0; + + /* SOF/CLOCKOUT pin 3 */ + if (priv->config.clock_odiv < 1) + priv->regs.iocon |= MCP25XXFD_IOCON_SOF; + + /* INT/GPIO (probably also clockout) as open drain */ + if (priv->config.gpio_opendrain) + priv->regs.iocon |= MCP25XXFD_IOCON_INTOD; + + ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_IOCON, priv->regs.iocon, + priv->spi_setup_speed_hz); + if (ret) + return ret; + + /* and put controller to sleep */ + mcp25xxfd_hw_sleep(spi); + + ret = register_candev(net); + if (ret) + goto error_probe; + + /* register debugfs */ + mcp25xxfd_debugfs_add(priv); + + devm_can_led_init(net); + + netdev_info(net, "MCP%x successfully initialized.\n", priv->model); + return 0; + +error_probe: + mcp25xxfd_power_enable(priv->power, 0); + +out_clk: + mcp25xxfd_stop_clock(spi, MCP25XXFD_CLK_USER_CAN); + +out_free: + free_candev(net); + dev_err(&spi->dev, "Probe failed, err=%d\n", -ret); + return ret; +} + +static int mcp25xxfd_can_remove(struct spi_device *spi) +{ + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct net_device *net = priv->net; + + mcp25xxfd_debugfs_remove(priv); + + unregister_candev(net); + + mcp25xxfd_power_enable(priv->power, 0); + + if (!IS_ERR(priv->clk)) + clk_disable_unprepare(priv->clk); + + free_candev(net); + + return 0; +} + +static int __maybe_unused mcp25xxfd_can_suspend(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + struct net_device *net = priv->net; + + priv->force_quit = 1; + disable_irq(spi->irq); + + if (netif_running(net)) { + netif_device_detach(net); + + mcp25xxfd_hw_sleep(spi); + mcp25xxfd_power_enable(priv->transceiver, 0); + priv->after_suspend = AFTER_SUSPEND_UP; + } else { + priv->after_suspend = AFTER_SUSPEND_DOWN; + } + + if (!IS_ERR_OR_NULL(priv->power)) { + regulator_disable(priv->power); + priv->after_suspend |= AFTER_SUSPEND_POWER; + } + + return 0; +} + +static int __maybe_unused mcp25xxfd_can_resume(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); + + if (priv->after_suspend & AFTER_SUSPEND_POWER) + mcp25xxfd_power_enable(priv->power, 1); + + if (priv->after_suspend & AFTER_SUSPEND_UP) + mcp25xxfd_power_enable(priv->transceiver, 1); + else + priv->after_suspend = 0; + + priv->force_quit = 0; + + enable_irq(spi->irq); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(mcp25xxfd_can_pm_ops, mcp25xxfd_can_suspend, + mcp25xxfd_can_resume); + +static struct spi_driver mcp25xxfd_can_driver = { + .driver = { + .name = DEVICE_NAME, + .of_match_table = mcp25xxfd_of_match, + .pm = &mcp25xxfd_can_pm_ops, + }, + .probe = mcp25xxfd_can_probe, + .remove = mcp25xxfd_can_remove, +}; + +static int __init mcp25xxfd_can_driver_init(void) +{ + int ret; + + ret = spi_register_driver(&mcp25xxfd_can_driver); + if (ret) + return ret; + + return 0; +} +module_init(mcp25xxfd_can_driver_init); + +static void __exit mcp25xxfd_can_driver_exit(void) +{ + spi_unregister_driver(&mcp25xxfd_can_driver); +} +module_exit(mcp25xxfd_can_driver_exit); + +MODULE_DESCRIPTION("Microchip 25XXFD CAN driver"); +MODULE_LICENSE("GPL v2"); From ca165875fdf5c66dbf1502764494ec43f3308121 Mon Sep 17 00:00:00 2001 From: Jim Blackler Date: Thu, 13 Jun 2019 11:54:36 +0100 Subject: [PATCH 223/281] ANDROID: Avoid taking multiple locks in handle_lmk_event Conflicting lock events have been reported resulting from rcu_read_lock, mmap_sem (in get_cmdline) and lmk_event_lock. This CL avoids the possibility of these conditions by moving handle_lmk_event outside rcu_read_lock and invoking get_cmdline before lmk_event_lock is taken. Bug: 133479338, 133829075 Signed-off-by: Jim Blackler Change-Id: I1c060dbd6200940d3b624ec275f31eedb5e2086d Git-commit: c93a1fab248c46487da803590a0f1cec135cd96a Git-repo: https://android.googlesource.com/kernel/common/ [spathi@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Srinivasarao P --- drivers/staging/android/lowmemorykiller.c | 28 +++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index a1febafbcb5e..a098685daa15 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -127,6 +127,7 @@ void handle_lmk_event(struct task_struct *selected, short min_score_adj) struct lmk_event *event; int res; long rss_in_pages = -1; + char taskname[MAX_TASKNAME]; struct mm_struct *mm = get_task_mm(selected); if (mm) { @@ -134,6 +135,17 @@ void handle_lmk_event(struct task_struct *selected, short min_score_adj) mmput(mm); } + res = get_cmdline(selected, taskname, MAX_TASKNAME - 1); + + /* No valid process name means this is definitely not associated with a + * userspace activity. + */ + + if (res <= 0 || res >= MAX_TASKNAME) + return; + + taskname[res] = '\0'; + spin_lock(&lmk_event_lock); head = event_buffer.head; @@ -148,18 +160,8 @@ void handle_lmk_event(struct task_struct *selected, short min_score_adj) events = (struct lmk_event *) event_buffer.buf; event = &events[head]; - res = get_cmdline(selected, event->taskname, MAX_TASKNAME - 1); - - /* No valid process name means this is definitely not associated with a - * userspace activity. - */ - - if (res <= 0 || res >= MAX_TASKNAME) { - spin_unlock(&lmk_event_lock); - return; - } + memcpy(event->taskname, taskname, res + 1); - event->taskname[res] = '\0'; event->pid = selected->pid; event->uid = from_kuid_munged(current_user_ns(), task_uid(selected)); if (selected->group_leader) @@ -786,7 +788,6 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) lowmem_deathpending_timeout = jiffies + HZ; rem += selected_tasksize; rcu_read_unlock(); - handle_lmk_event(selected, min_score_adj); /* give the system time to free up the memory */ msleep_interruptible(20); trace_almk_shrink(selected_tasksize, ret, @@ -801,6 +802,9 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) sc->nr_to_scan, sc->gfp_mask, rem); mutex_unlock(&scan_mutex); + if (selected) + handle_lmk_event(selected, min_score_adj); + return rem; } From e9701ca4192981870fd8b571820935e788f4fa65 Mon Sep 17 00:00:00 2001 From: Jim Blackler Date: Wed, 3 Jul 2019 17:33:51 +0100 Subject: [PATCH 224/281] ANDROID: Fixes to locking around handle_lmk_event get_task_struct used to reserve 'selected' outside rcu_read_lock block. Remove the need for get_task_mm, removing the possibility of lock issues there. Bug: 133479338 Signed-off-by: Jim Blackler Change-Id: I1399e2f669242c04e0e397bc09c987358aa97a0a Git-commit: d657433f124d1d5d521ee3ba8f3486e9169012e4 Git-repo: https://android.googlesource.com/kernel/common/ [spathi@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Srinivasarao P --- drivers/staging/android/lowmemorykiller.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index a098685daa15..d54e68b6259a 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -119,21 +119,15 @@ struct lmk_event { struct list_head list; }; -void handle_lmk_event(struct task_struct *selected, short min_score_adj) +void handle_lmk_event(struct task_struct *selected, int selected_tasksize, + short min_score_adj) { int head; int tail; struct lmk_event *events; struct lmk_event *event; int res; - long rss_in_pages = -1; char taskname[MAX_TASKNAME]; - struct mm_struct *mm = get_task_mm(selected); - - if (mm) { - rss_in_pages = get_mm_rss(mm); - mmput(mm); - } res = get_cmdline(selected, taskname, MAX_TASKNAME - 1); @@ -172,7 +166,7 @@ void handle_lmk_event(struct task_struct *selected, short min_score_adj) event->maj_flt = selected->maj_flt; event->oom_score_adj = selected->signal->oom_score_adj; event->start_time = nsec_to_clock_t(selected->real_start_time); - event->rss_in_pages = rss_in_pages; + event->rss_in_pages = selected_tasksize; event->min_score_adj = min_score_adj; event_buffer.head = (head + 1) & (MAX_BUFFERED_EVENTS - 1); @@ -788,6 +782,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) lowmem_deathpending_timeout = jiffies + HZ; rem += selected_tasksize; rcu_read_unlock(); + get_task_struct(selected); /* give the system time to free up the memory */ msleep_interruptible(20); trace_almk_shrink(selected_tasksize, ret, @@ -802,9 +797,10 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) sc->nr_to_scan, sc->gfp_mask, rem); mutex_unlock(&scan_mutex); - if (selected) - handle_lmk_event(selected, min_score_adj); - + if (selected) { + handle_lmk_event(selected, selected_tasksize, min_score_adj); + put_task_struct(selected); + } return rem; } From 515b0d70f2c870cd76069e7e479e3432048706fd Mon Sep 17 00:00:00 2001 From: Fei Mao Date: Thu, 8 Aug 2019 14:27:46 +0800 Subject: [PATCH 225/281] input: touchscreen: cyttsp5: resume from deep sleep If fail to exit EASYWAKE state, try to send POWER_ON to resume touch from deep sleep again. Change-Id: I6f7101af10b9d97d55eb41d02c3cd475d6a6865e Signed-off-by: Fei Mao --- drivers/input/touchscreen/cyttsp5/cyttsp5_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c index 119ac457dee1..44bb9ba6507e 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c @@ -3702,7 +3702,7 @@ static int cyttsp5_core_wake_device_from_easy_wakeup_( rc = cyttsp5_hid_output_exit_easywake_state_(cd, cd->easy_wakeup_gesture, &status); if (rc || status == 0) { - dev_err(cd->dev, "%s: failed, rc=%d, status=%d\n", + dev_dbg(cd->dev, "%s: failed, rc=%d, status=%d\n", __func__, rc, status); return -EBUSY; } @@ -4399,7 +4399,8 @@ static int cyttsp5_core_wake_device_(struct cyttsp5_core_data *cd) if (!IS_DEEP_SLEEP_CONFIGURED(cd->easy_wakeup_gesture)) { #ifdef CY_GES_WAKEUP - return cyttsp5_core_wake_device_from_easy_wakeup_(cd); + if (!cyttsp5_core_wake_device_from_easy_wakeup_(cd)) + return 0; #endif } From 995e9430b1cb4837c420c9cf0a89755c203de0ec Mon Sep 17 00:00:00 2001 From: jiangjia Date: Tue, 6 Aug 2019 14:58:08 +0800 Subject: [PATCH 226/281] ARM: dts: msm: increase adsp firmware size for sdm429w Increase adsp firmware size to 21M from 20M, for sdm429w-spyro. Change-Id: I39b38e82eef65b231a4e95762b41ee06b3c251d0 Signed-off-by: Jiangjiang Shen --- arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi index 32078275d38c..48c14c4b29f9 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi @@ -189,11 +189,11 @@ }; &adsp_fw_mem { - reg = <0x0 0x8b800000 0x0 0x1400000>; + reg = <0x0 0x8b800000 0x0 0x1500000>; }; &wcnss_fw_mem { - reg = <0x0 0x8cc00000 0x0 0x700000>; + reg = <0x0 0x8cd00000 0x0 0x700000>; }; &i2c_4 { From dcdd67e121860e01ab3e8a4157ed3edf641d8eb9 Mon Sep 17 00:00:00 2001 From: jianzhou Date: Thu, 8 Aug 2019 17:10:54 +0800 Subject: [PATCH 227/281] defconfig: msm8937/53/37go: Kernel configs required for Q requirement Change msm8937/53/37go kernel configs required for Q requirement. All all configs from kernel\configs\q\android-4.9\android-base.config, Add "CONFIG_USB_RTL8152" according to "android-base-conditional.xml", "CONFIG_DM_BOW=y" is required to support Userdata check pointing. Change-Id: I47c53c285e26f76c6222f6e4b544d1bd05c943de Signed-off-by: jianzhou --- arch/arm/configs/msm8937-perf_defconfig | 8 ++++++-- arch/arm/configs/msm8937_defconfig | 8 ++++++-- arch/arm/configs/msm8937go-perf_defconfig | 9 +++++++-- arch/arm/configs/msm8937go_defconfig | 9 +++++++-- arch/arm/configs/msm8953-perf_defconfig | 9 +++++++-- arch/arm/configs/msm8953_defconfig | 9 +++++++-- arch/arm64/configs/msm8937-perf_defconfig | 6 ++++-- arch/arm64/configs/msm8937_defconfig | 7 +++++-- arch/arm64/configs/msm8953-perf_defconfig | 6 ++++-- arch/arm64/configs/msm8953_defconfig | 6 ++++-- 10 files changed, 57 insertions(+), 20 deletions(-) diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig index 655d4db416b6..cb695d9c7ff4 100755 --- a/arch/arm/configs/msm8937-perf_defconfig +++ b/arch/arm/configs/msm8937-perf_defconfig @@ -39,7 +39,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set @@ -90,7 +89,6 @@ CONFIG_VFP=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -98,6 +96,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -107,6 +106,7 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPGRE_DEMUX=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y @@ -219,6 +219,7 @@ CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y @@ -275,6 +276,7 @@ CONFIG_DM_DEFAULT_KEY=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_TUN=y @@ -293,11 +295,13 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y +CONFIG_PPTP=y CONFIG_PPPOL2TP=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_ADMTEK is not set # CONFIG_WLAN_VENDOR_ATH is not set diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig index 6e9f54666f0e..0753f02ab725 100755 --- a/arch/arm/configs/msm8937_defconfig +++ b/arch/arm/configs/msm8937_defconfig @@ -40,7 +40,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -92,7 +91,6 @@ CONFIG_VFP=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -101,6 +99,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -110,6 +109,7 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPGRE_DEMUX=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y @@ -222,6 +222,7 @@ CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y @@ -279,6 +280,7 @@ CONFIG_DM_DEFAULT_KEY=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_TUN=y @@ -297,11 +299,13 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y +CONFIG_PPTP=y CONFIG_PPPOL2TP=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_ADMTEK is not set # CONFIG_WLAN_VENDOR_ATH is not set diff --git a/arch/arm/configs/msm8937go-perf_defconfig b/arch/arm/configs/msm8937go-perf_defconfig index 6ab6c96a84bd..60c012d55268 100755 --- a/arch/arm/configs/msm8937go-perf_defconfig +++ b/arch/arm/configs/msm8937go-perf_defconfig @@ -40,7 +40,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_KALLSYMS_ALL=y # CONFIG_BASE_FULL is not set CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set @@ -90,7 +89,6 @@ CONFIG_VFP=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -98,6 +96,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -107,10 +106,12 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPGRE_DEMUX=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y +CONFIG_INET_UDP_DIAG=y CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y @@ -216,6 +217,7 @@ CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y @@ -271,6 +273,7 @@ CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_TUN=y @@ -289,11 +292,13 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y +CONFIG_PPTP=y CONFIG_PPPOL2TP=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_ADMTEK is not set # CONFIG_WLAN_VENDOR_ATH is not set diff --git a/arch/arm/configs/msm8937go_defconfig b/arch/arm/configs/msm8937go_defconfig index 41f11be32766..1e6963745e59 100755 --- a/arch/arm/configs/msm8937go_defconfig +++ b/arch/arm/configs/msm8937go_defconfig @@ -41,7 +41,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_KALLSYMS_ALL=y # CONFIG_BASE_FULL is not set CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -92,7 +91,6 @@ CONFIG_VFP=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -101,6 +99,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -110,10 +109,12 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPGRE_DEMUX=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y +CONFIG_INET_UDP_DIAG=y CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y @@ -219,6 +220,7 @@ CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y @@ -275,6 +277,7 @@ CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_TUN=y @@ -293,11 +296,13 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y +CONFIG_PPTP=y CONFIG_PPPOL2TP=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_ADMTEK is not set # CONFIG_WLAN_VENDOR_ATH is not set diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig index d072b6790d9a..ee4be8cdefa2 100755 --- a/arch/arm/configs/msm8953-perf_defconfig +++ b/arch/arm/configs/msm8953-perf_defconfig @@ -37,7 +37,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -85,7 +84,6 @@ CONFIG_VFP=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -93,6 +91,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -102,10 +101,12 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPGRE_DEMUX=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y +CONFIG_INET_UDP_DIAG=y CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y @@ -211,6 +212,7 @@ CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y @@ -265,6 +267,7 @@ CONFIG_DM_REQ_CRYPT=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_TUN=y @@ -283,11 +286,13 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y +CONFIG_PPTP=y CONFIG_PPPOL2TP=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_ADMTEK is not set # CONFIG_WLAN_VENDOR_ATH is not set diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig index 8ba9cceaa5ac..6b3f0033448f 100755 --- a/arch/arm/configs/msm8953_defconfig +++ b/arch/arm/configs/msm8953_defconfig @@ -38,7 +38,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -88,7 +87,6 @@ CONFIG_VFP=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -97,6 +95,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -106,10 +105,12 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPGRE_DEMUX=y CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y +CONFIG_INET_UDP_DIAG=y CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y @@ -215,6 +216,7 @@ CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y @@ -270,6 +272,7 @@ CONFIG_DM_REQ_CRYPT=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_TUN=y @@ -288,11 +291,13 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y +CONFIG_PPTP=y CONFIG_PPPOL2TP=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_ADMTEK is not set # CONFIG_WLAN_VENDOR_ATH is not set diff --git a/arch/arm64/configs/msm8937-perf_defconfig b/arch/arm64/configs/msm8937-perf_defconfig index 7fde262b1b33..8e877f74ac04 100755 --- a/arch/arm64/configs/msm8937-perf_defconfig +++ b/arch/arm64/configs/msm8937-perf_defconfig @@ -38,7 +38,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -80,7 +79,6 @@ CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -97,6 +95,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -218,6 +217,7 @@ CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y @@ -274,6 +274,7 @@ CONFIG_DM_DEFAULT_KEY=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_TUN=y @@ -298,6 +299,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_ADMTEK is not set # CONFIG_WLAN_VENDOR_ATH is not set diff --git a/arch/arm64/configs/msm8937_defconfig b/arch/arm64/configs/msm8937_defconfig index 59f906afabb9..567bdbf8574b 100755 --- a/arch/arm64/configs/msm8937_defconfig +++ b/arch/arm64/configs/msm8937_defconfig @@ -39,7 +39,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -83,7 +82,6 @@ CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -101,6 +99,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -223,6 +222,7 @@ CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y @@ -280,6 +280,7 @@ CONFIG_DM_DEFAULT_KEY=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_TUN=y @@ -304,6 +305,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_ADMTEK is not set # CONFIG_WLAN_VENDOR_ATH is not set @@ -339,6 +341,7 @@ CONFIG_INPUT_UINPUT=y # CONFIG_SERIO_SERPORT is not set # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set # CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index b346f4ee974b..804ade3418ff 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -38,7 +38,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -79,7 +78,6 @@ CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -96,6 +94,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -215,6 +214,7 @@ CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y @@ -272,6 +272,7 @@ CONFIG_DM_DEFAULT_KEY=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_TUN=y @@ -295,6 +296,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_ADMTEK is not set # CONFIG_WLAN_VENDOR_ATH is not set diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index 2c1e89b46c2b..9affe57c25bb 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -39,7 +39,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_RD_LZ4 is not set CONFIG_KALLSYMS_ALL=y CONFIG_BPF_SYSCALL=y -# CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -82,7 +81,6 @@ CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y -CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -100,6 +98,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_INTERFACE=y CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -220,6 +219,7 @@ CONFIG_BRIDGE=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y @@ -278,6 +278,7 @@ CONFIG_DM_DEFAULT_KEY=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_BOW=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y CONFIG_TUN=y @@ -302,6 +303,7 @@ CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_RTL8152=y CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_ADMTEK is not set # CONFIG_WLAN_VENDOR_ATH is not set From abe179de7d53eafccb51ea66b9ed92972c276425 Mon Sep 17 00:00:00 2001 From: Hardik Arya Date: Mon, 17 Jun 2019 17:45:16 +0530 Subject: [PATCH 228/281] diag: Update diag get log request structure Currently diag get log mask is using structure with num_items which is not being used. The patch updates structure for diag get log mask request. Change-Id: I1d4d110ca1793e1c8bedcab33e2626f02af37926 Signed-off-by: Hardik Arya --- drivers/char/diag/diag_masks.c | 6 +++--- drivers/char/diag/diag_masks.h | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index c6ec2711f009..c67f0732a18a 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -1195,7 +1195,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len, int rsp_header_len = sizeof(struct diag_log_config_rsp_t); uint32_t mask_size = 0; struct diag_log_mask_t *log_item = NULL; - struct diag_log_config_req_t *req; + struct diag_log_config_get_req_t *req; struct diag_log_config_rsp_t rsp; struct diag_mask_info *mask_info = NULL; struct diag_md_session_t *info = NULL; @@ -1205,7 +1205,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len, mask_info = (!info) ? &log_mask : info->log_mask; if (!src_buf || !dest_buf || dest_len <= 0 || !mask_info || - src_len < sizeof(struct diag_log_config_req_t)) { + src_len < sizeof(struct diag_log_config_get_req_t)) { pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n", __func__, src_buf, src_len, dest_buf, dest_len, mask_info); @@ -1224,7 +1224,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len, return 0; } - req = (struct diag_log_config_req_t *)src_buf; + req = (struct diag_log_config_get_req_t *)src_buf; read_len += req_header_len; rsp.cmd_code = DIAG_CMD_LOG_CONFIG; diff --git a/drivers/char/diag/diag_masks.h b/drivers/char/diag/diag_masks.h index a736ff269e8d..5c7682548189 100644 --- a/drivers/char/diag/diag_masks.h +++ b/drivers/char/diag/diag_masks.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, 2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2015, 2018-2019 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 @@ -40,6 +40,13 @@ struct diag_msg_mask_t { uint32_t *ptr; }; +struct diag_log_config_get_req_t { + uint8_t cmd_code; + uint8_t padding[3]; + uint32_t sub_cmd; + uint32_t equip_id; +} __packed; + struct diag_log_config_req_t { uint8_t cmd_code; uint8_t padding[3]; From 87e22632efe91e06a7f64a40bf062dc87bfaf191 Mon Sep 17 00:00:00 2001 From: Junwen Wu Date: Fri, 9 Aug 2019 09:50:06 +0800 Subject: [PATCH 229/281] ARM: dts: msm:disable fg-gen3 for SDM845 RB3 The RB3,which is SDA845 without battery,need disable fg-gen3 to save the kernel boot time. Change-Id: If6a7108227aaec99ab7e1d7b3ef16bba6611cb88 Signed-off-by: Junwen Wu --- arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi index 2955610cc5f1..2e16dbdb8249 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi @@ -290,6 +290,7 @@ &pmi8998_fg { qcom,battery-data = <&mtp_batterydata>; + status = "disabled"; }; &smb1355_charger_0 { From 2b6cfb1853ee411fa982d7e0d87b7745f10f85f8 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Tue, 2 Jul 2019 20:21:06 +0530 Subject: [PATCH 230/281] usb: gadget: f_gsi: Use HW accelerated EPs for RmNet V2X instance When both RmNet LTE and V2X instances are enabled in a composition, use hardware accelerated EPs for V2X instance and normal EPs for LTE, and also set channel parameter flag 'is_sw_path' to true for LTE, so that IPA can ignore the dummy address for GEVENTCOUNT register. Change-Id: I6e194dbea4d8321c33501e8cab4f1f2f0817291f Signed-off-by: Ajay Agarwal --- drivers/usb/gadget/function/f_gsi.c | 32 ++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index d58b20a0cb37..0c1897bb9b82 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -535,6 +535,7 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) { int ret; struct f_gsi *gsi = d_port_to_gsi(d_port); + struct f_gsi *gsi_rmnet_v2x = __gsi[USB_PROT_RMNET_V2X_IPA]; struct ipa_usb_xdci_chan_params *in_params = &d_port->ipa_in_channel_params; struct ipa_usb_xdci_chan_params *out_params = @@ -663,6 +664,23 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) gsi_channel_info.depcmd_hi_addr; } + /* + * When both RmNet LTE and V2X instances are enabled in a composition, + * set 'is_sw_path' flag to true for LTE, so that IPA can ignore the + * dummy address for GEVENTCOUNT register. + */ + in_params->is_sw_path = false; + if (gsi->prot_id == USB_PROT_RMNET_IPA && + gsi_rmnet_v2x->function.fs_descriptors) + in_params->is_sw_path = true; + + if (d_port->out_ep) { + out_params->is_sw_path = false; + if (gsi->prot_id == USB_PROT_RMNET_IPA && + gsi_rmnet_v2x->function.fs_descriptors) + out_params->is_sw_path = true; + } + /* Populate connection params */ conn_params->max_pkt_size = (cdev->gadget->speed == USB_SPEED_SUPER) ? @@ -2415,6 +2433,7 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, unsigned int alt) { struct f_gsi *gsi = func_to_gsi(f); + struct f_gsi *gsi_rmnet_v2x = __gsi[USB_PROT_RMNET_V2X_IPA]; struct usb_composite_dev *cdev = f->config->cdev; struct net_device *net; int ret; @@ -2489,12 +2508,18 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, goto notify_ep_disable; } - /* Configure EPs for GSI */ + /* + * Configure EPs for GSI. Note that when both RmNet LTE + * and V2X instances are enabled in a composition, + * configure HW accelerated EPs for V2X instance and + * normal EPs for LTE. + */ if (gsi->d_port.in_ep && gsi->prot_id <= USB_PROT_RMNET_V2X_IPA) { if (gsi->prot_id == USB_PROT_DIAG_IPA) gsi->d_port.in_ep->ep_intr_num = 3; - else if (gsi->prot_id == USB_PROT_RMNET_V2X_IPA) + else if (gsi->prot_id == USB_PROT_RMNET_IPA && + gsi_rmnet_v2x->function.fs_descriptors) gsi->d_port.in_ep->ep_intr_num = 0; else gsi->d_port.in_ep->ep_intr_num = 2; @@ -2505,7 +2530,8 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, if (gsi->d_port.out_ep && gsi->prot_id <= USB_PROT_RMNET_V2X_IPA) { - if (gsi->prot_id == USB_PROT_RMNET_V2X_IPA) + if (gsi->prot_id == USB_PROT_RMNET_IPA && + gsi_rmnet_v2x->function.fs_descriptors) gsi->d_port.out_ep->ep_intr_num = 0; else gsi->d_port.out_ep->ep_intr_num = 1; From eb1d2d50955e65e2871f241e0738fbd46004a722 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Thu, 27 Jun 2019 17:32:28 +0530 Subject: [PATCH 231/281] usb: gadget: f_gsi: Notify line state change from set_alt for RmNet Currently the driver notifies line state change to QTI for RmNet interface on getting the line state SET control request from the host. There is a requirement now that the QTI wants to query IPA for ep_info once the data path has been set up. Hence, send the zero byte packet for line state change from setup() function to set_alt after the xdci_connect has been done. QTI can then query USB and IPA for info via IOCTLs. Change-Id: Iecae2c7e67b63474d26fcbccada9ebe2364295a7 Signed-off-by: Ajay Agarwal --- drivers/usb/gadget/function/f_gsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index 0c1897bb9b82..1cd612a13491 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -2224,7 +2224,6 @@ gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) queue_work(gsi->c_port.uevent_wq, &gsi->c_port.uevent_work); - gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0); value = 0; break; case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) @@ -2601,7 +2600,10 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, if (gsi->prot_id == USB_PROT_DIAG_IPA || gsi->prot_id == USB_PROT_DPL_ETHER || gsi->prot_id == USB_PROT_GPS_CTRL || - gsi->prot_id == USB_PROT_MBIM_IPA) + gsi->prot_id == USB_PROT_MBIM_IPA || + gsi->prot_id == USB_PROT_RMNET_IPA || + gsi->prot_id == USB_PROT_RMNET_V2X_IPA || + gsi->prot_id == USB_PROT_RMNET_ETHER) gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0); if (gsi->c_port.uevent_wq) From 2f73f3f8c5e589f7cdf719bcc83524048fff9344 Mon Sep 17 00:00:00 2001 From: Raja Mallik Date: Fri, 9 Aug 2019 16:55:14 +0530 Subject: [PATCH 232/281] msm: camera: eeprom: Release the mutex even though got error Release the mutex even though got error. Change-Id: I17a7f7b5ae91135e435bcbc14bece744465b9dd2 Signed-off-by: Depeng Shao Signed-off-by: Raja Mallik --- .../camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 06d6bd49b3b0..bcd3823a357c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -1016,7 +1016,7 @@ int32_t cam_eeprom_driver_cmd(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) &eeprom_cap, sizeof(struct cam_eeprom_query_cap_t))) { CAM_ERR(CAM_EEPROM, "Failed Copy to User"); - return -EFAULT; + rc = -EFAULT; goto release_mutex; } CAM_DBG(CAM_EEPROM, "eeprom_cap: ID: %d", eeprom_cap.slot_info); From f3a6527dac8f1c8ab32c155837688534270a074c Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Thu, 20 Jun 2019 18:14:54 -0700 Subject: [PATCH 233/281] usb: dwc3: Stop active transfer on control endpoints If cable disconnects before data stage completion dwc3_remove_requests() gets called for ep0 in and out but dwc3_ep0_complete_data() does not get called. dwc3_ep0_complete_data() function resets TRB enqueue count to 0. As a result upon next cable connect start transfer is called with wrong TRB address because trb_enqueue is set to 1. Since this TRB was completed in the past, HWO bit is cleared for this TRB. This results into usb enumeration failure due to control transfer stall. Fix this issue by issuing end transfer command on control endpoints after ep0 requests are removed for IN and OUT and reset trb_enqueue counters to 0. Change-Id: Ic5364f11372d85ec7c133024dc48bbc5d848ebf4 Signed-off-by: Hemant Kumar --- drivers/usb/dwc3/gadget.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 12352875ac3d..8438999e4cd5 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -744,6 +744,21 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } + + if (dep->number == 1 && dwc->ep0state != EP0_SETUP_PHASE) { + unsigned int dir; + + dbg_log_string("CTRLPEND %d", dwc->ep0state); + dir = !!dwc->ep0_expect_in; + if (dwc->ep0state == EP0_DATA_PHASE) + dwc3_ep0_end_control_data(dwc, dwc->eps[dir]); + else + dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]); + + dwc->eps[0]->trb_enqueue = 0; + dwc->eps[1]->trb_enqueue = 0; + } + dbg_log_string("DONE for %s(%d)", dep->name, dep->number); } From 069548df39ca2a06e66e6f99e8bfb4ef8ddbb152 Mon Sep 17 00:00:00 2001 From: Chaojun Wang Date: Wed, 8 May 2019 14:03:08 +0800 Subject: [PATCH 234/281] ARM: dts: msm: Add MCP25xxfd support for SDM845 RB3 platform MCP25xxfd is a CAN controller with SPI interface, add support for SDM845 RB3 platform. Change-Id: Ic60a78301a3da14bc38b968e9875a0bdb06d9496 Signed-off-by: Chaojun Wang --- arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi index cf84ecf74997..47638e3e57d4 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi @@ -33,6 +33,33 @@ status = "ok"; }; +&pcie1 { + status = "disable"; +}; + +&soc { + clk40M: can_clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <40000000>; + }; +}; + +&qupv3_se0_spi { + status = "ok"; + can@0 { + compatible = "microchip,mcp2517fd"; + reg = <0>; + clocks = <&clk40M>; + interrupt-parent = <&tlmm>; + interrupts = <104 0>; + interrupt-names = "can_irq"; + spi-max-frequency = <10000000>; + gpio-controller; + status = "okay"; + }; +}; + &qupv3_se3_i2c { status = "disabled"; }; From a6e64daf585c26685a48cd3e4aa9560eb55af754 Mon Sep 17 00:00:00 2001 From: Chaojun Wang Date: Wed, 8 May 2019 14:17:02 +0800 Subject: [PATCH 235/281] defconfig: SDM845: enable MCP25xxFD driver Enable MCP25xxFD driver for RB3. Change-Id: I3e64adeec13f8f6b3dc3dda781b4ade853996b7b Signed-off-by: Chaojun Wang --- arch/arm64/configs/sdm845-perf_defconfig | 2 ++ arch/arm64/configs/sdm845_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig index 1ec275b3b8e3..8a8154e5e03c 100755 --- a/arch/arm64/configs/sdm845-perf_defconfig +++ b/arch/arm64/configs/sdm845-perf_defconfig @@ -235,6 +235,8 @@ CONFIG_RMNET_DATA=y CONFIG_RMNET_DATA_FC=y CONFIG_RMNET_DATA_DEBUG_PKT=y CONFIG_SOCKEV_NLMCAST=y +CONFIG_CAN=y +CONFIG_CAN_MCP25XXFD=y CONFIG_BT=y CONFIG_MSM_BT_POWER=y CONFIG_CFG80211=y diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig index 1a39bca0bd78..38aadbeecaa7 100644 --- a/arch/arm64/configs/sdm845_defconfig +++ b/arch/arm64/configs/sdm845_defconfig @@ -240,6 +240,8 @@ CONFIG_RMNET_DATA=y CONFIG_RMNET_DATA_FC=y CONFIG_RMNET_DATA_DEBUG_PKT=y CONFIG_SOCKEV_NLMCAST=y +CONFIG_CAN=y +CONFIG_CAN_MCP25XXFD=y CONFIG_BT=y CONFIG_MSM_BT_POWER=y CONFIG_CFG80211=y From 07e443023349a5abbca0d27b8f9dbce79d3150d6 Mon Sep 17 00:00:00 2001 From: Pooja Kumari Date: Wed, 31 Jul 2019 15:20:19 +0530 Subject: [PATCH 236/281] msm: ipa3: Fix to memory allocation failure During device reboot when IPA is going for shutdown, the allocation for memory request fails. Add change in IPA to not sleep while memory allocation. Change-Id: I0bdbf0f622770566ad1135c76f6edc2790285420 Signed-off-by: Pooja Kumari --- drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c index 530adef46f09..35d5efcda4c7 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 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 @@ -3479,6 +3479,7 @@ int ipahal_fltrt_allocate_hw_tbl_imgs( int ipahal_fltrt_allocate_hw_sys_tbl(struct ipa_mem_buffer *tbl_mem) { struct ipahal_fltrt_obj *obj; + gfp_t flag = GFP_KERNEL; IPAHAL_DBG_LOW("Entry\n"); @@ -3496,10 +3497,14 @@ int ipahal_fltrt_allocate_hw_sys_tbl(struct ipa_mem_buffer *tbl_mem) /* add word for rule-set terminator */ tbl_mem->size += obj->tbl_width; - +alloc: tbl_mem->base = dma_alloc_coherent(ipahal_ctx->ipa_pdev, tbl_mem->size, - &tbl_mem->phys_base, GFP_KERNEL); + &tbl_mem->phys_base, flag); if (!tbl_mem->base) { + if (flag == GFP_KERNEL) { + flag = GFP_ATOMIC; + goto alloc; + } IPAHAL_ERR("fail to alloc DMA buf of size %d\n", tbl_mem->size); return -ENOMEM; From a854ce5bd77db896847e2b59751ba27caf9fdeb9 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Tue, 9 Jul 2019 19:32:21 +0530 Subject: [PATCH 237/281] usb: dwc3-msm: Add support for interrupt moderation in device mode Add support for interrupt moderation in device mode to ensure minimum time interval between core interrupts. Use the module parameter 'dwc3_gadget_imod_val' as follows: To enable/modify moderation value: - Disconnect the peripheral cable - echo > /sys/module/dwc3_msm/parameters/dwc3_gadget_imod_val - Start gadget by connecting peripheral cable. - Moderation will be enabled/modified. To disable interrupt moderation: - echo 0 > /sys/module/dwc3_msm/parameters/dwc3_gadget_imod_val - Start gadget by connecting peripheral cable. - Moderation will be disabled. Change-Id: Ic6189ef98d9003303332450afc67ed29413307be Signed-off-by: Ajay Agarwal --- drivers/usb/dwc3/dwc3-msm.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index a2a4438b625a..83df7508024e 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -71,6 +71,12 @@ static int cpu_to_affin; module_param(cpu_to_affin, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(cpu_to_affin, "affin usb irq to this cpu"); +/* Interrupt moderation for normal endpoints */ +static unsigned int dwc3_gadget_imod_val; +module_param(dwc3_gadget_imod_val, int, 0644); +MODULE_PARM_DESC(dwc3_gadget_imod_val, + "Interrupt moderation in usecs for normal EPs"); + /* XHCI registers */ #define USB3_HCSPARAMS1 (0x4) #define USB3_HCCPARAMS2 (0x1c) @@ -120,6 +126,12 @@ MODULE_PARM_DESC(cpu_to_affin, "affin usb irq to this cpu"); #define GSI_RING_BASE_ADDR_L(n) ((QSCRATCH_REG_OFFSET + 0x130) + (n*4)) #define GSI_RING_BASE_ADDR_H(n) ((QSCRATCH_REG_OFFSET + 0x144) + (n*4)) +#define IMOD(n) ((QSCRATCH_REG_OFFSET + 0x170) + (n*4)) +#define IMOD_EE_EN_MASK BIT(12) +#define IMOD_EE_CNT_MASK 0x7FF + +#define USEC_CNT (QSCRATCH_REG_OFFSET + 0x180) + #define GSI_IF_STS (QSCRATCH_REG_OFFSET + 0x1A4) #define GSI_WR_CTRL_STATE_MASK BIT(15) @@ -4405,9 +4417,22 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on) msm_dwc3_perf_vote_update(mdwc, true); schedule_delayed_work(&mdwc->perf_vote_work, msecs_to_jiffies(1000 * PM_QOS_SAMPLE_SEC)); + if (dwc3_gadget_imod_val > 0) { + dwc3_msm_write_reg(mdwc->base, USEC_CNT, 0x7D); + dwc3_msm_write_reg_field(mdwc->base, IMOD(0), + IMOD_EE_CNT_MASK, + dwc3_gadget_imod_val); + dwc3_msm_write_reg_field(mdwc->base, IMOD(0), + IMOD_EE_EN_MASK, 0x1); + } } else { dev_dbg(mdwc->dev, "%s: turn off gadget %s\n", __func__, dwc->gadget.name); + dwc3_msm_write_reg_field(mdwc->base, IMOD(0), + IMOD_EE_EN_MASK, 0x0); + dwc3_msm_write_reg_field(mdwc->base, IMOD(0), + IMOD_EE_CNT_MASK, 0x0); + dwc3_msm_write_reg(mdwc->base, USEC_CNT, 0x0); cancel_delayed_work_sync(&mdwc->perf_vote_work); msm_dwc3_perf_vote_update(mdwc, false); pm_qos_remove_request(&mdwc->pm_qos_req_dma); From 3feb18e373df68bd1befcaf63afaf1ba79b6a9be Mon Sep 17 00:00:00 2001 From: Kiran Gunda Date: Wed, 31 Jul 2019 14:37:58 +0530 Subject: [PATCH 238/281] ARM: dts: msm: Correct the smpa1 regulator label for sdm429w Correct the smpa1 regulator label from "regulator-s2" to "regulator-s1". Change-Id: I48ed64734a96e204896e5e3ad402e84b10386dcd Signed-off-by: Kiran Gunda --- arch/arm64/boot/dts/qcom/pm660-rpm-regulator.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/pm660-rpm-regulator.dtsi b/arch/arm64/boot/dts/qcom/pm660-rpm-regulator.dtsi index 6d384fc794c8..010694d02938 100644 --- a/arch/arm64/boot/dts/qcom/pm660-rpm-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/pm660-rpm-regulator.dtsi @@ -19,9 +19,9 @@ qcom,hpm-min-load = <100000>; status = "disabled"; - regulator-s2 { + regulator-s1 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pm660_s2"; + regulator-name = "pm660_s1"; qcom,set = <3>; status = "disabled"; }; From 0ec0af08ed5b06daeb9f3daba26a67b6496bda13 Mon Sep 17 00:00:00 2001 From: Pavankumar Vijapur Date: Thu, 1 Aug 2019 20:45:03 +0530 Subject: [PATCH 239/281] defconfig: sa415m: Make event driver as DLKM Make event driver as dynamically loadable kernel module. Change-Id: I947901b4b18c2ec3b3f05ca652e956bce14de7f7 Signed-off-by: Pavankumar Vijapur --- arch/arm/configs/sa415m-perf_defconfig | 2 +- arch/arm/configs/sa415m_defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/configs/sa415m-perf_defconfig b/arch/arm/configs/sa415m-perf_defconfig index a5170207954f..5a9b777ec74b 100644 --- a/arch/arm/configs/sa415m-perf_defconfig +++ b/arch/arm/configs/sa415m-perf_defconfig @@ -229,7 +229,7 @@ CONFIG_CLD_HL_SDIO_CORE=y CONFIG_CLD_LL_CORE=y CONFIG_CNSS_GENL=y # CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_MISC=y diff --git a/arch/arm/configs/sa415m_defconfig b/arch/arm/configs/sa415m_defconfig index e10d4ef1bf15..604602396195 100644 --- a/arch/arm/configs/sa415m_defconfig +++ b/arch/arm/configs/sa415m_defconfig @@ -230,7 +230,7 @@ CONFIG_CLD_HL_SDIO_CORE=y CONFIG_CLD_LL_CORE=y CONFIG_CNSS_GENL=y # CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_MISC=y From 7c96c83ce1f2370d19b87e2b6c1740a60c35d31b Mon Sep 17 00:00:00 2001 From: Raja Mallik Date: Mon, 5 Aug 2019 14:40:23 +0530 Subject: [PATCH 240/281] Merge remote-tracking branch 'dev/msm-4.14' into msm-4.9 07/19 * commit '358fc0a19fa18647de4882ec12931b999dd42118': msm: camera: util: Enabling logs to improve debugging msm: camera: cpas: logs added in the failure case for stop hw msm: camera: Print mem handle index and io config index msm: camera: isp: notify boot time stamp with precision msm: camera: reqmgr: Verify the req of two links msm: camera: reqmgr: Add initial sync support Change-Id: If15347cd3de17ac2e9933d3c07969209bd7f9c1a Signed-off-by: Raja Mallik --- .../msm/camera_v3/cam_cpas/cam_cpas_hw.c | 16 +- .../camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c | 6 +- .../cam_icp/icp_hw/bps_hw/bps_core.c | 6 +- .../icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c | 7 +- .../cam_icp/icp_hw/ipe_hw/ipe_core.c | 6 +- .../msm/camera_v3/cam_isp/cam_isp_context.c | 38 +++- .../msm/camera_v3/cam_isp/cam_isp_context.h | 4 + .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 69 ++++---- .../hw_utils/cam_isp_packet_parser.c | 14 +- .../isp_hw/ife_csid_hw/cam_ife_csid_core.c | 16 +- .../isp_hw/ife_csid_hw/cam_ife_csid_core.h | 2 + .../cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c | 7 +- .../camera_v3/cam_req_mgr/cam_req_mgr_core.c | 167 +++++++++++++++++- .../camera_v3/cam_req_mgr/cam_req_mgr_core.h | 10 +- .../cam_req_mgr/cam_req_mgr_interface.h | 2 + .../cam_sensor_module/cam_cci/cam_cci_soc.c | 4 +- .../cam_csiphy/cam_csiphy_core.c | 20 ++- .../msm/camera_v3/cam_utils/cam_packet_util.c | 52 +++++- 18 files changed, 370 insertions(+), 76 deletions(-) diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c index a68032cf6c19..a68e20745b1a 100644 --- a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c +++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c @@ -980,8 +980,10 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args, return -EINVAL; } - if (!CAM_CPAS_CLIENT_VALID(client_indx)) + if (!CAM_CPAS_CLIENT_VALID(client_indx)) { + CAM_ERR(CAM_CPAS, "Client index invalid %d", client_indx); return -EINVAL; + } mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); @@ -1099,8 +1101,10 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args, cmd_hw_stop = (struct cam_cpas_hw_cmd_stop *)stop_args; client_indx = CAM_CPAS_GET_CLIENT_IDX(cmd_hw_stop->client_handle); - if (!CAM_CPAS_CLIENT_VALID(client_indx)) + if (!CAM_CPAS_CLIENT_VALID(client_indx)) { + CAM_ERR(CAM_CPAS, "Client index invalid %d", client_indx); return -EINVAL; + } mutex_lock(&cpas_hw->hw_mutex); mutex_lock(&cpas_core->client_mutex[client_indx]); @@ -1162,14 +1166,20 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args, ahb_vote.vote.level = CAM_SUSPEND_VOTE; rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, cpas_client, &ahb_vote, NULL); - if (rc) + if (rc) { + CAM_ERR(CAM_CPAS, "ahb vote failed for %s rc %d", + cpas_client->data.identifier, rc); goto done; + } axi_vote.uncompressed_bw = 0; axi_vote.compressed_bw = 0; axi_vote.compressed_bw_ab = 0; rc = cam_cpas_util_apply_client_axi_vote(cpas_hw, cpas_client, &axi_vote); + if (rc) + CAM_ERR(CAM_CPAS, "axi vote failed for %s rc %d", + cpas_client->data.identifier, rc); done: mutex_unlock(&cpas_core->client_mutex[client_indx]); diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c index e13d7f2edcee..4dbc8f1bd991 100644 --- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c @@ -464,7 +464,11 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ICP_A5_CMD_CPAS_STOP: if (core_info->cpas_start) { - cam_cpas_stop(core_info->cpas_handle); + rc = cam_cpas_stop(core_info->cpas_handle); + if (rc) { + CAM_ERR(CAM_ICP, "cpas stop failed %d", rc); + return rc; + } core_info->cpas_start = false; } break; diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/bps_hw/bps_core.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/bps_hw/bps_core.c index c94276ce8778..f522f7138765 100644 --- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/bps_hw/bps_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/bps_hw/bps_core.c @@ -347,7 +347,11 @@ int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ICP_BPS_CMD_CPAS_STOP: if (core_info->cpas_start) { - cam_cpas_stop(core_info->cpas_handle); + rc = cam_cpas_stop(core_info->cpas_handle); + if (rc) { + CAM_ERR(CAM_ICP, "cpas stop failed %d", rc); + return rc; + } core_info->cpas_start = false; } break; diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index cfc474afc633..03b93acbd847 100644 --- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -4077,8 +4077,13 @@ static void cam_icp_mgr_print_io_bufs(struct cam_packet *packet, for (i = 0; i < packet->num_io_configs; i++) { for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { - if (!io_cfg[i].mem_handle[j]) + if (!io_cfg[i].mem_handle[j]) { + CAM_ERR(CAM_ICP, + "Mem Handle %d is NULL for %d io config", + j, i); break; + } + if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) == GET_FD_FROM_HANDLE(pf_buf_info)) { diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/ipe_hw/ipe_core.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/ipe_hw/ipe_core.c index ae3d1343c1c4..ae58b34062d6 100644 --- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/ipe_hw/ipe_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/ipe_hw/ipe_core.c @@ -342,7 +342,11 @@ int cam_ipe_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ICP_IPE_CMD_CPAS_STOP: if (core_info->cpas_start) { - cam_cpas_stop(core_info->cpas_handle); + rc = cam_cpas_stop(core_info->cpas_handle); + if (rc) { + CAM_ERR(CAM_ICP, "CPAS stop failed %d", rc); + return rc; + } core_info->cpas_start = false; } break; diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c index 1eb7389b2516..94d531d3d80f 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c @@ -571,21 +571,24 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( static void __cam_isp_ctx_send_sof_boot_timestamp( struct cam_isp_context *ctx_isp, uint64_t request_id, - uint32_t sof_event_status) + uint32_t sof_event_status, uint64_t delta_ts) { struct cam_req_mgr_message req_msg; req_msg.session_hdl = ctx_isp->base->session_hdl; req_msg.u.frame_msg.frame_id = ctx_isp->frame_id; req_msg.u.frame_msg.request_id = request_id; - req_msg.u.frame_msg.timestamp = ctx_isp->boot_timestamp; req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl; req_msg.u.frame_msg.sof_status = sof_event_status; + req_msg.u.frame_msg.timestamp = ctx_isp->prev_boot_timestamp + delta_ts; + CAM_DBG(CAM_ISP, - "request id:%lld frame number:%lld boot time stamp:0x%llx", - request_id, ctx_isp->frame_id, - ctx_isp->boot_timestamp); + "req id:%lld frame num:%lld bt_ts:0x%llx pre_bt_ts:0x%llx diff:0x%llx", + request_id, ctx_isp->frame_id, + ctx_isp->boot_timestamp, ctx_isp->prev_boot_timestamp, + delta_ts); + if (cam_req_mgr_notify_message(&req_msg, V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS, @@ -593,6 +596,8 @@ static void __cam_isp_ctx_send_sof_boot_timestamp( CAM_ERR(CAM_ISP, "Error in notifying the boot time for req id:%lld", request_id); + + ctx_isp->prev_boot_timestamp = req_msg.u.frame_msg.timestamp; } @@ -601,6 +606,7 @@ static void __cam_isp_ctx_send_sof_timestamp( uint32_t sof_event_status) { struct cam_req_mgr_message req_msg; + uint64_t delta_ts; req_msg.session_hdl = ctx_isp->base->session_hdl; req_msg.u.frame_msg.frame_id = ctx_isp->frame_id; @@ -610,9 +616,9 @@ static void __cam_isp_ctx_send_sof_timestamp( req_msg.u.frame_msg.sof_status = sof_event_status; CAM_DBG(CAM_ISP, - "request id:%lld frame number:%lld SOF time stamp:0x%llx", + "request id:%lld frame number:%lld SOF time stamp:0x%llx, Prev SOF time:0x%llx", request_id, ctx_isp->frame_id, - ctx_isp->sof_timestamp_val); + ctx_isp->sof_timestamp_val, ctx_isp->prev_sof_timestamp_val); CAM_DBG(CAM_ISP, "sof status:%d", sof_event_status); if (cam_req_mgr_notify_message(&req_msg, @@ -620,9 +626,17 @@ static void __cam_isp_ctx_send_sof_timestamp( CAM_ERR(CAM_ISP, "Error in notifying the sof time for req id:%lld", request_id); + delta_ts = ctx_isp->sof_timestamp_val - + ctx_isp->prev_sof_timestamp_val; __cam_isp_ctx_send_sof_boot_timestamp(ctx_isp, - request_id, sof_event_status); + request_id, sof_event_status, + (ctx_isp->prev_sof_timestamp_val == 0) ? + ctx_isp->boot_timestamp : + delta_ts); + + ctx_isp->prev_sof_timestamp_val = + ctx_isp->sof_timestamp_val; } @@ -703,6 +717,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld ctx %u", @@ -1335,6 +1350,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", @@ -1512,6 +1528,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", @@ -2100,6 +2117,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", @@ -2291,6 +2309,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", @@ -2361,6 +2380,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; + notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", @@ -3383,6 +3403,8 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( ctx_isp->req_info.last_applied_time_stamp = 0; ctx_isp->req_info.last_bufdone_time_stamp = 0; ctx_isp->req_info.last_reported_id_time_stamp = 0; + ctx_isp->prev_sof_timestamp_val = 0; + ctx_isp->prev_boot_timestamp = 0; atomic_set(&ctx_isp->process_bubble, 0); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h index bec84a85391c..a4f4e5ae0ee9 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h @@ -165,7 +165,9 @@ struct cam_isp_context_req_id_info { * @req_isp: ISP private request object storage * @hw_ctx: HW object returned by the acquire device command * @sof_timestamp_val: Captured time stamp value at sof hw event + * @prev_sof_timestamp_val Holds last notified sof time stamp * @boot_timestamp: Boot time stamp for a given req_id + * @prev_boot_timestamp Holds last notified boot time stamp * @active_req_cnt: Counter for the active request * @subscribe_event: The irq event mask that CRM subscribes to, IFE * will invoke CRM cb at those event. @@ -194,7 +196,9 @@ struct cam_isp_context { void *hw_ctx; uint64_t sof_timestamp_val; + uint64_t prev_sof_timestamp_val; uint64_t boot_timestamp; + uint64_t prev_boot_timestamp; int32_t active_req_cnt; uint32_t subscribe_event; atomic64_t state_monitor_head; diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 9b4839261c3e..cfc902af7a2b 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -4097,8 +4097,12 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet, for (i = 0; i < packet->num_io_configs; i++) { for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { - if (!io_cfg[i].mem_handle[j]) + if (!io_cfg[i].mem_handle[j]) { + CAM_ERR(CAM_ISP, + "Mem Handle %d is NULL for %d io config", + j, i); break; + } if (pf_buf_info && GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) == @@ -4261,45 +4265,44 @@ static int cam_ife_mgr_cmd_get_sof_timestamp( struct cam_hw_intf *hw_intf; struct cam_csid_get_time_stamp_args csid_get_time; - list_for_each_entry(hw_mgr_res, &ife_ctx->res_list_ife_csid, list) { - for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { - if (!hw_mgr_res->hw_res[i]) - continue; + hw_mgr_res = list_first_entry(&ife_ctx->res_list_ife_csid, + struct cam_ife_hw_mgr_res, list); + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + /* + * Get the SOF time stamp from left resource only. + * Left resource is master for dual vfe case and + * Rdi only context case left resource only hold + * the RDI resource + */ + + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf->hw_ops.process_cmd) { /* - * Get the SOF time stamp from left resource only. - * Left resource is master for dual vfe case and - * Rdi only context case left resource only hold - * the RDI resource + * Single VFE case, Get the time stamp from + * available one csid hw in the context + * Dual VFE case, get the time stamp from + * master(left) would be sufficient */ - hw_intf = hw_mgr_res->hw_res[i]->hw_intf; - if (hw_intf->hw_ops.process_cmd) { - /* - * Single VFE case, Get the time stamp from - * available one csid hw in the context - * Dual VFE case, get the time stamp from - * master(left) would be sufficient - */ - - csid_get_time.node_res = - hw_mgr_res->hw_res[i]; - rc = hw_intf->hw_ops.process_cmd( - hw_intf->hw_priv, - CAM_IFE_CSID_CMD_GET_TIME_STAMP, - &csid_get_time, - sizeof( - struct cam_csid_get_time_stamp_args)); - if (!rc && (i == CAM_ISP_HW_SPLIT_LEFT)) { - *time_stamp = - csid_get_time.time_stamp_val; - *boot_time_stamp = - csid_get_time.boot_timestamp; - } + csid_get_time.node_res = + hw_mgr_res->hw_res[i]; + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_IFE_CSID_CMD_GET_TIME_STAMP, + &csid_get_time, + sizeof( + struct cam_csid_get_time_stamp_args)); + if (!rc && (i == CAM_ISP_HW_SPLIT_LEFT)) { + *time_stamp = + csid_get_time.time_stamp_val; + *boot_time_stamp = + csid_get_time.boot_timestamp; } } } - if (rc) CAM_ERR(CAM_ISP, "Getting sof time stamp failed"); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index 5efab9f289dd..21f67bac9efe 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -491,7 +491,7 @@ int cam_isp_add_io_buffers( CAM_DBG(CAM_ISP, "======= io config idx %d ============", i); CAM_DBG(CAM_REQ, "i %d req_id %llu resource_type:%d fence:%d direction %d", - i, prepare->packet->header.request_id, + i, req_id, io_cfg[i].resource_type, io_cfg[i].fence, io_cfg[i].direction); CAM_DBG(CAM_ISP, "format: %d", io_cfg[i].format); @@ -618,8 +618,16 @@ int cam_isp_add_io_buffers( mmu_hdl, &io_addr[plane_id], &size); if (rc) { CAM_ERR(CAM_ISP, - "no io addr for plane%d", - plane_id); + "no io addr for plane%d Bufhdl:%d, Size =%d", + plane_id, + io_cfg[i].mem_handle[plane_id], + (int)size); + CAM_ERR(CAM_ISP, + "Port i %d Reqid %llu res_type:%d fence:%d dir %d", + i, req_id, + io_cfg[i].resource_type, + io_cfg[i].fence, + io_cfg[i].direction); rc = -ENOMEM; return rc; } diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index 5610f6d267ff..3431a640ed79 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -467,6 +467,7 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw) CAM_ERR(CAM_ISP, "CSID:%d IRQ value after reset rc = %d", csid_hw->hw_intf->hw_idx, val); csid_hw->error_irq_count = 0; + csid_hw->first_sof_ts = 0; for (i = 0 ; i < CAM_IFE_PIX_PATH_RES_MAX; i++) csid_hw->res_sof_cnt[i] = 0; @@ -1167,6 +1168,7 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; csid_hw->error_irq_count = 0; + csid_hw->first_sof_ts = 0; return rc; } @@ -2454,9 +2456,16 @@ static int cam_ife_csid_get_time_stamp( CAM_IFE_CSID_QTIMER_MUL_FACTOR, CAM_IFE_CSID_QTIMER_DIV_FACTOR); - get_monotonic_boottime64(&ts); - time_stamp->boot_timestamp = (uint64_t)((ts.tv_sec * 1000000000) + - ts.tv_nsec); + if (!csid_hw->first_sof_ts) { + get_monotonic_boottime64(&ts); + time_stamp->boot_timestamp = + (uint64_t)((ts.tv_sec * 1000000000) + + ts.tv_nsec); + CAM_DBG(CAM_ISP, "timestamp:%lld", + time_stamp->boot_timestamp); + csid_hw->first_sof_ts = 1; + } else + time_stamp->boot_timestamp = 0; return 0; } @@ -3737,6 +3746,7 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, ife_csid_hw->csid_debug = 0; ife_csid_hw->error_irq_count = 0; + ife_csid_hw->first_sof_ts = 0; return 0; err: diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h index 600deb245f32..9b4d5c3d6add 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h @@ -480,6 +480,7 @@ struct cam_ife_csid_path_cfg { * @init_frame_drop Initial frame drop number * @res_sof_cnt path resource sof count value. it used for initial * frame drop + * @first_sof_ts flag to mark the first sof has been registered * */ struct cam_ife_csid_hw { @@ -511,6 +512,7 @@ struct cam_ife_csid_hw { uint32_t dual_usage; uint32_t init_frame_drop; uint32_t res_sof_cnt[CAM_IFE_PIX_PATH_RES_MAX]; + uint32_t first_sof_ts; }; int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, diff --git a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index f7b42d5a7699..1a3a7cb38878 100644 --- a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -634,8 +634,13 @@ static void cam_jpeg_mgr_print_io_bufs(struct cam_packet *packet, for (i = 0; i < packet->num_io_configs; i++) { for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { - if (!io_cfg[i].mem_handle[j]) + if (!io_cfg[i].mem_handle[j]) { + CAM_ERR(CAM_JPEG, + "Mem Handle %d is NULL for %d io config", + j, i); break; + } + if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) == GET_FD_FROM_HANDLE(pf_buf_info)) { diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c index c8e2a023b0d4..b2994d52d83c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c @@ -48,6 +48,9 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) link->last_flush_id = 0; link->initial_sync_req = -1; link->in_msync_mode = false; + link->initial_skip = true; + link->sof_timestamp = 0; + link->prev_sof_timestamp = 0; } void cam_req_mgr_handle_core_shutdown(void) @@ -609,6 +612,19 @@ static int __cam_req_mgr_check_link_is_ready(struct cam_req_mgr_core_link *link, traverse_data.validate_only = validate_only; traverse_data.open_req_cnt = link->open_req_cnt; + /* + * Some no-sync mode requests are processed after link config, + * then process the sync mode requests after no-sync mode requests + * are handled, the initial_skip should be false when processing + * the sync mode requests. + */ + if (link->initial_skip) { + CAM_DBG(CAM_CRM, + "Set initial_skip to false for link %x", + link->link_hdl); + link->initial_skip = false; + } + /* * Traverse through all pd tables, if result is success, * apply the settings @@ -894,9 +910,11 @@ static int __cam_req_mgr_check_sync_req_is_ready( struct cam_req_mgr_slot *slot) { struct cam_req_mgr_core_link *sync_link = NULL; - int64_t req_id = 0; + struct cam_req_mgr_slot *sync_rd_slot = NULL; + int64_t req_id = 0, sync_req_id = 0; int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0; int32_t sync_num_slots = 0; + uint64_t sync_frame_duration = 0; bool ready = true, sync_ready = true; if (!link->sync_link) { @@ -907,11 +925,65 @@ static int __cam_req_mgr_check_sync_req_is_ready( sync_link = link->sync_link; req_id = slot->req_id; sync_num_slots = sync_link->req.in_q->num_slots; + sync_rd_idx = sync_link->req.in_q->rd_idx; + sync_rd_slot = &sync_link->req.in_q->slot[sync_rd_idx]; + sync_req_id = sync_rd_slot->req_id; CAM_DBG(CAM_REQ, "link_hdl %x req %lld frame_skip_flag %d ", link->link_hdl, req_id, link->sync_link_sof_skip); + if (sync_link->initial_skip) { + link->initial_skip = false; + __cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx); + CAM_DBG(CAM_CRM, + "sync link %x not streamed on", + sync_link->link_hdl); + return -EAGAIN; + } + + if (sync_link->prev_sof_timestamp) + sync_frame_duration = sync_link->sof_timestamp + - sync_link->prev_sof_timestamp; + else + sync_frame_duration = DEFAULT_FRAME_DURATION; + + CAM_DBG(CAM_CRM, + "sync link %x last frame duration is %d ns", + sync_link->link_hdl, sync_frame_duration); + + if (link->initial_skip) { + link->initial_skip = false; + + if (link->sof_timestamp > sync_link->sof_timestamp && + sync_link->sof_timestamp > 0 && + link->sof_timestamp - sync_link->sof_timestamp < + sync_frame_duration / 2) { + /* + * If this frame sync with the previous frame of sync + * link, then we need to skip this frame, since the + * previous frame of sync link is also skipped. + */ + __cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx); + CAM_DBG(CAM_CRM, + "This frame sync with previous sync_link %x frame", + sync_link->link_hdl); + return -EAGAIN; + } else if (link->sof_timestamp <= sync_link->sof_timestamp) { + /* + * Sometimes, link receives the SOF event is eariler + * than sync link in IFE CSID side, but link's SOF + * event is processed later than sync link's, then + * we need to skip this SOF event since the sync + * link's SOF event is also skipped. + */ + __cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx); + CAM_DBG(CAM_CRM, + "The previous frame of sync link is skipped"); + return -EAGAIN; + } + } + if (sync_link->sync_link_sof_skip) { CAM_DBG(CAM_REQ, "No req applied on corresponding SOF on sync link: %x", @@ -937,12 +1009,11 @@ static int __cam_req_mgr_check_sync_req_is_ready( sync_ready = false; } - sync_rd_idx = sync_link->req.in_q->rd_idx; if ((sync_link->req.in_q->slot[sync_slot_idx].status != CRM_SLOT_STATUS_REQ_APPLIED) && (((sync_slot_idx - sync_rd_idx + sync_num_slots) % sync_num_slots) >= 1) && - (sync_link->req.in_q->slot[sync_rd_idx].status != + (sync_rd_slot->status != CRM_SLOT_STATUS_REQ_APPLIED)) { CAM_DBG(CAM_CRM, "Req: %lld [other link] not next req to be applied on link: %x", @@ -975,7 +1046,15 @@ static int __cam_req_mgr_check_sync_req_is_ready( CAM_DBG(CAM_CRM, "Req: %lld ready %d sync_ready %d, ignore sync link next SOF", req_id, ready, sync_ready); - link->sync_link_sof_skip = true; + + /* + * Only skip the frames if current frame sync with + * next frame of sync link. + */ + if (link->sof_timestamp - sync_link->sof_timestamp > + sync_frame_duration / 2) + link->sync_link_sof_skip = true; + return -EINVAL; } else if (ready == false) { CAM_DBG(CAM_CRM, @@ -984,6 +1063,61 @@ static int __cam_req_mgr_check_sync_req_is_ready( return -EINVAL; } + /* + * Do the self-correction when the frames are sync, + * we consider that the frames are synced if the + * difference of two SOF timestamp less than + * (sync_frame_duration / 5). + */ + if ((link->sof_timestamp > sync_link->sof_timestamp) && + (sync_link->sof_timestamp > 0) && + (link->sof_timestamp - sync_link->sof_timestamp < + sync_frame_duration / 5) && + (sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) { + + /* + * This means current frame should sync with next + * frame of sync link, then the request id of in + * rd slot of two links should be same. + */ + CAM_DBG(CAM_CRM, + "link %x req_id %lld, sync_link %x req_id %lld", + link->link_hdl, req_id, + sync_link->link_hdl, sync_req_id); + + if (req_id > sync_req_id) { + CAM_DBG(CAM_CRM, + "link %x too quickly, skip this frame", + link->link_hdl); + return -EAGAIN; + } else if (req_id < sync_req_id) { + CAM_DBG(CAM_CRM, + "sync link %x too quickly, skip next frame of sync link", + sync_link->link_hdl); + link->sync_link_sof_skip = true; + } + } else if ((sync_link->sof_timestamp > 0) && + (link->sof_timestamp < sync_link->sof_timestamp) && + (sync_link->sof_timestamp - link->sof_timestamp < + sync_frame_duration / 5) && + (sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) { + + /* + * There is a timing issue once enter this condition, + * it means link receives the SOF event earlier than + * sync link in IFE CSID side, but the process in CRM + * is sync_link earlier than link, then previous SOF + * event of sync link is skipped, so we also need to + * skip this SOF event. + */ + if (req_id >= sync_req_id) { + CAM_DBG(CAM_CRM, + "Timing issue, the sof event of link %x is delayed", + link->link_hdl); + return -EAGAIN; + } + } + CAM_DBG(CAM_REQ, "Req: %lld ready to apply on link: %x [validation successful]", req_id, link->link_hdl); @@ -1011,10 +1145,11 @@ static int __cam_req_mgr_check_sync_req_is_ready( * */ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, - uint32_t trigger) + struct cam_req_mgr_trigger_notify *trigger_data) { int rc = 0, idx, last_app_idx; int reset_step = 0; + uint32_t trigger = trigger_data->trigger; struct cam_req_mgr_slot *slot = NULL; struct cam_req_mgr_req_queue *in_q; struct cam_req_mgr_core_session *session; @@ -1052,6 +1187,13 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, } if (trigger == CAM_TRIGGER_POINT_SOF) { + /* + * Update the timestamp in session lock protection + * to avoid timing issue. + */ + link->prev_sof_timestamp = link->sof_timestamp; + link->sof_timestamp = trigger_data->sof_timestamp_val; + if (link->trigger_mask) { CAM_ERR_RATE_LIMIT(CAM_CRM, "Applying for last EOF fails"); @@ -2141,7 +2283,7 @@ static int cam_req_mgr_process_trigger(void *priv, void *data) __cam_req_mgr_inc_idx(&in_q->rd_idx, 1, in_q->num_slots); } - rc = __cam_req_mgr_process_req(link, trigger_data->trigger); + rc = __cam_req_mgr_process_req(link, trigger_data); release_lock: mutex_unlock(&link->req.lock); @@ -2372,6 +2514,7 @@ static int cam_req_mgr_cb_notify_trigger( notify_trigger->link_hdl = trigger_data->link_hdl; notify_trigger->dev_hdl = trigger_data->dev_hdl; notify_trigger->trigger = trigger_data->trigger; + notify_trigger->sof_timestamp_val = trigger_data->sof_timestamp_val; task->process_cb = &cam_req_mgr_process_trigger; rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0); @@ -3125,8 +3268,6 @@ int cam_req_mgr_sync_config( link1->is_master = false; link2->is_master = false; - link1->initial_skip = false; - link2->initial_skip = false; link1->in_msync_mode = false; link2->in_msync_mode = false; @@ -3137,6 +3278,16 @@ int cam_req_mgr_sync_config( link1->sync_link = link2; link2->sync_link = link1; __cam_req_mgr_set_master_link(link1, link2); + } else { + /* + * Reset below info after the mode is configured + * to NO-SYNC mode since they may be overridden + * if the sync config is invoked after SOF comes. + */ + link1->initial_skip = true; + link2->initial_skip = true; + link1->sof_timestamp = 0; + link2->sof_timestamp = 0; } cam_session->sync_mode = sync_info->sync_mode; diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h index 05fe0860bfa0..94f26dee8917 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h @@ -32,6 +32,9 @@ #define MAX_SYNC_COUNT 65535 +/* Default frame rate is 30 */ +#define DEFAULT_FRAME_DURATION 33333333 + #define SYNC_LINK_SOF_CNT_MAX_LMT 1 #define MAXIMUM_LINKS_PER_SESSION 4 @@ -321,7 +324,10 @@ struct cam_req_mgr_connected_device { * master-slave sync * @in_msync_mode : Flag to determine if a link is in master-slave mode * @initial_sync_req : The initial req which is required to sync with the - * other link + * other link, it means current hasn't receive any + * stream after streamon if it is true + * @sof_timestamp_value : SOF timestamp value + * @prev_sof_timestamp : Previous SOF timestamp value * */ struct cam_req_mgr_core_link { @@ -349,6 +355,8 @@ struct cam_req_mgr_core_link { bool initial_skip; bool in_msync_mode; int64_t initial_sync_req; + uint64_t sof_timestamp; + uint64_t prev_sof_timestamp; }; /** diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h index 1d1df45c6ea5..934bc76014a5 100644 --- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h +++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h @@ -201,12 +201,14 @@ enum cam_req_mgr_link_evt_type { * @frame_id : frame id for internal tracking * @trigger : trigger point of this notification, CRM will send apply * only to the devices which subscribe to this point. + * @sof_timestamp_val: Captured time stamp value at sof hw event */ struct cam_req_mgr_trigger_notify { int32_t link_hdl; int32_t dev_hdl; int64_t frame_id; uint32_t trigger; + uint64_t sof_timestamp_val; }; /** diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c index 0181a4d8e2ff..f66d86ce091e 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c @@ -410,7 +410,9 @@ int cam_cci_soc_release(struct cci_device *cci_dev) cci_dev->cci_state = CCI_STATE_DISABLED; cci_dev->cycles_per_us = 0; - cam_cpas_stop(cci_dev->cpas_handle); + rc = cam_cpas_stop(cci_dev->cpas_handle); + if (rc) + CAM_ERR(CAM_CCI, "cpas stop failed %d", rc); return rc; } diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index 8074ecd9112a..b8605596aa6c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -551,7 +551,7 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev) void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev) { struct cam_hw_soc_info *soc_info; - int32_t i = 0; + int32_t i = 0, rc = 0; if (csiphy_dev->csiphy_state == CAM_CSIPHY_INIT) return; @@ -574,7 +574,10 @@ void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev) cam_csiphy_reset(csiphy_dev); cam_soc_util_disable_platform_resource(soc_info, true, true); - cam_cpas_stop(csiphy_dev->cpas_handle); + rc = cam_cpas_stop(csiphy_dev->cpas_handle); + if (rc) + CAM_ERR(CAM_CSIPHY, "cpas stop failed %d", rc); + csiphy_dev->csiphy_state = CAM_CSIPHY_ACQUIRE; } @@ -934,7 +937,10 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, if (rc < 0) { csiphy_dev->csiphy_info.secure_mode[offset] = CAM_SECURE_MODE_NON_SECURE; - cam_cpas_stop(csiphy_dev->cpas_handle); + rc = cam_cpas_stop(csiphy_dev->cpas_handle); + if (rc < 0) + CAM_ERR(CAM_CSIPHY, + "de-voting CPAS: %d", rc); goto release_mutex; } } @@ -942,7 +948,9 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, rc = cam_csiphy_enable_hw(csiphy_dev); if (rc != 0) { CAM_ERR(CAM_CSIPHY, "cam_csiphy_enable_hw failed"); - cam_cpas_stop(csiphy_dev->cpas_handle); + rc = cam_cpas_stop(csiphy_dev->cpas_handle); + if (rc < 0) + CAM_ERR(CAM_CSIPHY, "de-voting CPAS: %d", rc); goto release_mutex; } rc = cam_csiphy_config_dev(csiphy_dev); @@ -952,7 +960,9 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, if (rc < 0) { CAM_ERR(CAM_CSIPHY, "cam_csiphy_config_dev failed"); cam_csiphy_disable_hw(csiphy_dev); - cam_cpas_stop(csiphy_dev->cpas_handle); + rc = cam_cpas_stop(csiphy_dev->cpas_handle); + if (rc < 0) + CAM_ERR(CAM_CSIPHY, "de-voting CPAS: %d", rc); goto release_mutex; } csiphy_dev->start_dev_count++; diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c index 3708c212d57b..185e0608e547 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c @@ -182,11 +182,15 @@ int cam_packet_util_process_patches(struct cam_packet *packet, int i; int rc = 0; int32_t hdl; + uint64_t requestId; + uint32_t num_patches; /* process patch descriptor */ patch_desc = (struct cam_patch_desc *) ((uint32_t *) &packet->payload + packet->patch_offset/4); + requestId = packet->header.request_id; + num_patches = packet->num_patches; CAM_DBG(CAM_UTIL, "packet = %pK patch_desc = %pK size = %lu", (void *)packet, (void *)patch_desc, sizeof(struct cam_patch_desc)); @@ -197,7 +201,16 @@ int cam_packet_util_process_patches(struct cam_packet *packet, rc = cam_mem_get_io_buf(patch_desc[i].src_buf_hdl, hdl, &iova_addr, &src_buf_size); if (rc < 0) { - CAM_ERR(CAM_UTIL, "unable to get src buf address"); + CAM_ERR(CAM_UTIL, + "unable to get src buf address ReqId: %llu, num_patches = %d", + requestId, num_patches); + CAM_ERR(CAM_UTIL, + "i = %d patch info = %x %x %x %x src_bfsz:0x%x", + i, patch_desc[i].dst_buf_hdl, + patch_desc[i].dst_offset, + patch_desc[i].src_buf_hdl, + patch_desc[i].src_offset, + (uint32_t)src_buf_size); return rc; } src_buf_iova_addr = (uint32_t *)iova_addr; @@ -206,18 +219,37 @@ int cam_packet_util_process_patches(struct cam_packet *packet, rc = cam_mem_get_cpu_buf(patch_desc[i].dst_buf_hdl, &cpu_addr, &dst_buf_len); if (rc < 0 || !cpu_addr || (dst_buf_len == 0)) { - CAM_ERR(CAM_UTIL, "unable to get dst buf address"); + CAM_ERR(CAM_UTIL, + "unable to get dst buf address ReqId: %llu, num_patches = %d", + requestId, num_patches); + CAM_ERR(CAM_UTIL, + "i = %d patch info = %x %x %x %x dst_bfsz:0x%x", + i, patch_desc[i].dst_buf_hdl, + patch_desc[i].dst_offset, + patch_desc[i].src_buf_hdl, + patch_desc[i].src_offset, + (uint32_t)dst_buf_len); return rc; } dst_cpu_addr = (uint32_t *)cpu_addr; - CAM_DBG(CAM_UTIL, "i = %d patch info = %x %x %x %x", i, - patch_desc[i].dst_buf_hdl, patch_desc[i].dst_offset, + CAM_DBG(CAM_UTIL, + "ReqId: %llu, i = %d patch info = %x %x %x %x", + requestId, i, patch_desc[i].dst_buf_hdl, + patch_desc[i].dst_offset, patch_desc[i].src_buf_hdl, patch_desc[i].src_offset); if ((size_t)patch_desc[i].src_offset >= src_buf_size) { CAM_ERR(CAM_UTIL, - "Invalid src buf patch offset"); + "Invalid src buf patch offset ReqId: %llu, num_patches = %d", + requestId, num_patches); + CAM_ERR(CAM_UTIL, + "i = %d patch info = %x %x %x %x src_bfsz:0x%x", + i, patch_desc[i].dst_buf_hdl, + patch_desc[i].dst_offset, + patch_desc[i].src_buf_hdl, + patch_desc[i].src_offset, + (uint32_t)src_buf_size); return -EINVAL; } @@ -225,7 +257,15 @@ int cam_packet_util_process_patches(struct cam_packet *packet, ((dst_buf_len - sizeof(void *)) < (size_t)patch_desc[i].dst_offset)) { CAM_ERR(CAM_UTIL, - "Invalid dst buf patch offset"); + "Invalid dst buf patch offset ReqId: %llu, num_patches = %d", + requestId, num_patches); + CAM_ERR(CAM_UTIL, + "i = %d patch info = %x %x %x %x dst_bfsz:0x%x", + i, patch_desc[i].dst_buf_hdl, + patch_desc[i].dst_offset, + patch_desc[i].src_buf_hdl, + patch_desc[i].src_offset, + (uint32_t)dst_buf_len); return -EINVAL; } From dc86248a26bb0a109193d5f456813deff8b0614a Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Mon, 5 Aug 2019 20:02:19 +0530 Subject: [PATCH 241/281] fs: crypto: fix issue introduced with lts-integration Fix the perf issue introduced with wrong conflict resolution of 'commit 81b89766408b ("Merge android-4.9.175 (e2171b6) into msm-4.9")'. Change-Id: I3b368c5efd8e297bbe6b5c6e3ad12389a0edde7e Signed-off-by: Neeraj Soni --- fs/ext4/inode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b5e183744df0..8cb2298bdf6b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3624,8 +3624,9 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter) ssize_t ret; int rw = iov_iter_rw(iter); -#ifdef CONFIG_FS_ENCRYPTION - if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)) +#ifdef CONFIG_EXT4_FS_ENCRYPTION + if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) + && !fscrypt_using_hardware_encryption(inode)) return 0; #endif From ee17579ad418f83840f864721443fbf3ff5e76eb Mon Sep 17 00:00:00 2001 From: xiaolin Date: Tue, 13 Aug 2019 19:21:02 +0800 Subject: [PATCH 242/281] ARM: dts: Optimize the gpio status at RBSC The gpio67 and gpio91 are wrong pull status which will lead the power current leakage. So we need fix them and save power. Change-Id: I7a1f02eb3c549b95b72b6f3ef4d355c0e47d5cd1 Signed-off-by: xiaolin --- .../boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi index cc104988b351..05b16666857b 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi @@ -15,14 +15,46 @@ #include "sdm429-spyro-qrd-evt-camera.dtsi" #include "sdm429-spyro-qrd-evt-audio.dtsi" +&tlmm { + sd_eldo_active { + sd_eldo_active: sd_eldo_active { + mux { + pins = "gpio91"; + function = "gpio"; + }; + + config { + pins = "gpio91"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + sd_eldo_suspend { + sd_eldo_suspend: sd_eldo_suspend { + mux { + pins = "gpio91"; + function = "gpio"; + }; + + config { + pins = "gpio91"; + drive-strength = <2>; + bias-disable; + }; + }; + }; +}; + &gpio_key_active { mux { - pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; + pins = "gpio127", "gpio128", "gpio35", "gpio126"; function = "gpio"; }; config { - pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; + pins = "gpio127", "gpio128", "gpio35", "gpio126"; drive-strength = <2>; bias-pull-up; }; @@ -30,12 +62,12 @@ &gpio_key_suspend { mux { - pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; + pins = "gpio127", "gpio128", "gpio35", "gpio126"; function = "gpio"; }; config { - pins = "gpio91", "gpio127", "gpio128", "gpio35", "gpio126"; + pins = "gpio127", "gpio128", "gpio35", "gpio126"; drive-strength = <2>; bias-pull-up; }; @@ -124,8 +156,10 @@ qcom,vdd-io-current-level = <200 22000>; pinctrl-names = "active", "sleep"; - pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on + &sd_eldo_active>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off + &sd_eldo_suspend>; cd-gpios = <&tlmm 67 0x0>; From 212856ead7517012f8c226116716a803125f207e Mon Sep 17 00:00:00 2001 From: Jing Xue Date: Tue, 13 Aug 2019 15:28:03 +0800 Subject: [PATCH 243/281] ARM: dts: msm: add some zones and regulator cooling device for spyro all lowf thermal zone hasn't been build successfully because of the deleted property of cx_cdev.so add low_limits governor for some zones to cooling better when track low temp. and add pm660 cx regulator to cooling device. Change-Id: I402c0ce1bb70baf28c7883f30326381701eeacc1 Signed-off-by: Jing Xue --- .../boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi | 659 ++++++++++++++++++ .../boot/dts/qcom/sdm429w-regulator.dtsi | 8 + 2 files changed, 667 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi index a5a52c43188f..9eeaefb7c1d7 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi @@ -14,6 +14,7 @@ #include "sdm429-spyro-qrd-mdss-panels.dtsi" #include "sdm429-spyro-qrd-evt-camera.dtsi" #include "sdm429-spyro-qrd-evt-audio.dtsi" +#include &gpio_key_active { mux { @@ -400,3 +401,661 @@ }; }; + +&pm660_vadc { + chan@50 { + label = "pmic_therm"; + reg = <0x50>; + qcom,decimation = <2>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; +}; + +&pm660_adc_tm { + chan@50 { + label = "pmic_therm"; + reg = <0x50>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,btm-channel-number = <0x48>; + qcom,thermal-node; + }; +}; + +&thermal_zones { + + emmc-therm-adc { + status = "disabled"; + }; + + aoss0-lowf { + status = "disabled"; + }; + + mdm-core-lowf { + status = "disabled"; + }; + + lpass-lowf { + status = "disabled"; + }; + + camera-lowf { + status = "disabled"; + }; + + cpuss1-lowf { + status = "disabled"; + }; + + apc1-cpu0-lowf { + status = "disabled"; + }; + + apc1-cpu1-lowf { + status = "disabled"; + }; + + apc1-cpu2-lowf { + status = "disabled"; + }; + + apc1-cpu3-lowf { + status = "disabled"; + }; + + cpuss0-lowf { + status = "disabled"; + }; + + gpu-lowf { + status = "disabled"; + }; + + aoss0-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 0>; + tracks-low; + + trips { + aoss0_trip: aoss-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&aoss0_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + mdm-core-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 1>; + tracks-low; + + trips { + mdm_core_trip: mdm-core-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&mdm_core_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&mdm_core_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&mdm_core_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + lpass-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 2>; + tracks-low; + + trips { + qdsp_trip: qdsp-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&qdsp_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&qdsp_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&qdsp_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + camera-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 3>; + tracks-low; + + trips { + camera_trip: camera-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&camera_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&camera_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&camera_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + cpuss1-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 4>; + tracks-low; + + trips { + cpuss1_trip: cpuss1-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpuss1_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&cpuss1_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&cpuss1_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + apc1-cpu0-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 5>; + tracks-low; + + trips { + cpu0_trip: apc1-cpu0-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpu0_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&cpu0_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&cpu0_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + apc1-cpu1-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 6>; + tracks-low; + + trips { + cpu1_trip: apc1-cpu1-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpu1_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&cpu1_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&cpu1_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + apc1-cpu2-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 7>; + tracks-low; + + trips { + cpu2_trip: apc1-cpu2-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpu2_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&cpu2_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&cpu2_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + apc1-cpu3-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 8>; + tracks-low; + + trips { + cpu3_trip: apc1-cpu3-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpu3_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&cpu3_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&cpu3_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + cpuss0-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 9>; + tracks-low; + + trips { + cpuss0_lowf_trip: cpuss0-lowf-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&cpuss0_lowf_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&cpuss0_lowf_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&cpuss0_lowf_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + gpu-lowfr { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-governor = "low_limits_floor"; + thermal-sensors = <&tsens0 10>; + tracks-low; + + trips { + gpu_lowf_trip: gpu-lowf-trip { + temperature = <5000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + cpu0_vdd_cdev { + trip = <&gpu_lowf_trip>; + cooling-device = <&CPU0 (THERMAL_MAX_LIMIT-2) + (THERMAL_MAX_LIMIT-2)>; + }; + + cx_vdd_cdev { + trip = <&gpu_lowf_trip>; + cooling-device = <&pm660_cx_cdev 0 0>; + }; + + modem_vdd_cdev { + trip = <&gpu_lowf_trip>; + cooling-device = <&modem_vdd 0 0>; + }; + }; + }; + + camera-therm-adc { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&pm660_adc_tm 0x4e>; + wake-capable-sensor; + thermal-governor = "user_space"; + + trips { + active-config0 { + temperature = <65000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + pmic-therm-adc { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&pm660_adc_tm 0x50>; + wake-capable-sensor; + thermal-governor = "user_space"; + + trips { + active-config0 { + temperature = <65000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + quiet-therm-step { + polling-delay-passive = <1000>; + polling-delay = <0>; + thermal-sensors = <&pm660_adc_tm 0x51>; + thermal-governor = "step_wise"; + + trips { + quiet_batt_439_trip1: quiet-batt-trip1 { + temperature = <38000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_batt_439_trip2: quiet-batt-trip2 { + temperature = <40000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_batt_439_trip3: quiet-batt-trip3 { + temperature = <42000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_batt_439_trip4: quiet-batt-trip4 { + temperature = <44000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_modem_439_trip1: quiet-modem-trip0 { + temperature = <44000>; + hysteresis = <4000>; + type = "passive"; + }; + + quiet_modem_439_trip2: quiet-modem-trip1 { + temperature = <46000>; + hysteresis = <4000>; + type = "passive"; + }; + + quiet_batt_439_trip5: quiet-batt-trip5 { + temperature = <46000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_439_batt_trip6_mdm_trip3: quiet-bt-trp6-mdm-trp3 { + temperature = <48000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_cpus_439_trip: quiet-cpus-trip { + temperature = <48000>; + hysteresis = <0>; + type = "passive"; + }; + + quiet_gpu_439_trip: quiet-gpu-trip { + temperature = <50000>; + hysteresis = <0>; + type = "passive"; + }; + + quiet_batt_439_trip7: quiet-batt-trip7 { + temperature = <50000>; + hysteresis = <2000>; + type = "passive"; + }; + + quiet_modem_439_trip4: quiet-modem-trip3 { + temperature = <55000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + + cooling-maps { + skin_cpu0 { + trip = <&quiet_cpus_439_trip>; + /* throttle from fmax to 1497600KHz */ + cooling-device = <&CPU0 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-3)>; + }; + + skin_cpu1 { + trip = <&quiet_cpus_439_trip>; + cooling-device = <&CPU1 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-3)>; + }; + + skin_cpu2 { + trip = <&quiet_cpus_439_trip>; + cooling-device = <&CPU2 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-3)>; + }; + + skin_cpu3 { + trip = <&quiet_cpus_439_trip>; + cooling-device = <&CPU3 THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-3)>; + }; + + skin_gpu { + trip = <&quiet_gpu_439_trip>; + /* throttle from fmax to 510000000Hz */ + cooling-device = <&msm_gpu THERMAL_NO_LIMIT + (THERMAL_MAX_LIMIT-2)>; + }; + + modem_proc_lvl1 { + trip = <&quiet_modem_439_trip1>; + cooling-device = <&modem_proc 1 1>; + }; + + modem_proc_lvl2 { + trip = <&quiet_modem_439_trip4>; + cooling-device = <&modem_proc 3 3>; + }; + + modem_lvl1 { + trip = <&quiet_modem_439_trip2>; + cooling-device = <&modem_pa 1 1>; + }; + + modem_lvl2 { + trip = <&quiet_439_batt_trip6_mdm_trip3>; + cooling-device = <&modem_pa 2 2>; + }; + + modem_lvl3 { + trip = <&quiet_modem_439_trip4>; + cooling-device = <&modem_pa 3 3>; + }; + + battery_lvl1 { + trip = <&quiet_batt_439_trip1>; + cooling-device = <&pm660_charger 1 1>; + }; + + battery_lvl2 { + trip = <&quiet_batt_439_trip2>; + cooling-device = <&pm660_charger 2 2>; + }; + + battery_lvl3 { + trip = <&quiet_batt_439_trip3>; + cooling-device = <&pm660_charger 3 3>; + }; + + battery_lvl4 { + trip = <&quiet_batt_439_trip4>; + cooling-device = <&pm660_charger 4 4>; + }; + + battery_lvl5 { + trip = <&quiet_batt_439_trip5>; + cooling-device = <&pm660_charger 5 5>; + }; + + battery_lvl6 { + trip = <&quiet_439_batt_trip6_mdm_trip3>; + cooling-device = <&pm660_charger 6 6>; + }; + + battery_lvl7 { + trip = <&quiet_batt_439_trip7>; + cooling-device = <&pm660_charger 7 7>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi index 4b521b220903..db76a2483f21 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-regulator.dtsi @@ -55,6 +55,14 @@ ; qcom,use-voltage-level; }; + + pm660_cx_cdev: regulator-cx-cdev { + compatible = "qcom,regulator-cooling-device"; + regulator-cdev-supply = <&pm660_s1_floor_level>; + regulator-levels = ; + #cooling-cells = <2>; + }; }; /* PM660 S2 - VDD_MX supply */ From e56c1c5c3c61f67cb2004c2d9f531e1853ed581e Mon Sep 17 00:00:00 2001 From: Depeng Shao Date: Mon, 5 Aug 2019 21:31:18 +0800 Subject: [PATCH 244/281] msm: camera: eeprom: Release the mutex even though got error Release the mutex even though got error. Change-Id: Iaeec418ce7db4623cede6c922869c6f8c69ab595 Signed-off-by: Depeng Shao --- .../msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 6797ba4e58d6..20976afd9c22 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -974,7 +974,7 @@ int32_t cam_eeprom_driver_cmd(struct cam_eeprom_ctrl_t *e_ctrl, void *arg) &eeprom_cap, sizeof(struct cam_eeprom_query_cap_t))) { CAM_ERR(CAM_EEPROM, "Failed Copy to User"); - return -EFAULT; + rc = -EFAULT; goto release_mutex; } CAM_DBG(CAM_EEPROM, "eeprom_cap: ID: %d", eeprom_cap.slot_info); From 1ce4cea6dc532da30729ebec21422400c503fb46 Mon Sep 17 00:00:00 2001 From: Aishwarya Prasad Date: Wed, 14 Aug 2019 15:21:53 +0530 Subject: [PATCH 245/281] drivers: net: can: Add non-blocking call for end upgrade ioctl Add non-blocking call to avoid the return value error. Change-Id: I86d58b7051240a0f0a2d94eb7da5ea09508311f7 Signed-off-by: Aishwarya Prasad --- drivers/net/can/spi/qti-can.c | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/spi/qti-can.c b/drivers/net/can/spi/qti-can.c index 3aa93951daba..013114861e6b 100644 --- a/drivers/net/can/spi/qti-can.c +++ b/drivers/net/can/spi/qti-can.c @@ -1049,6 +1049,40 @@ static int qti_can_convert_ioctl_cmd_to_spi_cmd(int ioctl_cmd) return -EINVAL; } +static int qti_can_end_fwupgrade_ioctl(struct net_device *netdev, + struct ifreq *ifr, int cmd) +{ + int spi_cmd, ret; + + struct qti_can *priv_data; + struct qti_can_netdev_privdata *netdev_priv_data; + struct spi_device *spi; + int len = 0; + u8 *data = NULL; + + netdev_priv_data = netdev_priv(netdev); + priv_data = netdev_priv_data->qti_can; + spi = priv_data->spidev; + spi_cmd = qti_can_convert_ioctl_cmd_to_spi_cmd(cmd); + LOGDI("%s spi_cmd %x\n", __func__, spi_cmd); + if (spi_cmd < 0) { + LOGDE("%s wrong command %d\n", __func__, cmd); + return spi_cmd; + } + + if (!ifr) + return -EINVAL; + + mutex_lock(&priv_data->spi_lock); + LOGDI("%s len %d\n", __func__, len); + + ret = qti_can_send_spi_locked(priv_data, spi_cmd, len, data); + + mutex_unlock(&priv_data->spi_lock); + + return ret; +} + static int qti_can_do_blocking_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { @@ -1184,10 +1218,12 @@ static int qti_can_netdev_do_ioctl(struct net_device *netdev, qti_can_frame_filter(netdev, ifr, cmd); ret = 0; break; + case IOCTL_END_FIRMWARE_UPGRADE: + ret = qti_can_end_fwupgrade_ioctl(netdev, ifr, cmd); + break; case IOCTL_GET_FW_BR_VERSION: case IOCTL_BEGIN_FIRMWARE_UPGRADE: case IOCTL_FIRMWARE_UPGRADE_DATA: - case IOCTL_END_FIRMWARE_UPGRADE: case IOCTL_BEGIN_BOOT_ROM_UPGRADE: case IOCTL_BOOT_ROM_UPGRADE_DATA: case IOCTL_END_BOOT_ROM_UPGRADE: From 03e60b46a9ac6d1ddd274bc2356b34d54e78656e Mon Sep 17 00:00:00 2001 From: Santosh Dronamraju Date: Wed, 7 Aug 2019 14:14:44 +0530 Subject: [PATCH 246/281] defconfig: sa415m: enable TZ and Qsee log Enabled TZ and Qsee log for sdxpoorwills. Change-Id: I41931a1ac42fd54e12ba80764862dea1b9945aca Signed-off-by: Santosh Dronamraju --- arch/arm/configs/sa415m_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/sa415m_defconfig b/arch/arm/configs/sa415m_defconfig index e10d4ef1bf15..92e3642bc11f 100644 --- a/arch/arm/configs/sa415m_defconfig +++ b/arch/arm/configs/sa415m_defconfig @@ -445,6 +445,7 @@ CONFIG_PWM=y CONFIG_PWM_QPNP=y CONFIG_QCOM_SHOW_RESUME_IRQ=y CONFIG_ANDROID=y +CONFIG_MSM_TZ_LOG=y CONFIG_EXT3_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_VFAT_FS=y From b61e6f8ced2ef6eb90710f2aa23f944bb2774738 Mon Sep 17 00:00:00 2001 From: Tengfei Fan Date: Thu, 15 Aug 2019 15:48:10 +0800 Subject: [PATCH 247/281] arm32: Potential rollover condition for timer counter There is potential rollover condition for CNTVCT and CNTPCT counters. So on any architecture timer counter read, if the least significant 32 bits are set, reread counter. Change-Id: Iacc482ad956d5589d59a2a111576ec0463f5a1bb Signed-off-by: Tengfei Fan --- arch/arm/include/asm/arch_timer.h | 7 +++++++ drivers/clocksource/Kconfig | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index d4ebf5679f1f..1d85857771fd 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -92,7 +92,14 @@ static inline u64 arch_counter_get_cntvct(void) u64 cval; isb(); +#if IS_ENABLED(CONFIG_MSM_TIMER_LEAP) +#define L32_BITS 0x00000000FFFFFFFF + do { + asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval)); + } while ((cval & L32_BITS) == L32_BITS); +#else asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval)); +#endif return cval; } diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 91cf85785782..863be4358a58 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -334,7 +334,7 @@ config ARM_ARCH_TIMER_VCT_ACCESS config MSM_TIMER_LEAP bool "ARCH TIMER counter rollover" default n - depends on ARM_ARCH_TIMER && ARM64 + depends on ARM_ARCH_TIMER help This option enables a check for least significant 32 bits of counter rollover. On every counter read if least significant From d78a6969e03f12a09fd5073474f4c2718a9b38e5 Mon Sep 17 00:00:00 2001 From: Tengfei Fan Date: Thu, 15 Aug 2019 16:48:40 +0800 Subject: [PATCH 248/281] defconfig: msm: enable MSM_TIMER_LEAP config There is potential rollover condition for CNTVCT and CNTPCT counters.enable the config to control the counter read to avoid rollover. Change-Id: I6e3430e6ffe631d175d560fbcf0e4cee46ff7715 Signed-off-by: Tengfei Fan --- arch/arm/configs/msm8937-perf_defconfig | 1 + arch/arm/configs/msm8937_defconfig | 1 + arch/arm/configs/msm8937go-perf_defconfig | 1 + arch/arm/configs/msm8937go_defconfig | 1 + arch/arm/configs/msm8953-perf_defconfig | 1 + arch/arm/configs/msm8953_defconfig | 1 + arch/arm/configs/sdm670-perf_defconfig | 1 + arch/arm/configs/sdm670_defconfig | 1 + 8 files changed, 8 insertions(+) diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig index 655d4db416b6..2feff14cd7e1 100755 --- a/arch/arm/configs/msm8937-perf_defconfig +++ b/arch/arm/configs/msm8937-perf_defconfig @@ -554,6 +554,7 @@ CONFIG_USB_BAM=y CONFIG_MSM_RMNET_BAM=y CONFIG_MSM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_MAILBOX=y CONFIG_ARM_SMMU=y CONFIG_QCOM_LAZY_MAPPING=y diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig index 6e9f54666f0e..fa4dc506b393 100755 --- a/arch/arm/configs/msm8937_defconfig +++ b/arch/arm/configs/msm8937_defconfig @@ -565,6 +565,7 @@ CONFIG_MSM_EXT_DISPLAY=y CONFIG_MSM_RMNET_BAM=y CONFIG_MSM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_MAILBOX=y CONFIG_ARM_SMMU=y CONFIG_QCOM_LAZY_MAPPING=y diff --git a/arch/arm/configs/msm8937go-perf_defconfig b/arch/arm/configs/msm8937go-perf_defconfig index 6ab6c96a84bd..8b9fd0786636 100755 --- a/arch/arm/configs/msm8937go-perf_defconfig +++ b/arch/arm/configs/msm8937go-perf_defconfig @@ -548,6 +548,7 @@ CONFIG_USB_BAM=y CONFIG_MSM_RMNET_BAM=y CONFIG_MSM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_MAILBOX=y CONFIG_ARM_SMMU=y CONFIG_QCOM_LAZY_MAPPING=y diff --git a/arch/arm/configs/msm8937go_defconfig b/arch/arm/configs/msm8937go_defconfig index 41f11be32766..4ebb26b384e2 100755 --- a/arch/arm/configs/msm8937go_defconfig +++ b/arch/arm/configs/msm8937go_defconfig @@ -557,6 +557,7 @@ CONFIG_MSM_EXT_DISPLAY=y CONFIG_MSM_RMNET_BAM=y CONFIG_MSM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_MAILBOX=y CONFIG_ARM_SMMU=y CONFIG_QCOM_LAZY_MAPPING=y diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig index d072b6790d9a..e008aa1c3cdc 100755 --- a/arch/arm/configs/msm8953-perf_defconfig +++ b/arch/arm/configs/msm8953-perf_defconfig @@ -555,6 +555,7 @@ CONFIG_USB_BAM=y CONFIG_MSM_RMNET_BAM=y CONFIG_MSM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_MAILBOX=y CONFIG_ARM_SMMU=y CONFIG_QCOM_LAZY_MAPPING=y diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig index 8ba9cceaa5ac..a4ccfb7f6bec 100755 --- a/arch/arm/configs/msm8953_defconfig +++ b/arch/arm/configs/msm8953_defconfig @@ -565,6 +565,7 @@ CONFIG_MSM_EXT_DISPLAY=y CONFIG_MSM_RMNET_BAM=y CONFIG_MSM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_MAILBOX=y CONFIG_ARM_SMMU=y CONFIG_QCOM_LAZY_MAPPING=y diff --git a/arch/arm/configs/sdm670-perf_defconfig b/arch/arm/configs/sdm670-perf_defconfig index c67ee518542d..a4d16315303c 100755 --- a/arch/arm/configs/sdm670-perf_defconfig +++ b/arch/arm/configs/sdm670-perf_defconfig @@ -468,6 +468,7 @@ CONFIG_MSM_GPUCC_SDM845=y CONFIG_MSM_CLK_AOP_QMP=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_MSM_QMP=y CONFIG_ARM_SMMU=y CONFIG_QCOM_LAZY_MAPPING=y diff --git a/arch/arm/configs/sdm670_defconfig b/arch/arm/configs/sdm670_defconfig index 6a92eb410bcd..8d9d85b9dd14 100755 --- a/arch/arm/configs/sdm670_defconfig +++ b/arch/arm/configs/sdm670_defconfig @@ -480,6 +480,7 @@ CONFIG_MSM_GPUCC_SDM845=y CONFIG_MSM_CLK_AOP_QMP=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_MSM_QMP=y CONFIG_ARM_SMMU=y CONFIG_QCOM_LAZY_MAPPING=y From 79457f1020bc4eed750fdc459e021d465a437cc6 Mon Sep 17 00:00:00 2001 From: Paras Nagda Date: Sat, 27 Apr 2019 20:11:21 +0530 Subject: [PATCH 249/281] vidc_3x: update the condition for load check load calculation check should be for a non realtime session else it will result in hardware overload error. Change-Id: I86675d4e4f37a4c3c0e6080393255ad11c6ee6f9 Signed-off-by: Paras Nagda --- drivers/media/platform/msm/vidc_3x/msm_vidc_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c index be3b99265c67..d7e215404ec3 100644 --- a/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc_3x/msm_vidc_common.c @@ -347,7 +347,7 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, * ----------------|----------------------|------------------------| */ - if (is_realtime_session(inst) && + if (!is_realtime_session(inst) && (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) { if (!inst->prop.fps) { dprintk(VIDC_INFO, "instance:%pK fps = 0\n", inst); From c0c8730b99c37e6a5ab3681b30512057b1acfebb Mon Sep 17 00:00:00 2001 From: Ziyu Jian Date: Thu, 15 Aug 2019 18:59:20 +0800 Subject: [PATCH 250/281] msm: camera: cci: Add mutex_q lock for cci_init cci_write is being executed meanwhile cci_init is called, which will maybe cause cci timeout since cci_init will do reset operation. So add the mutex_q lock which is used by cci_write into cci_init. Change-Id: I81c67f27205f4250f08ca7ab38799f6454578dbd Signed-off-by: Ziyu Jian --- .../msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c index 8c2853b5cc62..927e00bb54e6 100644 --- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c +++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, 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 @@ -51,6 +51,10 @@ int cam_cci_init(struct v4l2_subdev *sd, CAM_DBG(CAM_CCI, "master %d", master); if (master < MASTER_MAX && master >= 0) { mutex_lock(&cci_dev->cci_master_info[master].mutex); + mutex_lock(&cci_dev-> + cci_master_info[master].mutex_q[QUEUE_0]); + mutex_lock(&cci_dev-> + cci_master_info[master].mutex_q[QUEUE_1]); flush_workqueue(cci_dev->write_wq[master]); /* Re-initialize the completion */ reinit_completion( @@ -73,6 +77,10 @@ int cam_cci_init(struct v4l2_subdev *sd, CCI_TIMEOUT); if (rc <= 0) CAM_ERR(CAM_CCI, "wait failed %d", rc); + mutex_unlock(&cci_dev-> + cci_master_info[master].mutex_q[QUEUE_1]); + mutex_unlock(&cci_dev-> + cci_master_info[master].mutex_q[QUEUE_0]); mutex_unlock(&cci_dev->cci_master_info[master].mutex); } return 0; From ab29efa81ced8f0298b557f728dc0502ea2d1bff Mon Sep 17 00:00:00 2001 From: Puneet Yatnal Date: Mon, 5 Aug 2019 13:13:31 +0530 Subject: [PATCH 251/281] drivers: input: sensors: disabled smi130 irq after 40 sec of boottime Disabled irq of sensor after 40 second of buffering if there is no active client to read the data. Change-Id: Ide5090fcb592628a6cf5e42fd41f4c305a3b899d Signed-off-by: Puneet Yatnal --- drivers/input/sensors/smi130/smi130_acc.c | 28 +++++++++++++++++-- .../input/sensors/smi130/smi130_gyro_driver.c | 28 +++++++++++++++++-- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/drivers/input/sensors/smi130/smi130_acc.c b/drivers/input/sensors/smi130/smi130_acc.c index c36c31dab67b..a63e08e521c3 100644 --- a/drivers/input/sensors/smi130/smi130_acc.c +++ b/drivers/input/sensors/smi130/smi130_acc.c @@ -1604,6 +1604,7 @@ struct smi130_acc_data { bool read_acc_boot_sample; int acc_bufsample_cnt; bool acc_buffer_smi130_samples; + bool acc_enable; struct kmem_cache *smi_acc_cachepool; struct smi_acc_sample *smi130_acc_samplist[SMI_ACC_MAXSAMPLE]; int max_buffer_time; @@ -4073,11 +4074,24 @@ static inline int smi130_check_acc_early_buff_enable_flag( else return 0; } +static void smi130_check_acc_enable_flag(struct smi130_acc_data *client_data, + unsigned long data) +{ + if (data == SMI_ACC2X2_MODE_NORMAL) + client_data->acc_enable = true; + else + client_data->acc_enable = false; +} #else static inline int smi130_check_acc_early_buff_enable_flag( struct smi130_acc_data *client_data) { return 0; +} +static void smi130_check_acc_enable_flag(struct smi130_acc_data *client_data, + unsigned long data) +{ + } #endif @@ -5481,13 +5495,17 @@ static ssize_t smi130_acc_mode_store(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct smi130_acc_data *smi130_acc = i2c_get_clientdata(client); - error = smi130_check_acc_early_buff_enable_flag(smi130_acc); - if (error) - return count; error = kstrtoul(buf, 10, &data); if (error) return error; + + smi130_check_acc_enable_flag(smi130_acc, data); + + error = smi130_check_acc_early_buff_enable_flag(smi130_acc); + if (error) + return count; + if (smi130_acc_set_mode(smi130_acc->smi130_acc_client, (unsigned char) data, SMI_ACC_ENABLED_BSX) < 0) return -EINVAL; @@ -6915,6 +6933,9 @@ static void store_acc_boot_sample(struct smi130_acc_data *client_data, PINFO("End of ACC buffering %d\n", client_data->acc_bufsample_cnt); client_data->acc_buffer_smi130_samples = false; + if (client_data->acc_enable == false) + smi130_acc_set_mode(client_data->smi130_acc_client, + SMI_ACC2X2_MODE_SUSPEND, 1); } } #else @@ -6982,6 +7003,7 @@ static int smi130_acc_early_buff_init(struct i2c_client *client, } client_data->acc_buffer_smi130_samples = true; + client_data->acc_enable = false; smi130_acc_set_mode(client, SMI_ACC2X2_MODE_NORMAL, 1); smi130_acc_set_bandwidth(client, SMI_ACC2X2_BW_62_50HZ); diff --git a/drivers/input/sensors/smi130/smi130_gyro_driver.c b/drivers/input/sensors/smi130/smi130_gyro_driver.c index 552d39cf25fc..fd9e87d2e5b3 100644 --- a/drivers/input/sensors/smi130/smi130_gyro_driver.c +++ b/drivers/input/sensors/smi130/smi130_gyro_driver.c @@ -295,6 +295,7 @@ struct smi_gyro_client_data { bool read_gyro_boot_sample; int gyro_bufsample_cnt; bool gyro_buffer_smi130_samples; + bool gyro_enable; struct kmem_cache *smi_gyro_cachepool; struct smi_gyro_sample *smi130_gyro_samplist[SMI_GYRO_MAXSAMPLE]; int max_buffer_time; @@ -860,12 +861,24 @@ static inline int smi130_check_gyro_early_buff_enable_flag( else return 0; } +static void smi130_check_gyro_enable_flag( + struct smi_gyro_client_data *client_data, unsigned long data) +{ + if (data == SMI130_GYRO_MODE_NORMAL) + client_data->gyro_enable = true; + else + client_data->gyro_enable = false; +} #else static inline int smi130_check_gyro_early_buff_enable_flag( struct smi_gyro_client_data *client_data) { return 0; } +static void smi130_check_gyro_enable_flag( + struct smi_gyro_client_data *client_data, unsigned long data) +{ +} #endif static ssize_t smi_gyro_show_op_mode(struct device *dev, @@ -895,13 +908,17 @@ static ssize_t smi_gyro_store_op_mode(struct device *dev, long op_mode; - err = smi130_check_gyro_early_buff_enable_flag(client_data); - if (err) - return count; err = kstrtoul(buf, 10, &op_mode); if (err) return err; + + smi130_check_gyro_enable_flag(client_data, op_mode); + + err = smi130_check_gyro_early_buff_enable_flag(client_data); + if (err) + return count; + mutex_lock(&client_data->mutex_op_mode); err = SMI_GYRO_CALL_API(set_mode)(op_mode); @@ -1742,6 +1759,10 @@ static void store_gyro_boot_sample(struct smi_gyro_client_data *client_data, PINFO("End of GYRO buffering %d", client_data->gyro_bufsample_cnt); client_data->gyro_buffer_smi130_samples = false; + if (client_data->gyro_enable == false) { + smi130_gyro_set_mode(SMI130_GYRO_MODE_SUSPEND); + smi130_gyro_delay(5); + } } } #else @@ -1810,6 +1831,7 @@ static int smi130_gyro_early_buff_init(struct smi_gyro_client_data *client_data) } client_data->gyro_buffer_smi130_samples = true; + client_data->gyro_enable = false; smi130_gyro_set_mode(SMI130_GYRO_MODE_NORMAL); smi130_gyro_delay(5); From 1093d5d29612527d893a21258c9b6f84c207ddb6 Mon Sep 17 00:00:00 2001 From: Rishi Gupta Date: Fri, 16 Aug 2019 14:18:29 +0530 Subject: [PATCH 252/281] ARM: dts: msm: Disable mmc rescan on SA415M TTP This commit disables scanning for mmc card presence again and again on SA415M TTP devices as the presence is handled through GPIO. This scanning otherwise causes unnecessary CPU consumption. Change-Id: Ic08482064c49a9c24780c86a8c719636e1528cbd Signed-off-by: Rishi Gupta --- arch/arm/boot/dts/qcom/sa415m-ttp.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi index 1cf499e858a5..b0d746a372ac 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi +++ b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi @@ -20,6 +20,10 @@ status = "okay"; }; +&sdhc_1 { + qcom,nonremovable; +}; + &usb { status = "okay"; qcom,connector-type-uAB; From 389dd5c2a9a6d8463782de96dbc5306fbeebfcd3 Mon Sep 17 00:00:00 2001 From: wumeif Date: Mon, 19 Aug 2019 19:09:35 +0800 Subject: [PATCH 253/281] defconfig: msm: Enable USB SERIAL CP210X and FTDI for APQ8009 Add config to enable USB SERIAL CP210X and FTDI for apq8009. Change-Id: Id681a3f2fc93d7415c654a8cc99056a9e157600f Signed-off-by: wumeif --- arch/arm/configs/msm8909_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig index ccf4b596d1f3..cc4509f5e99d 100644 --- a/arch/arm/configs/msm8909_defconfig +++ b/arch/arm/configs/msm8909_defconfig @@ -384,6 +384,8 @@ CONFIG_USB_EHCI_MSM=y CONFIG_USB_ACM=y CONFIG_USB_STORAGE=y CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CP210X=y +CONFIG_USB_SERIAL_FTDI_SIO=y CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DEBUG_FILES=y From 6d7e81946040a9ce1b702f17b620a89cfa2ab18b Mon Sep 17 00:00:00 2001 From: Neng Chen Date: Tue, 20 Aug 2019 11:33:45 +0800 Subject: [PATCH 254/281] ARM: dts: msm: enable eeprom for camera ID 1 on Spyro WDP Camera ID 1 supports eeprom and ID 2 doesn't support on Spyro WDP. Change-Id: I654ba7ce4e4fabd172729956d90031f00fd946b5 Signed-off-by: Neng Chen --- .../dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi | 101 ++++++------------ .../dts/qcom/sdm429w-camera-sensor-spyro.dtsi | 99 +++++------------ 2 files changed, 59 insertions(+), 141 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi index 5c1594888f6b..8d047caccc39 100644 --- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt-camera.dtsi @@ -203,82 +203,40 @@ eeprom_spyro1: qcom,eeprom@1 { cell-index = <1>; reg = <0x1>; - qcom,eeprom-name = "sunny_8865"; compatible = "qcom,eeprom"; - qcom,slave-addr = <0x6c>; - qcom,cci-master = <0>; - qcom,num-blocks = <8>; - - qcom,page0 = <1 0x0100 2 0x01 1 1>; - qcom,poll0 = <0 0x0 2 0x0 1 0>; - qcom,mem0 = <0 0x0 2 0x0 1 0>; - - qcom,page1 = <1 0x5002 2 0x00 1 0>; - qcom,poll1 = <0 0x0 2 0x0 1 0>; - qcom,mem1 = <0 0x0 2 0x0 1 0>; - - qcom,page2 = <1 0x3d84 2 0xc0 1 0>; - qcom,poll2 = <0 0x0 2 0x0 1 0>; - qcom,mem2 = <0 0x0 2 0x0 1 0>; - - qcom,page3 = <1 0x3d88 2 0x70 1 0>; - qcom,poll3 = <0 0x0 2 0x0 1 0>; - qcom,mem3 = <0 0x0 2 0x0 1 0>; - - qcom,page4 = <1 0x3d89 2 0x10 1 0>; - qcom,poll4 = <0 0x0 2 0x0 1 0>; - qcom,mem4 = <0 0x0 2 0x0 1 0>; - - qcom,page5 = <1 0x3d8a 2 0x70 1 0>; - qcom,poll5 = <0 0x0 2 0x0 1 0>; - qcom,mem5 = <0 0x0 2 0x0 1 0>; - - qcom,page6 = <1 0x3d8b 2 0xf4 1 0>; - qcom,poll6 = <0 0x0 2 0x0 1 0>; - qcom,mem6 = <0 0x0 2 0x0 1 0>; - - qcom,page7 = <1 0x3d81 2 0x01 1 10>; - qcom,poll7 = <0 0x0 2 0x0 1 1>; - qcom,mem7 = <1536 0x7010 2 0 1 0>; + qcom,cci-master = <1>; cam_vdig-supply = <&pm660_l3>; - cam_vana-supply = <&pm660_l7>; - cam_vio-supply = <&pm660_l6>; + cam_vio-supply = <&pm660_l14>; + cam_vana-supply = <&pm660_s5>; cam_vaf-supply = <&pm660_l17>; - qcom,cam-vreg-name = "cam_vdig", "cam_vio", - "cam_vana", "cam_vaf"; - qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-max-voltage = <1200000 0 2800000 3200000>; - qcom,cam-vreg-op-mode = <105000 0 80000 100000>; - qcom,gpio-no-mux = <0>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 1420000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 1420000>; + qcom,cam-vreg-op-mode = <200000 80000 80000>; pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk2_default - &cam_sensor_front1_default>; - pinctrl-1 = <&cam_sensor_mclk2_sleep - &cam_sensor_front1_sleep>; - gpios = <&tlmm 28 0>, - <&tlmm 40 0>, - <&tlmm 39 0>; - qcom,gpio-reset = <1>; - qcom,gpio-standby = <2>; - qcom,gpio-req-tbl-num = <0 1 2>; - qcom,gpio-req-tbl-flags = <1 0 0>; - qcom,gpio-req-tbl-label = "CAMIF_MCLK2", - "CAM_RESET2", - "CAM_STANDBY2"; - qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg", - "sensor_vreg", - "sensor_gpio", "sensor_gpio" , "sensor_clk"; - qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio", - "sensor_gpio_reset", "sensor_gpio_standby", - "sensor_cam_mclk"; - qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>; - qcom,cam-power-seq-delay = <1 1 1 30 30 5>; - status = "disabled"; - clocks = <&clock_gcc clk_mclk2_clk_src>, - <&clock_gcc clk_gcc_camss_mclk2_clk>; + pinctrl-0 = <&cam_sensor_mclk1_default + &cam_sensor_front_default>; + pinctrl-1 = <&cam_sensor_mclk1_sleep + &cam_sensor_front_sleep>; + gpios = <&tlmm 27 0>, + <&tlmm 33 0>, + <&tlmm 66 0>, + <&tlmm 38 0>; + qcom,gpio-vana= <1>; + qcom,gpio-vdig= <2>; + qcom,gpio-reset = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_AVDD1", + "CAM_DVDD1", + "CAM_RESET1"; + status = "ok"; + clocks = <&clock_gcc clk_mclk1_clk_src>, + <&clock_gcc clk_gcc_camss_mclk1_clk>; clock-names = "cam_src_clk", "cam_clk"; - qcom,clock-rates = <19200000 0>; + qcom,clock-rates = <24000000 0>; }; qcom,camera@0 { @@ -337,6 +295,8 @@ qcom,csiphy-sd-index = <1>; qcom,csid-sd-index = <1>; qcom,mount-angle = <270>; + qcom,eeprom-src = <&eeprom_spyro1>; + cam_vdig-supply = <&pm660_l3>; cam_vio-supply = <&pm660_l14>; cam_vana-supply = <&pm660_s5>; @@ -378,7 +338,6 @@ qcom,csiphy-sd-index = <1>; qcom,csid-sd-index = <1>; qcom,mount-angle = <270>; - qcom,eeprom-src = <&eeprom_spyro1>; qcom,actuator-src = <&actuator_spyro1>; cam_vdig-supply = <&pm660_l3>; cam_vana-supply = <&pm660_l7>; diff --git a/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi index 45756f77791a..c032db594262 100644 --- a/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm429w-camera-sensor-spyro.dtsi @@ -109,82 +109,40 @@ eeprom_spyro1: qcom,eeprom@1 { cell-index = <1>; reg = <0x1>; - qcom,eeprom-name = "sunny_8865"; compatible = "qcom,eeprom"; - qcom,slave-addr = <0x6c>; - qcom,cci-master = <0>; - qcom,num-blocks = <8>; - - qcom,page0 = <1 0x0100 2 0x01 1 1>; - qcom,poll0 = <0 0x0 2 0x0 1 0>; - qcom,mem0 = <0 0x0 2 0x0 1 0>; - - qcom,page1 = <1 0x5002 2 0x00 1 0>; - qcom,poll1 = <0 0x0 2 0x0 1 0>; - qcom,mem1 = <0 0x0 2 0x0 1 0>; - - qcom,page2 = <1 0x3d84 2 0xc0 1 0>; - qcom,poll2 = <0 0x0 2 0x0 1 0>; - qcom,mem2 = <0 0x0 2 0x0 1 0>; - - qcom,page3 = <1 0x3d88 2 0x70 1 0>; - qcom,poll3 = <0 0x0 2 0x0 1 0>; - qcom,mem3 = <0 0x0 2 0x0 1 0>; - - qcom,page4 = <1 0x3d89 2 0x10 1 0>; - qcom,poll4 = <0 0x0 2 0x0 1 0>; - qcom,mem4 = <0 0x0 2 0x0 1 0>; - - qcom,page5 = <1 0x3d8a 2 0x70 1 0>; - qcom,poll5 = <0 0x0 2 0x0 1 0>; - qcom,mem5 = <0 0x0 2 0x0 1 0>; - - qcom,page6 = <1 0x3d8b 2 0xf4 1 0>; - qcom,poll6 = <0 0x0 2 0x0 1 0>; - qcom,mem6 = <0 0x0 2 0x0 1 0>; - - qcom,page7 = <1 0x3d81 2 0x01 1 10>; - qcom,poll7 = <0 0x0 2 0x0 1 1>; - qcom,mem7 = <1536 0x7010 2 0 1 0>; + qcom,cci-master = <1>; cam_vdig-supply = <&pm660_l3>; - cam_vana-supply = <&pm660_l7>; - cam_vio-supply = <&pm660_l6>; + cam_vio-supply = <&pm660_l14>; + cam_vana-supply = <&pm660_s5>; cam_vaf-supply = <&pm660_l17>; - qcom,cam-vreg-name = "cam_vdig", "cam_vio", - "cam_vana", "cam_vaf"; - qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-max-voltage = <1200000 0 2800000 3200000>; - qcom,cam-vreg-op-mode = <105000 0 80000 100000>; - qcom,gpio-no-mux = <0>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 1420000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 1420000>; + qcom,cam-vreg-op-mode = <200000 80000 80000>; pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk2_default - &cam_sensor_front1_default>; - pinctrl-1 = <&cam_sensor_mclk2_sleep - &cam_sensor_front1_sleep>; - gpios = <&tlmm 28 0>, - <&tlmm 40 0>, - <&tlmm 39 0>; - qcom,gpio-reset = <1>; - qcom,gpio-standby = <2>; - qcom,gpio-req-tbl-num = <0 1 2>; - qcom,gpio-req-tbl-flags = <1 0 0>; - qcom,gpio-req-tbl-label = "CAMIF_MCLK2", - "CAM_RESET2", - "CAM_STANDBY2"; - qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg", - "sensor_vreg", - "sensor_gpio", "sensor_gpio" , "sensor_clk"; - qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio", - "sensor_gpio_reset", "sensor_gpio_standby", - "sensor_cam_mclk"; - qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>; - qcom,cam-power-seq-delay = <1 1 1 30 30 5>; + pinctrl-0 = <&cam_sensor_mclk1_default + &cam_sensor_front_default>; + pinctrl-1 = <&cam_sensor_mclk1_sleep + &cam_sensor_front_sleep>; + gpios = <&tlmm 27 0>, + <&tlmm 33 0>, + <&tlmm 66 0>, + <&tlmm 38 0>; + qcom,gpio-vana= <1>; + qcom,gpio-vdig= <2>; + qcom,gpio-reset = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_AVDD1", + "CAM_DVDD1", + "CAM_RESET1"; status = "ok"; - clocks = <&clock_gcc clk_mclk2_clk_src>, - <&clock_gcc clk_gcc_camss_mclk2_clk>; + clocks = <&clock_gcc clk_mclk1_clk_src>, + <&clock_gcc clk_gcc_camss_mclk1_clk>; clock-names = "cam_src_clk", "cam_clk"; - qcom,clock-rates = <19200000 0>; + qcom,clock-rates = <24000000 0>; }; qcom,camera@0 { @@ -244,6 +202,8 @@ qcom,csiphy-sd-index = <1>; qcom,csid-sd-index = <1>; qcom,mount-angle = <270>; + qcom,eeprom-src = <&eeprom_spyro1>; + cam_vdig-supply = <&pm660_l3>; cam_vio-supply = <&pm660_l14>; cam_vaf-supply = <&pm660_l19>; @@ -286,7 +246,6 @@ qcom,csiphy-sd-index = <1>; qcom,csid-sd-index = <1>; qcom,mount-angle = <270>; - qcom,eeprom-src = <&eeprom_spyro1>; qcom,actuator-src = <&actuator_spyro1>; cam_vdig-supply = <&pm660_l3>; cam_vana-supply = <&pm660_l7>; From 0ce726a2b6628d616d874cdf12fee8c3165fb327 Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Tue, 20 Aug 2019 17:13:40 +0530 Subject: [PATCH 255/281] ARM: dts: msm: Fix ER indices as per ipa-hw support In sdxpoorwills, only 12 ER indices are supported for AP EE from IPA-GSI. So, modify the ER index from 9/13 to 7/11. Change-Id: I3e975dabb4fc8c528ffe662dff8005618d9e4796 Signed-off-by: Mohammed Javid --- arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts index 10ee58cc58a0..2eaca0282ab2 100644 --- a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts +++ b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts @@ -32,7 +32,7 @@ &ipa_hw { qcom,use-ipa-in-mhi-mode; qcom,ipa-config-is-auto; - qcom,mhi-event-ring-id-limits = <9 13>; /* start and end */ + qcom,mhi-event-ring-id-limits = <7 11>; /* start and end */ }; &cnss_pcie { From 93cdaa51bf1ea7e54bd3f2a22080edeefcb58b95 Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Wed, 31 Jul 2019 20:37:15 +0530 Subject: [PATCH 256/281] msm: ipa: Update modem ep info for auto use case on ipav4.0 Update ipa driver's ep_mapping for modem end points accordingly to support CV2X use case. Change-Id: I9274d48c469a21d37f7e982b1b9f2418ad39ad1f Signed-off-by: Mohammed Javid --- drivers/platform/msm/ipa/ipa_api.c | 16 +++++++- drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 44 +++++++++++++-------- include/uapi/linux/msm_ipa.h | 17 +++++--- 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_api.c b/drivers/platform/msm/ipa/ipa_api.c index 0ab6e9084e99..2c1146427409 100644 --- a/drivers/platform/msm/ipa/ipa_api.c +++ b/drivers/platform/msm/ipa/ipa_api.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, 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 @@ -187,7 +187,19 @@ const char *ipa_clients_strings[IPA_CLIENT_MAX] = { __stringify(RESERVERD_PROD_74), __stringify(IPA_CLIENT_MHI_DPL_CONS), __stringify(RESERVERD_PROD_76), - __stringify(IPA_CLIENT_DUMMY_CONS1) + __stringify(IPA_CLIENT_DUMMY_CONS1), + __stringify(IPA_CLIENT_WIGIG_PROD), + __stringify(IPA_CLIENT_WIGIG1_CONS), + __stringify(RESERVERD_PROD_80), + __stringify(IPA_CLIENT_WIGIG2_CONS), + __stringify(RESERVERD_PROD_82), + __stringify(IPA_CLIENT_WIGIG3_CONS), + __stringify(RESERVERD_PROD_84), + __stringify(IPA_CLIENT_WIGIG4_CONS), + __stringify(IPA_CLIENT_MHI2_PROD), + __stringify(IPA_CLIENT_MHI2_CONS), + __stringify(IPA_CLIENT_Q6_CV2X_PROD), + __stringify(IPA_CLIENT_Q6_CV2X_CONS) }; /** diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 090cfa08057f..60af28dc1805 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -1593,12 +1593,12 @@ static const struct ipa_ep_configuration ipa3_ep_mapping IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY, QMB_MASTER_SELECT_DDR, { 5, 7, 20, 24, IPA_EE_AP, GSI_USE_PREFETCH_BUFS } }, - [IPA_4_0_AUTO][IPA_CLIENT_ODU_PROD] = { - false, IPA_v4_0_GROUP_UL_DL, + [IPA_4_0_AUTO][IPA_CLIENT_Q6_CV2X_PROD] = { + true, IPA_v4_0_GROUP_CV2X, true, IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, QMB_MASTER_SELECT_DDR, - { 1, 0, 8, 16, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY } }, + { 1, 2, 8, 16, IPA_EE_Q6, GSI_ESCAPE_BUF_ONLY } }, [IPA_4_0_AUTO][IPA_CLIENT_ETHERNET_PROD] = { true, IPA_v4_0_GROUP_UL_DL, true, @@ -1606,13 +1606,13 @@ static const struct ipa_ep_configuration ipa3_ep_mapping QMB_MASTER_SELECT_DDR, { 9, 0, 8, 16, IPA_EE_UC, GSI_USE_PREFETCH_BUFS } }, [IPA_4_0_AUTO][IPA_CLIENT_Q6_WAN_PROD] = { - false, IPA_v4_0_GROUP_UL_DL, + true, IPA_v4_0_GROUP_UL_DL, true, IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP, QMB_MASTER_SELECT_DDR, { 3, 0, 16, 32, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, [IPA_4_0_AUTO][IPA_CLIENT_Q6_CMD_PROD] = { - false, IPA_v4_0_GROUP_UL_DL, + true, IPA_v4_0_GROUP_UL_DL, false, IPA_DPS_HPS_SEQ_TYPE_PKT_PROCESS_NO_DEC_UCP, QMB_MASTER_SELECT_DDR, @@ -1711,23 +1711,23 @@ static const struct ipa_ep_configuration ipa3_ep_mapping QMB_MASTER_SELECT_DDR, { 22, 1, 9, 9, IPA_EE_UC, GSI_USE_PREFETCH_BUFS } }, [IPA_4_0_AUTO][IPA_CLIENT_Q6_LAN_CONS] = { - false, IPA_v4_0_GROUP_UL_DL, + true, IPA_v4_0_GROUP_UL_DL, false, IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR, { 14, 4, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, [IPA_4_0_AUTO][IPA_CLIENT_Q6_WAN_CONS] = { - false, IPA_v4_0_GROUP_UL_DL, + true, IPA_v4_0_GROUP_UL_DL, false, IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR, { 13, 3, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, - [IPA_4_0_AUTO][IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS] = { - false, IPA_v4_0_GROUP_UL_DL, + [IPA_4_0_AUTO][IPA_CLIENT_Q6_CV2X_CONS] = { + true, IPA_v4_0_GROUP_CV2X, false, IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR, - { 16, 5, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + { 16, 5, 9, 9, IPA_EE_Q6, GSI_ESCAPE_BUF_ONLY } }, /* Only for test purpose */ /* MBIM aggregation test pipes should have the same QMB as USB_CONS */ [IPA_4_0_AUTO][IPA_CLIENT_TEST_CONS] = { @@ -1799,14 +1799,20 @@ static const struct ipa_ep_configuration ipa3_ep_mapping IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, QMB_MASTER_SELECT_DDR, { 9, 0, 8, 16, IPA_EE_UC, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_CV2X_PROD] = { + true, IPA_v4_0_GROUP_CV2X, + true, + IPA_DPS_HPS_REP_SEQ_TYPE_2PKT_PROC_PASS_NO_DEC_UCP_DMAP, + QMB_MASTER_SELECT_DDR, + { 1, 2, 8, 16, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_WAN_PROD] = { - false, IPA_v4_0_GROUP_UL_DL, + true, IPA_v4_0_GROUP_UL_DL, true, IPA_DPS_HPS_SEQ_TYPE_PKT_PROCESS_NO_DEC_UCP, QMB_MASTER_SELECT_DDR, { 3, 0, 16, 32, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_CMD_PROD] = { - false, IPA_v4_0_MHI_GROUP_PCIE, + true, IPA_v4_0_MHI_GROUP_PCIE, false, IPA_DPS_HPS_SEQ_TYPE_PKT_PROCESS_NO_DEC_UCP, QMB_MASTER_SELECT_DDR, @@ -1887,17 +1893,23 @@ static const struct ipa_ep_configuration ipa3_ep_mapping QMB_MASTER_SELECT_DDR, { 22, 1, 9, 9, IPA_EE_UC, GSI_USE_PREFETCH_BUFS } }, [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_LAN_CONS] = { - false, IPA_v4_0_MHI_GROUP_DDR, + true, IPA_v4_0_MHI_GROUP_DDR, false, IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR, { 14, 4, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_WAN_CONS] = { - false, IPA_v4_0_MHI_GROUP_DDR, + true, IPA_v4_0_MHI_GROUP_DDR, false, IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR, { 13, 3, 9, 9, IPA_EE_Q6, GSI_USE_PREFETCH_BUFS } }, + [IPA_4_0_AUTO_MHI][IPA_CLIENT_Q6_CV2X_CONS] = { + true, IPA_v4_0_GROUP_CV2X, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 16, 5, 9, 9, IPA_EE_Q6, GSI_ESCAPE_BUF_ONLY } }, [IPA_4_0_AUTO_MHI][IPA_CLIENT_MEMCPY_DMA_SYNC_CONS] = { true, IPA_v4_0_MHI_GROUP_DMA, false, @@ -5414,8 +5426,8 @@ void ipa3_set_resorce_groups_min_max_limits(void) case IPA_4_0_AUTO_MHI: src_rsrc_type_max = IPA_v4_0_RSRC_GRP_TYPE_SRC_MAX; dst_rsrc_type_max = IPA_v4_0_RSRC_GRP_TYPE_DST_MAX; - src_grp_idx_max = IPA_v4_0_GROUP_CV2X; - dst_grp_idx_max = IPA_v4_0_GROUP_CV2X; + src_grp_idx_max = IPA_v4_0_SRC_GROUP_MAX; + dst_grp_idx_max = IPA_v4_0_DST_GROUP_MAX; break; default: IPAERR("invalid hw type index\n"); diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h index 3c810c2ceccf..59b9133b67a5 100644 --- a/include/uapi/linux/msm_ipa.h +++ b/include/uapi/linux/msm_ipa.h @@ -334,11 +334,14 @@ enum ipa_client_type { IPA_CLIENT_MHI2_PROD = 86, IPA_CLIENT_MHI2_CONS = 87, + + IPA_CLIENT_Q6_CV2X_PROD = 88, + IPA_CLIENT_Q6_CV2X_CONS = 89, }; #define IPA_CLIENT_DUMMY_CONS IPA_CLIENT_DUMMY_CONS1 #define IPA_CLIENT_WIGIG4_CONS IPA_CLIENT_WIGIG4_CONS -#define IPA_CLIENT_MAX (IPA_CLIENT_MHI2_CONS + 1) +#define IPA_CLIENT_MAX (IPA_CLIENT_Q6_CV2X_CONS + 1) #define IPA_CLIENT_IS_APPS_CONS(client) \ ((client) == IPA_CLIENT_APPS_LAN_CONS || \ @@ -367,20 +370,23 @@ enum ipa_client_type { (client) == IPA_CLIENT_Q6_DUN_CONS || \ (client) == IPA_CLIENT_Q6_DECOMP_CONS || \ (client) == IPA_CLIENT_Q6_DECOMP2_CONS || \ - (client) == IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS) + (client) == IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS || \ + (client) == IPA_CLIENT_Q6_CV2X_CONS) #define IPA_CLIENT_IS_Q6_PROD(client) \ ((client) == IPA_CLIENT_Q6_LAN_PROD || \ (client) == IPA_CLIENT_Q6_WAN_PROD || \ (client) == IPA_CLIENT_Q6_CMD_PROD || \ (client) == IPA_CLIENT_Q6_DECOMP_PROD || \ - (client) == IPA_CLIENT_Q6_DECOMP2_PROD) + (client) == IPA_CLIENT_Q6_DECOMP2_PROD || \ + (client) == IPA_CLIENT_Q6_CV2X_PROD) #define IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client) \ ((client) == IPA_CLIENT_Q6_LAN_CONS || \ (client) == IPA_CLIENT_Q6_WAN_CONS || \ (client) == IPA_CLIENT_Q6_DUN_CONS || \ - (client) == IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS) + (client) == IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS || \ + (client) == IPA_CLIENT_Q6_CV2X_CONS) #define IPA_CLIENT_IS_Q6_ZIP_CONS(client) \ ((client) == IPA_CLIENT_Q6_DECOMP_CONS || \ @@ -389,7 +395,8 @@ enum ipa_client_type { #define IPA_CLIENT_IS_Q6_NON_ZIP_PROD(client) \ ((client) == IPA_CLIENT_Q6_LAN_PROD || \ (client) == IPA_CLIENT_Q6_WAN_PROD || \ - (client) == IPA_CLIENT_Q6_CMD_PROD) + (client) == IPA_CLIENT_Q6_CMD_PROD || \ + (client) == IPA_CLIENT_Q6_CV2X_PROD) #define IPA_CLIENT_IS_Q6_ZIP_PROD(client) \ ((client) == IPA_CLIENT_Q6_DECOMP_PROD || \ From f109cf60ad82bea183688e0f20436b26ce811987 Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Tue, 2 Jul 2019 13:16:54 +0530 Subject: [PATCH 257/281] msm: ipa: Add support in ipa-mhi driver for cv2x Only one pair of MHI ep's are supported till now. With respect to auto-pcie use case requirement we need to support one more MHI ep pair for cv2x. Modify ipa-mhi driver to support additional mhi ep pair. Change-Id: I301dc7c46c6bfcc995db5a6a56c677481588d20b Signed-off-by: Mohammed Javid --- .../platform/msm/ipa/ipa_clients/ipa_mhi_client.c | 4 ++-- drivers/platform/msm/ipa/ipa_v3/ipa.c | 13 +++++++++++-- drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c | 14 ++++++++++++-- include/uapi/linux/msm_ipa.h | 2 ++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c b/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c index 7c9738178eeb..e21147318aae 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c @@ -66,8 +66,8 @@ #define IPA_MHI_SUSPEND_SLEEP_MIN 900 #define IPA_MHI_SUSPEND_SLEEP_MAX 1100 -#define IPA_MHI_MAX_UL_CHANNELS 1 -#define IPA_MHI_MAX_DL_CHANNELS 2 +#define IPA_MHI_MAX_UL_CHANNELS 2 +#define IPA_MHI_MAX_DL_CHANNELS 3 /* bit #40 in address should be asserted for MHI transfers over pcie */ #define IPA_MHI_CLIENT_HOST_ADDR_COND(addr) \ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index f882bd785872..80513d239a28 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -2854,9 +2854,14 @@ void ipa3_q6_pre_shutdown_cleanup(void) ipa3_q6_pipe_delay(true); ipa3_q6_avoid_holb(); - if (ipa3_ctx->ipa_config_is_mhi) + if (ipa3_ctx->ipa_config_is_mhi) { ipa3_set_reset_client_cons_pipe_sus_holb(true, IPA_CLIENT_MHI_CONS); + if (ipa3_ctx->ipa_config_is_auto) + ipa3_set_reset_client_cons_pipe_sus_holb(true, + IPA_CLIENT_MHI2_CONS); + } + if (ipa3_q6_clean_q6_tables()) { IPAERR("Failed to clean Q6 tables\n"); BUG(); @@ -2874,9 +2879,13 @@ void ipa3_q6_pre_shutdown_cleanup(void) if (ipa3_ctx->ipa_config_is_auto) ipa3_set_reset_client_prod_pipe_delay(true, IPA_CLIENT_USB2_PROD); - if (ipa3_ctx->ipa_config_is_mhi) + if (ipa3_ctx->ipa_config_is_mhi) { ipa3_set_reset_client_prod_pipe_delay(true, IPA_CLIENT_MHI_PROD); + if (ipa3_ctx->ipa_config_is_auto) + ipa3_set_reset_client_prod_pipe_delay(true, + IPA_CLIENT_MHI2_PROD); + } IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG_LOW("Exit with success\n"); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c index c4eb731562a3..cc15baa7511b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019 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 @@ -383,6 +383,7 @@ int ipa3_mhi_init_engine(struct ipa_mhi_init_engine *params) int res; struct gsi_device_scratch gsi_scratch; const struct ipa_gsi_ep_config *gsi_ep_info; + u32 ipa_mhi_max_ul_channels, ipa_mhi_max_dl_channels; IPA_MHI_FUNC_ENTRY(); @@ -391,7 +392,16 @@ int ipa3_mhi_init_engine(struct ipa_mhi_init_engine *params) return -EINVAL; } - if ((IPA_MHI_MAX_UL_CHANNELS + IPA_MHI_MAX_DL_CHANNELS) > + ipa_mhi_max_ul_channels = IPA_MHI_MAX_UL_CHANNELS; + ipa_mhi_max_dl_channels = IPA_MHI_MAX_DL_CHANNELS; + + /* In case of Auto-pcie config, MHI2_PROD and MHI2_CONS is used */ + if (ipa3_ctx->ipa_config_is_auto == true) { + ipa_mhi_max_ul_channels++; + ipa_mhi_max_dl_channels++; + } + + if ((ipa_mhi_max_ul_channels + ipa_mhi_max_dl_channels) > ((ipa3_ctx->mhi_evid_limits[1] - ipa3_ctx->mhi_evid_limits[0]) + 1)) { IPAERR("Not enough event rings for MHI\n"); diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h index 3c810c2ceccf..8ba4844883b2 100644 --- a/include/uapi/linux/msm_ipa.h +++ b/include/uapi/linux/msm_ipa.h @@ -411,6 +411,8 @@ enum ipa_client_type { #define IPA_CLIENT_IS_MHI(client) \ ((client) == IPA_CLIENT_MHI_CONS || \ (client) == IPA_CLIENT_MHI_PROD || \ + (client) == IPA_CLIENT_MHI2_PROD || \ + (client) == IPA_CLIENT_MHI2_CONS || \ (client) == IPA_CLIENT_MHI_DPL_CONS) #define IPA_CLIENT_IS_TEST_PROD(client) \ From a80bcf76e1de43f63160bc5ef84844dfe8b87e11 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Tue, 20 Aug 2019 14:19:55 +0530 Subject: [PATCH 258/281] diag: dci: Prevent using uninitialized variables Presently chance of using uninitialized variables if a dci command is not found is avoided by initializing command structure variables. Change-Id: I190299917ea6c7fadfc7686d43a7da098e0bc05e Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 12bc3ac5032b..12c8bd91f239 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -2082,6 +2082,11 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len) if ((ret == DIAG_DCI_NO_ERROR && !common_cmd) || ret < 0) return ret; + reg_entry.cmd_code = 0; + reg_entry.subsys_id = 0; + reg_entry.cmd_code_hi = 0; + reg_entry.cmd_code_lo = 0; + if (header_len >= (sizeof(uint8_t))) reg_entry.cmd_code = header->cmd_code; if (header_len >= (2 * sizeof(uint8_t))) From a84e7ded825d4c0ce52840d15a66cbd5a115108b Mon Sep 17 00:00:00 2001 From: Prasad Sodagudi Date: Mon, 24 Sep 2018 16:25:55 -0700 Subject: [PATCH 259/281] kernel: time: Add delay after cpu_relax() in tight loops Tight loops of spin_lock_irqsave() and spin_unlock_irqrestore() in timer and hrtimer are causing scheduling delays. Add delay of few nano seconds after cpu_relax in the timer/hrtimer tight loops. Change-Id: Iaa0ab92da93f7b245b1d922b6edca2bebdc0fbce Signed-off-by: Prasad Sodagudi Signed-off-by: Chetan C R --- kernel/time/hrtimer.c | 3 +++ kernel/time/tick-internal.h | 1 + kernel/time/timer.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 11e4af2fc2ee..d471752c373b 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -149,6 +150,7 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer, raw_spin_unlock_irqrestore(&base->cpu_base->lock, *flags); } cpu_relax(); + ndelay(TIMER_LOCK_TIGHT_LOOP_DELAY_NS); } } @@ -1043,6 +1045,7 @@ int hrtimer_cancel(struct hrtimer *timer) if (ret >= 0) return ret; cpu_relax(); + ndelay(TIMER_LOCK_TIGHT_LOOP_DELAY_NS); } } EXPORT_SYMBOL_GPL(hrtimer_cancel); diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index f738251000fe..0059764b8dc7 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h @@ -165,3 +165,4 @@ DECLARE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases); extern u64 get_next_timer_interrupt(unsigned long basej, u64 basem); void timer_clear_idle(void); +#define TIMER_LOCK_TIGHT_LOOP_DELAY_NS 350 diff --git a/kernel/time/timer.c b/kernel/time/timer.c index af9a29ec90a6..018e2f5946ef 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -942,6 +942,7 @@ static struct timer_base *lock_timer_base(struct timer_list *timer, spin_unlock_irqrestore(&base->lock, *flags); } cpu_relax(); + ndelay(TIMER_LOCK_TIGHT_LOOP_DELAY_NS); } } @@ -1264,6 +1265,7 @@ int del_timer_sync(struct timer_list *timer) if (ret >= 0) return ret; cpu_relax(); + ndelay(TIMER_LOCK_TIGHT_LOOP_DELAY_NS); } } EXPORT_SYMBOL(del_timer_sync); From bda56cb5fedcbeb777f2cc5adf92c8abf87b080c Mon Sep 17 00:00:00 2001 From: Prasad Sodagudi Date: Mon, 12 Nov 2018 09:33:33 -0800 Subject: [PATCH 260/281] arm64: Add padding to thread_info structure Both flags and preempt_count variables of thread_info are falling into the same cache line. When one of the cores is incrementing/ decrementing the preempt_count continuously in a tight loop with spin_lock_irqsave() and spin_unlock_irqrestore() APIs, this causes the flags update to be delayed. When the thread_info flags updates are delayed, it leads to increased tasks scheduling latencies. So move the thread_info's preempt_count into different cache line by adding padding. Change-Id: I950d15a02b4df0c31862c3a11eb1a3d8fc17dff8 Signed-off-by: Prasad Sodagudi --- arch/arm64/include/asm/thread_info.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index 3b7968201575..af0c14dce54d 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -40,6 +40,7 @@ typedef unsigned long mm_segment_t; */ struct thread_info { unsigned long flags; /* low level flags */ + unsigned long padding[7]; mm_segment_t addr_limit; /* address limit */ #ifdef CONFIG_ARM64_SW_TTBR0_PAN u64 ttbr0; /* saved TTBR0_EL1 */ From 28b26f560f9063669605ed99e678a1b12553bc39 Mon Sep 17 00:00:00 2001 From: Junwen Wu Date: Tue, 20 Aug 2019 10:36:03 +0800 Subject: [PATCH 261/281] ARM: dts: msm: disable bcl_sensor for SDM845 RB3 The bcl_sensor has a dependency on the FG gen3 driver. Disable the same as FG is already disabled on this platform,disable bcl_sensor can address the issue. Change-Id: I23577171366cc89a211ad8b350ff6a5590989f0f Signed-off-by: Junwen Wu --- arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi index 2e16dbdb8249..2db4b60b433f 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-rb3.dtsi @@ -293,6 +293,10 @@ status = "disabled"; }; +&bcl_sensor { + status = "disabled"; +}; + &smb1355_charger_0 { status = "ok"; qcom,disable-ctm; From 26f45fc33a079abe64fdf636e3d2a1fb2ba89283 Mon Sep 17 00:00:00 2001 From: Akshay Pandit Date: Fri, 10 May 2019 17:53:27 +0530 Subject: [PATCH 262/281] msm: ipa_v2: Protect ipa default routing table Protect ipa default routing table from addition, deletion and modification once after default rule added by ipa driver. Change-Id: I4b8fdd9208425c5eb0bceed0ce62fb7d7a075e36 Signed-off-by: Pooja Kumari Signed-off-by: Akshay Pandit --- drivers/platform/msm/ipa/ipa_v2/ipa_rt.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c index 095d60b67eeb..50bb9bcf9674 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c @@ -1067,9 +1067,8 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name, * tables */ if (!strcmp(tbl->name, IPA_DFLT_RT_TBL_NAME) && - (tbl->rule_cnt > 0) && (at_rear != 0)) { - IPAERR("cannot add rule at end of tbl rule_cnt=%d at_rear=%d\n", - tbl->rule_cnt, at_rear); + (tbl->rule_cnt > 0)) { + IPAERR_RL("cannot add rules to default rt table\n"); goto error; } @@ -1608,6 +1607,11 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule) goto error; } + if (!strcmp(entry->tbl->name, IPA_DFLT_RT_TBL_NAME)) { + IPAERR_RL("Default tbl rule cannot be modified\n"); + return -EINVAL; + } + /* Adding check to confirm still * header entry present in header table or not */ From ef3c097ec7c035b92176126c8bace6cb0cb11210 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Thu, 22 Aug 2019 20:25:02 +0530 Subject: [PATCH 263/281] ARM: dts: msm: Disable ethernet interface for mhi swip for sdxpoorwills Remove "qcom,mhi-ethernet-interface" property such that mhi swip will support default rawip network interface instead of ethernet network interface on sdxpoorwills. Change-Id: Ic0a4c0e5177a0258b26c66802ed14278eeec258f Signed-off-by: Rama Krishna Phani A --- arch/arm/boot/dts/qcom/sdxpoorwills.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi index abbc8b5a7f65..c74425344aa0 100644 --- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi +++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi @@ -522,7 +522,6 @@ mhi_net_device: qcom,mhi_net_dev { compatible = "qcom,msm-mhi-dev-net"; - qcom,mhi-ethernet-interface; status = "disabled"; }; From 32ba95deb15c77a57c470eb46dbf64abd4c947d3 Mon Sep 17 00:00:00 2001 From: Mohammed Nayeem Ur Rahman Date: Fri, 26 Jul 2019 17:31:37 +0530 Subject: [PATCH 264/281] adsprpc: Fix glink receive function not to be called in IRQ context glink receive acknowledge function was called from IRQ context This function can sleep and since function that can sleep cannot be called from Interrupt context, moved this. Change-Id: I838dffae2011e016ff3a7ac90e3556eeb4689220 Signed-off-by: Mohammed Nayeem Ur Rahman --- drivers/char/adsprpc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index dea48e16f193..dba81f9977fa 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -240,6 +240,8 @@ struct smq_invoke_ctx { unsigned int *attrs; uint32_t *crc; uint64_t ctxid; + void *handle; + const void *ptr; }; struct fastrpc_ctx_lst { @@ -2044,7 +2046,8 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, if (err) goto bail; } - + if (ctx->handle) + glink_rx_done(ctx->handle, ctx->ptr, true); PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS), if (!fl->sctx->smmu.coherent) inv_args(ctx); @@ -2883,11 +2886,13 @@ static void fastrpc_glink_notify_rx(void *handle, const void *priv, if (err) goto bail; + me->ctxtable[index]->handle = handle; + me->ctxtable[index]->ptr = ptr; + context_notify_user(me->ctxtable[index], rsp->retval); bail: if (err) pr_err("adsprpc: invalid response or context\n"); - glink_rx_done(handle, ptr, true); } static void fastrpc_glink_notify_state(void *handle, const void *priv, From 008e34cb55038a75208ab52e92823073fa6efa63 Mon Sep 17 00:00:00 2001 From: Rahul Agarwal Date: Sun, 25 Aug 2019 23:50:00 +0530 Subject: [PATCH 265/281] defconfig: sa415m: Enable Android Binder IPC Driver Enable support for Android Binder IPC Driver. Change-Id: Id1f76a81dbf6356e54a8ab23e2832cc202a0b4ae Signed-off-by: Rahul Agarwal --- arch/arm/configs/sa415m-perf_defconfig | 2 ++ arch/arm/configs/sa415m_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/configs/sa415m-perf_defconfig b/arch/arm/configs/sa415m-perf_defconfig index 5a9b777ec74b..326cc4abc432 100644 --- a/arch/arm/configs/sa415m-perf_defconfig +++ b/arch/arm/configs/sa415m-perf_defconfig @@ -414,6 +414,8 @@ CONFIG_PWM=y CONFIG_PWM_QPNP=y CONFIG_QCOM_SHOW_RESUME_IRQ=y CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_BINDER_IPC_32BIT=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_UBIFS_FS=y diff --git a/arch/arm/configs/sa415m_defconfig b/arch/arm/configs/sa415m_defconfig index c3ec5c58ba4e..96b3cb9e74b0 100644 --- a/arch/arm/configs/sa415m_defconfig +++ b/arch/arm/configs/sa415m_defconfig @@ -445,6 +445,8 @@ CONFIG_PWM=y CONFIG_PWM_QPNP=y CONFIG_QCOM_SHOW_RESUME_IRQ=y CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_BINDER_IPC_32BIT=y CONFIG_MSM_TZ_LOG=y CONFIG_EXT3_FS=y CONFIG_EXT4_FS_SECURITY=y From df847feac0cda3b0de5edbb1a2888af6fa67e9e5 Mon Sep 17 00:00:00 2001 From: Sankeerth Billakanti Date: Thu, 11 Jul 2019 11:49:48 +0530 Subject: [PATCH 266/281] drm/msm/dp: add checks to prevent buffer overflows Add checks to prevent buffer overflows through debugfs. Change-Id: I1242a6e94b3182a9a3b0cbef4b04a9f8b14a4103 Signed-off-by: Sankeerth Billakanti --- drivers/gpu/drm/msm/dp/dp_debug.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c b/drivers/gpu/drm/msm/dp/dp_debug.c index 92fc9bc1bb3a..d023f64178e5 100644 --- a/drivers/gpu/drm/msm/dp/dp_debug.c +++ b/drivers/gpu/drm/msm/dp/dp_debug.c @@ -192,6 +192,8 @@ static ssize_t dp_debug_write_dpcd(struct file *file, goto bail; size = min_t(size_t, count, SZ_2K); + if (size < 4) + goto bail; buf = kzalloc(size, GFP_KERNEL); if (ZERO_OR_NULL_PTR(buf)) { @@ -220,6 +222,8 @@ static ssize_t dp_debug_write_dpcd(struct file *file, } size -= 4; + if (size == 0) + goto bail; dpcd_size = size / char_to_nib; buf_t = buf + 4; @@ -271,6 +275,7 @@ static ssize_t dp_debug_read_dpcd(struct file *file, len += snprintf(buf, SZ_8, "0x%x\n", debug->aux->reg); + len = min_t(size_t, count, len); if (copy_to_user(user_buff, buf, len)) return -EFAULT; @@ -428,7 +433,7 @@ static ssize_t dp_debug_write_exe_mode(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { struct dp_debug_private *debug = file->private_data; - char *buf; + char buf[SZ_32]; size_t len = 0; if (!debug) @@ -437,8 +442,11 @@ static ssize_t dp_debug_write_exe_mode(struct file *file, if (*ppos) return 0; + /* Leave room for termination char */ len = min_t(size_t, count, SZ_32 - 1); - buf = memdup_user(user_buff, len); + if (copy_from_user(buf, user_buff, len)) + goto end; + buf[len] = '\0'; if (sscanf(buf, "%3s", debug->exe_mode) != 1) @@ -469,6 +477,7 @@ static ssize_t dp_debug_read_connected(struct file *file, len += snprintf(buf, SZ_8, "%d\n", debug->usbpd->hpd_high); + len = min_t(size_t, count, len); if (copy_to_user(user_buff, buf, len)) return -EFAULT; @@ -532,6 +541,7 @@ static ssize_t dp_debug_read_edid_modes(struct file *file, } mutex_unlock(&connector->dev->mode_config.mutex); + len = min_t(size_t, count, len); if (copy_to_user(user_buff, buf, len)) { kfree(buf); rc = -EFAULT; @@ -621,6 +631,7 @@ static ssize_t dp_debug_read_info(struct file *file, char __user *user_buff, if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) goto error; + len = min_t(size_t, count, len); if (copy_to_user(user_buff, buf, len)) goto error; @@ -653,6 +664,7 @@ static ssize_t dp_debug_bw_code_read(struct file *file, len += snprintf(buf + len, (SZ_4K - len), "max_bw_code = %d\n", debug->panel->max_bw_code); + len = min_t(size_t, count, len); if (copy_to_user(user_buff, buf, len)) { kfree(buf); return -EFAULT; @@ -678,6 +690,7 @@ static ssize_t dp_debug_tpg_read(struct file *file, len += snprintf(buf, SZ_8, "%d\n", debug->dp_debug.tpg_state); + len = min_t(size_t, count, len); if (copy_to_user(user_buff, buf, len)) return -EFAULT; @@ -868,6 +881,7 @@ static ssize_t dp_debug_read_hdr(struct file *file, goto error; } + len = min_t(size_t, count, len); if (copy_to_user(user_buff, buf, len)) { kfree(buf); rc = -EFAULT; @@ -1027,6 +1041,7 @@ static ssize_t dp_debug_read_dump(struct file *file, print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_NONE, 16, 4, buf, len, false); + len = min_t(size_t, count, len); if (copy_to_user(user_buff, buf, len)) return -EFAULT; From bf419241067b18ee1b24a72c26601592f3e032f6 Mon Sep 17 00:00:00 2001 From: Tingwei Zhang Date: Mon, 26 Aug 2019 19:05:33 +0800 Subject: [PATCH 267/281] deconfig: msm8937/53/37go: Increase minimal loop count to 16 Change BLK_DEV_LOOP_MIN_COUNT's value from 8 to 16 to meet Android requirement. Change-Id: Id1078cc1d3d1a4f05111cafad8007c983512b711 Signed-off-by: Tingwei Zhang --- arch/arm/configs/msm8937-perf_defconfig | 1 + arch/arm/configs/msm8937_defconfig | 1 + arch/arm/configs/msm8937go-perf_defconfig | 1 + arch/arm/configs/msm8937go_defconfig | 1 + arch/arm/configs/msm8953-perf_defconfig | 1 + arch/arm/configs/msm8953_defconfig | 1 + arch/arm64/configs/msm8937-perf_defconfig | 1 + arch/arm64/configs/msm8937_defconfig | 1 + arch/arm64/configs/msm8953-perf_defconfig | 1 + arch/arm64/configs/msm8953_defconfig | 1 + 10 files changed, 10 insertions(+) diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig index 2feff14cd7e1..f9fcc7cebcd4 100755 --- a/arch/arm/configs/msm8937-perf_defconfig +++ b/arch/arm/configs/msm8937-perf_defconfig @@ -250,6 +250,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig index fa4dc506b393..502de4451766 100755 --- a/arch/arm/configs/msm8937_defconfig +++ b/arch/arm/configs/msm8937_defconfig @@ -254,6 +254,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm/configs/msm8937go-perf_defconfig b/arch/arm/configs/msm8937go-perf_defconfig index 8b9fd0786636..9667e5fd3dec 100755 --- a/arch/arm/configs/msm8937go-perf_defconfig +++ b/arch/arm/configs/msm8937go-perf_defconfig @@ -247,6 +247,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm/configs/msm8937go_defconfig b/arch/arm/configs/msm8937go_defconfig index 4ebb26b384e2..7b15381927ae 100755 --- a/arch/arm/configs/msm8937go_defconfig +++ b/arch/arm/configs/msm8937go_defconfig @@ -251,6 +251,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig index e008aa1c3cdc..3bda5c1005b1 100755 --- a/arch/arm/configs/msm8953-perf_defconfig +++ b/arch/arm/configs/msm8953-perf_defconfig @@ -242,6 +242,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig index a4ccfb7f6bec..f7bc2ed76d7c 100755 --- a/arch/arm/configs/msm8953_defconfig +++ b/arch/arm/configs/msm8953_defconfig @@ -247,6 +247,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm64/configs/msm8937-perf_defconfig b/arch/arm64/configs/msm8937-perf_defconfig index 7fde262b1b33..c1b861c379a5 100755 --- a/arch/arm64/configs/msm8937-perf_defconfig +++ b/arch/arm64/configs/msm8937-perf_defconfig @@ -249,6 +249,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm64/configs/msm8937_defconfig b/arch/arm64/configs/msm8937_defconfig index 59f906afabb9..b172fe349be8 100755 --- a/arch/arm64/configs/msm8937_defconfig +++ b/arch/arm64/configs/msm8937_defconfig @@ -255,6 +255,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index b346f4ee974b..79b92b80fc42 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -248,6 +248,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index 2c1e89b46c2b..02eea305bbcd 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -254,6 +254,7 @@ CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y CONFIG_DMA_CMA=y CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_HDCP_QSEECOM=y From ad22df30ed3162b4ca183f2cd796e8ac77fa32d2 Mon Sep 17 00:00:00 2001 From: Junlin Zhang Date: Fri, 23 Aug 2019 16:01:24 +0800 Subject: [PATCH 268/281] bt-power: Check chip type first before BT resetting As BT reset only is needed for qca6174 chip, so check chip type first to avoid triggering get_bt_reset_gpio_value() for other chip. CRs-Fixed: 2514357 Change-Id: Icaaf7046aa02d3ae3ecb5bf565cc94c89f11fb71 Signed-off-by: Junlin Zhang --- drivers/bluetooth/bluetooth-power.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/bluetooth-power.c b/drivers/bluetooth/bluetooth-power.c index 650585c2ea44..272a83dc2cfd 100644 --- a/drivers/bluetooth/bluetooth-power.c +++ b/drivers/bluetooth/bluetooth-power.c @@ -676,8 +676,8 @@ static int bt_power_probe(struct platform_device *pdev) btpdev = pdev; if (of_id) { - if ((get_bt_reset_gpio_value() == BT_RESET_GPIO_HIGH_VAL) - && (strcmp(of_id->compatible, "qca,qca6174") == 0)) { + if ((strcmp(of_id->compatible, "qca,qca6174") == 0) && + (get_bt_reset_gpio_value() == BT_RESET_GPIO_HIGH_VAL)) { bluetooth_toggle_radio(pdev->dev.platform_data, 0); bluetooth_toggle_radio(pdev->dev.platform_data, 1); } From e3ed1a344e128b179b81da731229a8a83f4d736d Mon Sep 17 00:00:00 2001 From: Raja Mallik Date: Thu, 22 Aug 2019 17:12:32 +0530 Subject: [PATCH 269/281] Merge remote-tracking branch 'dev/msm-4.14' into msm-4.9 08/19 * commit '65130d2ad231cd3fd65e076e45b4593b9555f5b1': msm: camera: cam_isp: Change default fps value ARM: dts: msm: Add dtsi string support for bindings msm: camera: isp: Added PPI driver functionality msm: camera: isp: Log information during IFE acquire failure msm: camera: cam_isp: Recovery after IRQ delayed msm: camera: isp: Add fps Blob support msm: camera: isp: Enable pixel_format_measurement in CSID msm: camera: isp: Handle wait and active list during flush all msm: camera: isp: Add irq status prints to CAM_ERR Change-Id: I43ce3f6daaa91302e8b1db030b7953372b463606 Signed-off-by: Raja Mallik --- .../bindings/media/video/msm-cam-ppi.txt | 102 ++++ .../msm/camera_v3/cam_core/cam_hw_mgr_intf.h | 12 + .../cam_cpas/cpas_top/cam_cpastop_hw.c | 8 + .../cam_cpas/cpas_top/cpastop_v150_110.h | 537 ++++++++++++++++++ .../camera_v3/cam_cpas/include/cam_cpas_api.h | 1 + .../msm/camera_v3/cam_isp/cam_isp_context.c | 207 ++++++- .../msm/camera_v3/cam_isp/cam_isp_context.h | 11 + .../cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 375 +++++++++++- .../isp_hw_mgr/include/cam_isp_hw_mgr_intf.h | 20 +- .../isp_hw_mgr/isp_hw/ife_csid_hw/Makefile | 1 + .../isp_hw/ife_csid_hw/cam_csid_ppi170.c | 58 ++ .../isp_hw/ife_csid_hw/cam_csid_ppi170.h | 32 ++ .../isp_hw/ife_csid_hw/cam_csid_ppi_core.c | 404 +++++++++++++ .../isp_hw/ife_csid_hw/cam_csid_ppi_core.h | 103 ++++ .../isp_hw/ife_csid_hw/cam_csid_ppi_dev.c | 147 +++++ .../isp_hw/ife_csid_hw/cam_csid_ppi_dev.h | 22 + .../isp_hw/ife_csid_hw/cam_ife_csid170.h | 4 + .../isp_hw/ife_csid_hw/cam_ife_csid175.h | 4 + .../isp_hw/ife_csid_hw/cam_ife_csid175_200.h | 4 + .../isp_hw/ife_csid_hw/cam_ife_csid_core.c | 288 +++++++++- .../isp_hw/ife_csid_hw/cam_ife_csid_core.h | 21 +- .../isp_hw/include/cam_ife_csid_hw_intf.h | 13 + .../isp_hw_mgr/isp_hw/include/cam_isp_hw.h | 5 + .../isp_hw/include/cam_vfe_hw_intf.h | 11 + .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c | 3 + .../vfe_hw/vfe_top/cam_vfe_camif_ver2.c | 26 +- .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c | 20 + include/uapi/media/cam_isp.h | 57 +- 28 files changed, 2422 insertions(+), 74 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt create mode 100644 drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cpastop_v150_110.h create mode 100644 drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c create mode 100644 drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h create mode 100644 drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c create mode 100644 drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h create mode 100644 drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c create mode 100644 drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h diff --git a/Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt b/Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt new file mode 100644 index 000000000000..aeed60fa6055 --- /dev/null +++ b/Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt @@ -0,0 +1,102 @@ +* Qualcomm Technologies, Inc. MSM camera PPI + +======================= +Required Node Structure +======================= +The camera PPI node must be described in First level of device nodes. The +first level describe the overall PPI node structure. + +====================================== +First Level Node - PPI device +====================================== + +- compatible + Usage: required + Value type: + Definition: Should be "qcom,ppi-v1.0", + "qcom,ppi-v1.1", "qcom,ppi-v1.2", + "qcom,ppi-v2.0", "qcom,ppi". + +- cell-index: ppi hardware core index + Usage: required + Value type: + Definition: Should specify the Hardware index id. + +- reg + Usage: required + Value type: + Definition: offset and length of the register set + for the device for the ppi operating in + compatible mode. + +- reg-names + Usage: required + Value type: + Definition: Should specify relevant names to each + reg property defined. + +- reg-cam-base + Usage: required + Value type: + Definition: offset of PPI in camera hw block + +- interrupts + Usage: required + Value type: + Definition: Interrupt associated with PPI HW. + +- interrupt-names + Usage: required + Value type: + Definition: Name of the interrupt. + +- clock-names + Usage: required + Value type: + Definition: List of clock names required for PPI HW. + +- clock-rates + Usage: required + Value type: + Definition: List of clock rates in Hz for PPI HW. + +- clock-cntl-level + Usage: required + Value type: + Definition: All different clock level node can support. + +- clocks + Usage: required + Value type: + Definition: all clock phandle and source clocks. + +- regulator-names + Usage: required + Value type: + Definition: name of the voltage regulators required for the device. + +- gdscr-supply + Usage: required + Value type: + Definition: should contain gdsr regulator used for PPI clocks. + +Example: + qcom,ppi0@ace0000 { + cell-index = <0>; + compatible = "qcom,ppi170"; + reg-names = "ppi"; + reg = <0xace0000 0x200>; + reg-cam-base = <0xe0000>; + interrupt-names = "ppi"; + interrupts = <0 202 0>; + regulator-names = "gdscr", "refgen"; + gdscr-supply = <&titan_top_gdsc>; + clocks = <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&clock_camcc CAM_CC_PPI0_CLK>, + <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>, + <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK>; + clock-names = "cphy_rx_clk_src", "ppi0_clk" + clock-rates = <400000000 0 300000000 0>; + clock-cntl-level = "turbo"; + status = "ok"; +}; diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h b/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h index 6b7a9007cff9..2afdafb03184 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h @@ -262,6 +262,16 @@ struct cam_hw_dump_pf_args { bool *mem_found; }; +/** + * struct cam_hw_reset_args -hw reset arguments + * + * @ctxt_to_hw_map: HW context from the acquire + * + */ +struct cam_hw_reset_args { + void *ctxt_to_hw_map; +}; + /* enum cam_hw_mgr_command - Hardware manager command type */ enum cam_hw_mgr_command { CAM_HW_MGR_CMD_INTERNAL, @@ -313,6 +323,7 @@ struct cam_hw_cmd_args { * @hw_open: Function pointer for HW init * @hw_close: Function pointer for HW deinit * @hw_flush: Function pointer for HW flush + * @hw_reset: Function pointer for HW reset * */ struct cam_hw_mgr_intf { @@ -333,6 +344,7 @@ struct cam_hw_mgr_intf { int (*hw_open)(void *hw_priv, void *fw_download_args); int (*hw_close)(void *hw_priv, void *hw_close_args); int (*hw_flush)(void *hw_priv, void *hw_flush_args); + int (*hw_reset)(void *hw_priv, void *hw_reset_args); }; #endif /* _CAM_HW_MGR_INTF_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c index 719fb12d7353..aaa435d34f4c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c +++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c @@ -21,6 +21,7 @@ #include "cam_cpas_soc.h" #include "cpastop100.h" #include "cpastop_v150_100.h" +#include "cpastop_v150_110.h" #include "cpastop_v170_110.h" #include "cpastop_v175_100.h" #include "cpastop_v175_101.h" @@ -117,6 +118,10 @@ static int cam_cpastop_get_hw_info(struct cam_hw_info *cpas_hw, (hw_caps->cpas_version.minor == 0) && (hw_caps->cpas_version.incr == 0)) soc_info->hw_version = CAM_CPAS_TITAN_150_V100; + else if ((hw_caps->cpas_version.major == 1) && + (hw_caps->cpas_version.minor == 1) && + (hw_caps->cpas_version.incr == 0)) + soc_info->hw_version = CAM_CPAS_TITAN_150_V110; } CAM_DBG(CAM_CPAS, "CPAS HW VERSION %x", soc_info->hw_version); @@ -668,6 +673,9 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw, case CAM_CPAS_TITAN_150_V100: camnoc_info = &cam150_cpas100_camnoc_info; break; + case CAM_CPAS_TITAN_150_V110: + camnoc_info = &cam150_cpas110_camnoc_info; + break; default: CAM_ERR(CAM_CPAS, "Camera Version not supported %d.%d.%d", hw_caps->camera_version.major, diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cpastop_v150_110.h b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cpastop_v150_110.h new file mode 100644 index 000000000000..734f3784ef6c --- /dev/null +++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cpastop_v150_110.h @@ -0,0 +1,537 @@ +/* Copyright (c) 2019, 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 _CPASTOP_V150_110_H_ +#define _CPASTOP_V150_110_H_ + +#define TEST_IRQ_ENABLE 0 + +static struct cam_camnoc_irq_sbm cam_cpas_v150_110_irq_sbm = { + .sbm_enable = { + .access_type = CAM_REG_TYPE_READ_WRITE, + .enable = true, + .offset = 0x2040, /* SBM_FAULTINEN0_LOW */ + .value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/ + 0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */ + 0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */ + 0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */ + 0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */ + 0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */ + (TEST_IRQ_ENABLE ? + 0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */ + 0x0), + }, + .sbm_status = { + .access_type = CAM_REG_TYPE_READ, + .enable = true, + .offset = 0x2048, /* SBM_FAULTINSTATUS0_LOW */ + }, + .sbm_clear = { + .access_type = CAM_REG_TYPE_WRITE, + .enable = true, + .offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */ + .value = TEST_IRQ_ENABLE ? 0x6 : 0x2, + } +}; + +static struct cam_camnoc_irq_err + cam_cpas_v150_110_irq_err[] = { + { + .irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR, + .enable = true, + .sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */ + .err_enable = { + .access_type = CAM_REG_TYPE_READ_WRITE, + .enable = true, + .offset = 0x2708, /* ERRLOGGER_MAINCTL_LOW */ + .value = 1, + }, + .err_status = { + .access_type = CAM_REG_TYPE_READ, + .enable = true, + .offset = 0x2710, /* ERRLOGGER_ERRVLD_LOW */ + }, + .err_clear = { + .access_type = CAM_REG_TYPE_WRITE, + .enable = true, + .offset = 0x2718, /* ERRLOGGER_ERRCLR_LOW */ + .value = 1, + }, + }, + { + .irq_type = CAM_CAMNOC_HW_IRQ_IFE02_UBWC_ENCODE_ERROR, + .enable = true, + .sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */ + .err_enable = { + .access_type = CAM_REG_TYPE_READ_WRITE, + .enable = true, + .offset = 0x5a0, /* SPECIFIC_IFE02_ENCERREN_LOW */ + .value = 1, + }, + .err_status = { + .access_type = CAM_REG_TYPE_READ, + .enable = true, + .offset = 0x590, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */ + }, + .err_clear = { + .access_type = CAM_REG_TYPE_WRITE, + .enable = true, + .offset = 0x598, /* SPECIFIC_IFE02_ENCERRCLR_LOW */ + .value = 1, + }, + }, + { + .irq_type = CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR, + .enable = true, + .sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */ + .err_enable = { + .access_type = CAM_REG_TYPE_READ_WRITE, + .enable = true, + .offset = 0x9a0, /* SPECIFIC_IFE13_ENCERREN_LOW */ + .value = 1, + }, + .err_status = { + .access_type = CAM_REG_TYPE_READ, + .enable = true, + .offset = 0x990, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */ + }, + .err_clear = { + .access_type = CAM_REG_TYPE_WRITE, + .enable = true, + .offset = 0x998, /* SPECIFIC_IFE13_ENCERRCLR_LOW */ + .value = 1, + }, + }, + { + .irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR, + .enable = true, + .sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */ + .err_enable = { + .access_type = CAM_REG_TYPE_READ_WRITE, + .enable = true, + .offset = 0xd20, /* SPECIFIC_IBL_RD_DECERREN_LOW */ + .value = 1, + }, + .err_status = { + .access_type = CAM_REG_TYPE_READ, + .enable = true, + .offset = 0xd10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */ + }, + .err_clear = { + .access_type = CAM_REG_TYPE_WRITE, + .enable = true, + .offset = 0xd18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */ + .value = 1, + }, + }, + { + .irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR, + .enable = true, + .sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */ + .err_enable = { + .access_type = CAM_REG_TYPE_READ_WRITE, + .enable = true, + .offset = 0x11a0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */ + .value = 1, + }, + .err_status = { + .access_type = CAM_REG_TYPE_READ, + .enable = true, + .offset = 0x1190, + /* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */ + }, + .err_clear = { + .access_type = CAM_REG_TYPE_WRITE, + .enable = true, + .offset = 0x1198, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */ + .value = 1, + }, + }, + { + .irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT, + .enable = true, + .sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */ + .err_enable = { + .access_type = CAM_REG_TYPE_READ_WRITE, + .enable = true, + .offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */ + .value = 0x1, + }, + .err_status = { + .access_type = CAM_REG_TYPE_READ, + .enable = true, + .offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */ + }, + .err_clear = { + .enable = false, + }, + }, + { + .irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1, + .enable = false, + }, + { + .irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2, + .enable = false, + }, + { + .irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST, + .enable = TEST_IRQ_ENABLE ? true : false, + .sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */ + .err_enable = { + .access_type = CAM_REG_TYPE_READ_WRITE, + .enable = true, + .offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */ + .value = 0x5, + }, + .err_status = { + .access_type = CAM_REG_TYPE_READ, + .enable = true, + .offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */ + }, + .err_clear = { + .enable = false, + }, + }, +}; + +static struct cam_camnoc_specific + cam_cpas_v150_110_camnoc_specific[] = { + { + .port_type = CAM_CAMNOC_CDM, + .enable = true, + .priority_lut_low = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x30, /* SPECIFIC_CDM_PRIORITYLUT_LOW */ + .value = 0x22222222, + }, + .priority_lut_high = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x34, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */ + .value = 0x22222222, + }, + .urgency = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 1, + .offset = 0x38, /* SPECIFIC_CDM_URGENCY_LOW */ + .mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */ + .shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */ + .value = 0x2, + }, + .danger_lut = { + .enable = false, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x40, /* SPECIFIC_CDM_DANGERLUT_LOW */ + .value = 0x0, + }, + .safe_lut = { + .enable = false, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x48, /* SPECIFIC_CDM_SAFELUT_LOW */ + .value = 0x0, + }, + .ubwc_ctl = { + .enable = false, + }, + }, + { + .port_type = CAM_CAMNOC_IFE02, + .enable = true, + .priority_lut_low = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x430, /* SPECIFIC_IFE02_PRIORITYLUT_LOW */ + .value = 0x66665433, + }, + .priority_lut_high = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x434, /* SPECIFIC_IFE02_PRIORITYLUT_HIGH */ + .value = 0x66666666, + }, + .urgency = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 1, + .offset = 0x438, /* SPECIFIC_IFE02_URGENCY_LOW */ + /* SPECIFIC_IFE02_URGENCY_LOW_WRITE_MASK */ + .mask = 0x70, + /* SPECIFIC_IFE02_URGENCY_LOW_WRITE_SHIFT */ + .shift = 0x4, + .value = 0x30, + }, + .danger_lut = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .offset = 0x440, /* SPECIFIC_IFE02_DANGERLUT_LOW */ + .value = 0xFFFFFF00, + }, + .safe_lut = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .offset = 0x448, /* SPECIFIC_IFE02_SAFELUT_LOW */ + .value = 0x1, + }, + .ubwc_ctl = { + .enable = false, + }, + }, + { + .port_type = CAM_CAMNOC_IFE13, + .enable = true, + .priority_lut_low = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x830, /* SPECIFIC_IFE13_PRIORITYLUT_LOW */ + .value = 0x66665433, + }, + .priority_lut_high = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x834, /* SPECIFIC_IFE13_PRIORITYLUT_HIGH */ + .value = 0x66666666, + }, + .urgency = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 1, + .offset = 0x838, /* SPECIFIC_IFE13_URGENCY_LOW */ + /* SPECIFIC_IFE13_URGENCY_LOW_WRITE_MASK */ + .mask = 0x70, + /* SPECIFIC_IFE13_URGENCY_LOW_WRITE_SHIFT */ + .shift = 0x4, + .value = 0x30, + }, + .danger_lut = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .offset = 0x840, /* SPECIFIC_IFE13_DANGERLUT_LOW */ + .value = 0xFFFFFF00, + }, + .safe_lut = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .offset = 0x848, /* SPECIFIC_IFE13_SAFELUT_LOW */ + .value = 0x1, + }, + .ubwc_ctl = { + .enable = false, + }, + }, + { + .port_type = CAM_CAMNOC_IPE_BPS_LRME_READ, + .enable = true, + .priority_lut_low = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0xc30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */ + .value = 0x33333333, + }, + .priority_lut_high = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0xc34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */ + .value = 0x33333333, + }, + .urgency = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 1, + .offset = 0xc38, /* SPECIFIC_IBL_RD_URGENCY_LOW */ + /* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */ + .mask = 0x7, + /* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */ + .shift = 0x0, + .value = 3, + }, + .danger_lut = { + .enable = false, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0xc40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */ + .value = 0x0, + }, + .safe_lut = { + .enable = false, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0xc48, /* SPECIFIC_IBL_RD_SAFELUT_LOW */ + .value = 0x0, + }, + .ubwc_ctl = { + .enable = false, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */ + .value = 1, + }, + }, + { + .port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE, + .enable = true, + .priority_lut_low = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x1030, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */ + .value = 0x33333333, + }, + .priority_lut_high = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x1034, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */ + .value = 0x33333333, + }, + .urgency = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 1, + .offset = 0x1038, /* SPECIFIC_IBL_WR_URGENCY_LOW */ + /* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */ + .mask = 0x70, + /* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */ + .shift = 0x4, + .value = 0x30, + }, + .danger_lut = { + .enable = false, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x1040, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */ + .value = 0x0, + }, + .safe_lut = { + .enable = false, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x1048, /* SPECIFIC_IBL_WR_SAFELUT_LOW */ + .value = 0x0, + }, + .ubwc_ctl = { + .enable = false, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */ + .value = 0x5, + }, + }, + { + .port_type = CAM_CAMNOC_JPEG, + .enable = true, + .priority_lut_low = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x1430, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */ + .value = 0x22222222, + }, + .priority_lut_high = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x1434, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */ + .value = 0x22222222, + }, + .urgency = { + .enable = true, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x1438, /* SPECIFIC_JPEG_URGENCY_LOW */ + .value = 0x22, + }, + .danger_lut = { + .enable = false, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x1440, /* SPECIFIC_JPEG_DANGERLUT_LOW */ + .value = 0x0, + }, + .safe_lut = { + .enable = false, + .access_type = CAM_REG_TYPE_READ_WRITE, + .masked_value = 0, + .offset = 0x1448, /* SPECIFIC_JPEG_SAFELUT_LOW */ + .value = 0x0, + }, + .ubwc_ctl = { + .enable = false, + }, + }, + { + .port_type = CAM_CAMNOC_FD, + .enable = false, + }, + { + .port_type = CAM_CAMNOC_ICP, + .enable = true, + .flag_out_set0_low = { + .enable = true, + .access_type = CAM_REG_TYPE_WRITE, + .masked_value = 0, + .offset = 0x2088, + .value = 0x100000, + }, + }, +}; + +static struct cam_camnoc_err_logger_info cam150_cpas110_err_logger_offsets = { + .mainctrl = 0x2708, /* ERRLOGGER_MAINCTL_LOW */ + .errvld = 0x2710, /* ERRLOGGER_ERRVLD_LOW */ + .errlog0_low = 0x2720, /* ERRLOGGER_ERRLOG0_LOW */ + .errlog0_high = 0x2724, /* ERRLOGGER_ERRLOG0_HIGH */ + .errlog1_low = 0x2728, /* ERRLOGGER_ERRLOG1_LOW */ + .errlog1_high = 0x272c, /* ERRLOGGER_ERRLOG1_HIGH */ + .errlog2_low = 0x2730, /* ERRLOGGER_ERRLOG2_LOW */ + .errlog2_high = 0x2734, /* ERRLOGGER_ERRLOG2_HIGH */ + .errlog3_low = 0x2738, /* ERRLOGGER_ERRLOG3_LOW */ + .errlog3_high = 0x273c, /* ERRLOGGER_ERRLOG3_HIGH */ +}; + +static struct cam_cpas_hw_errata_wa_list cam150_cpas110_errata_wa_list = { + .camnoc_flush_slave_pending_trans = { + .enable = false, + .data.reg_info = { + .access_type = CAM_REG_TYPE_READ, + .offset = 0x2100, /* SidebandManager_SenseIn0_Low */ + .mask = 0xE0000, /* Bits 17, 18, 19 */ + .value = 0, /* expected to be 0 */ + }, + }, +}; + +static struct cam_camnoc_info cam150_cpas110_camnoc_info = { + .specific = &cam_cpas_v150_110_camnoc_specific[0], + .specific_size = sizeof(cam_cpas_v150_110_camnoc_specific) / + sizeof(cam_cpas_v150_110_camnoc_specific[0]), + .irq_sbm = &cam_cpas_v150_110_irq_sbm, + .irq_err = &cam_cpas_v150_110_irq_err[0], + .irq_err_size = sizeof(cam_cpas_v150_110_irq_err) / + sizeof(cam_cpas_v150_110_irq_err[0]), + .err_logger = &cam150_cpas110_err_logger_offsets, + .errata_wa_list = &cam150_cpas110_errata_wa_list, +}; + +#endif /* _CPASTOP_V150_110_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/include/cam_cpas_api.h b/drivers/media/platform/msm/camera_v3/cam_cpas/include/cam_cpas_api.h index 7b534a93c71d..f2858631ce29 100644 --- a/drivers/media/platform/msm/camera_v3/cam_cpas/include/cam_cpas_api.h +++ b/drivers/media/platform/msm/camera_v3/cam_cpas/include/cam_cpas_api.h @@ -43,6 +43,7 @@ enum cam_cpas_reg_base { enum cam_cpas_hw_version { CAM_CPAS_TITAN_NONE = 0, CAM_CPAS_TITAN_150_V100 = 0x150100, + CAM_CPAS_TITAN_150_V110 = 0x150110, CAM_CPAS_TITAN_170_V100 = 0x170100, CAM_CPAS_TITAN_170_V110 = 0x170110, CAM_CPAS_TITAN_170_V120 = 0x170120, diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c index 94d531d3d80f..53c1c0fd54a9 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c @@ -452,6 +452,14 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( trace_cam_buf_done("ISP", ctx, req); req_isp = (struct cam_isp_ctx_req *) req->req_priv; + if (ctx_isp->frame_id == 1) + ctx_isp->irq_timestamps = done->irq_mono_boot_time; + else if (ctx_isp->fps && ((done->irq_mono_boot_time - + ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps))) + ctx_isp->irq_delay_detect = true; + + ctx_isp->irq_timestamps = done->irq_mono_boot_time; + for (i = 0; i < done->num_handles; i++) { for (j = 0; j < req_isp->num_fence_map_out; j++) { if (done->resource_handle[i] == @@ -565,6 +573,26 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( ctx_isp->substate_activated); } + if (ctx_isp->active_req_cnt && ctx_isp->irq_delay_detect) { + CAM_ERR(CAM_ISP, "isp req[%lld] IRQ buf done got delayed", + req->request_id); + req = list_first_entry(&ctx->active_req_list, + struct cam_ctx_request, list); + req_isp = (struct cam_isp_ctx_req *) req->req_priv; + + for (j = 0; j < req_isp->num_fence_map_out; j++) { + rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id, + CAM_SYNC_STATE_SIGNALED_ERROR); + if (rc) + CAM_DBG(CAM_ISP, "Sync failed with rc = %d", + rc); + req_isp->fence_map_out[j].sync_id = -1; + } + list_del_init(&req->list); + list_add_tail(&req->list, &ctx->free_req_list); + ctx_isp->active_req_cnt--; + } + ctx_isp->irq_delay_detect = false; end: return rc; } @@ -643,12 +671,47 @@ static void __cam_isp_ctx_send_sof_timestamp( static int __cam_isp_ctx_reg_upd_in_epoch_state( struct cam_isp_context *ctx_isp, void *evt_data) { - if (ctx_isp->frame_id == 1) + struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data; + + struct cam_context *ctx = ctx_isp->base; + struct cam_ctx_request *req = NULL; + struct cam_isp_ctx_req *req_isp = NULL; + + if (ctx_isp->frame_id == 1) { CAM_DBG(CAM_ISP, "Reg update for early PCR"); - else + if (!list_empty(&ctx->active_req_list)) { + req = list_first_entry(&ctx->active_req_list, + struct cam_ctx_request, list); + req_isp = (struct cam_isp_ctx_req *) req->req_priv; + } else if (!list_empty(&ctx->wait_req_list)) { + req = list_first_entry(&ctx->active_req_list, + struct cam_ctx_request, list); + req_isp = (struct cam_isp_ctx_req *) req->req_priv; + } + } else { + if (!list_empty(&ctx->wait_req_list)) { + req = list_first_entry(&ctx->active_req_list, + struct cam_ctx_request, list); + req_isp = (struct cam_isp_ctx_req *) req->req_priv; + } CAM_WARN(CAM_ISP, "Unexpected reg update in activated substate:%d for frame_id:%lld", ctx_isp->substate_activated, ctx_isp->frame_id); + } + + if (req_isp && req_isp->hw_update_data.fps) { + ctx_isp->fps = req_isp->hw_update_data.fps; + CAM_DBG(CAM_ISP, "req_isp %pK, Upadting ctx_isp->fps %d", + req_isp, ctx_isp->fps); + } + + if (ctx_isp->frame_id == 1) + ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time; + else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time - + ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps))) + ctx_isp->irq_delay_detect = true; + + ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time; return 0; } @@ -658,7 +721,8 @@ static int __cam_isp_ctx_reg_upd_in_activated_state( int rc = 0; struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; - struct cam_isp_ctx_req *req_isp; + struct cam_isp_ctx_req *req_isp = NULL; + struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data; if (list_empty(&ctx->wait_req_list)) { CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request"); @@ -683,13 +747,22 @@ static int __cam_isp_ctx_reg_upd_in_activated_state( req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); } + if (req_isp && req_isp->hw_update_data.fps) + ctx_isp->fps = req_isp->hw_update_data.fps; + /* * This function only called directly from applied and bubble applied * state so change substate here. */ ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH; CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); + if (ctx_isp->frame_id == 1) + ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time; + else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time - + ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps))) + ctx_isp->irq_delay_detect = true; + ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time; end: return rc; } @@ -817,6 +890,14 @@ static int __cam_isp_ctx_sof_in_activated_state( ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->boot_timestamp = sof_event_data->boot_time; + if (ctx_isp->frame_id == 1) + ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time; + else if (ctx_isp->fps && ((sof_event_data->irq_mono_boot_time - + ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps))) + ctx_isp->irq_delay_detect = true; + + ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time; + CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u", ctx_isp->frame_id, ctx_isp->sof_timestamp_val, ctx->ctx_id); @@ -828,8 +909,9 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, { int rc = 0; struct cam_ctx_request *req = NULL; - struct cam_isp_ctx_req *req_isp; + struct cam_isp_ctx_req *req_isp = NULL; struct cam_context *ctx = ctx_isp->base; + struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data; if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) { CAM_DBG(CAM_ISP, "invalid RUP"); @@ -852,6 +934,16 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, "receive rup in unexpected state"); } + if (req_isp && req_isp->hw_update_data.fps) + ctx_isp->fps = req_isp->hw_update_data.fps; + + if (ctx_isp->frame_id == 1) + ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time; + else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time - + ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps))) + ctx_isp->irq_delay_detect = true; + + ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time; end: return rc; } @@ -860,9 +952,10 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, void *evt_data) { struct cam_ctx_request *req; - struct cam_isp_ctx_req *req_isp; + struct cam_isp_ctx_req *req_isp = NULL; struct cam_context *ctx = ctx_isp->base; uint64_t request_id = 0; + struct cam_isp_hw_epoch_event_data *epoch_hw_event_data = evt_data; if (list_empty(&ctx->wait_req_list)) { /* @@ -928,6 +1021,15 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, ctx_isp->substate_activated); end: + if (ctx_isp->frame_id == 1) + ctx_isp->irq_timestamps = + epoch_hw_event_data->irq_mono_boot_time; + else if (ctx_isp->fps && ((epoch_hw_event_data->irq_mono_boot_time - + ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps))) + ctx_isp->irq_delay_detect = true; + + ctx_isp->irq_timestamps = epoch_hw_event_data->irq_mono_boot_time; + return 0; } @@ -960,6 +1062,14 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp, ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->boot_timestamp = sof_event_data->boot_time; + if (ctx_isp->frame_id == 1) + ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time; + else if (ctx_isp->fps && ((sof_event_data->irq_mono_boot_time - + ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps))) + ctx_isp->irq_delay_detect = true; + + ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time; + if (list_empty(&ctx->active_req_list)) ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; else @@ -1442,7 +1552,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp, { int rc = 0; struct cam_ctx_request *req = NULL; - struct cam_isp_ctx_req *req_isp; + struct cam_isp_ctx_req *req_isp = NULL; struct cam_context *ctx = ctx_isp->base; if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) { @@ -1466,6 +1576,9 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp, "receive rup in unexpected state"); } + if (req_isp && req_isp->hw_update_data.fps) + ctx_isp->fps = req_isp->hw_update_data.fps; + end: return rc; } @@ -1476,7 +1589,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( int rc = 0; struct cam_ctx_request *req = NULL; struct cam_context *ctx = ctx_isp->base; - struct cam_isp_ctx_req *req_isp; + struct cam_isp_ctx_req *req_isp = NULL; struct cam_req_mgr_trigger_notify notify; uint64_t request_id = 0; @@ -1499,6 +1612,9 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( list_add_tail(&req->list, &ctx->free_req_list); } + if (req_isp && req_isp->hw_update_data.fps) + ctx_isp->fps = req_isp->hw_update_data.fps; + /* * This function only called directly from applied and bubble applied * state so change substate here. @@ -1922,16 +2038,19 @@ static int __cam_isp_ctx_flush_req_in_top_state( struct cam_req_mgr_flush_request *flush_req) { int rc = 0; - struct cam_isp_context *ctx_isp; - - ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; + struct cam_isp_context *ctx_isp = + (struct cam_isp_context *) ctx->ctx_priv; + struct cam_isp_stop_args stop_isp; + struct cam_hw_stop_args stop_args; + struct cam_isp_start_args start_isp; + struct cam_hw_reset_args reset_args; if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) { - CAM_INFO(CAM_ISP, "Last request id to flush is %lld", - flush_req->req_id); + CAM_INFO(CAM_ISP, "ctx id:%d Last request id to flush is %lld", + ctx->ctx_id, flush_req->req_id); ctx->last_flush_req = flush_req->req_id; } - CAM_DBG(CAM_ISP, "try to flush pending list"); + CAM_DBG(CAM_ISP, "ctx id:%d try to flush pending list", ctx->ctx_id); spin_lock_bh(&ctx->lock); rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req); @@ -1954,6 +2073,57 @@ static int __cam_isp_ctx_flush_req_in_top_state( spin_unlock_bh(&ctx->lock); atomic_set(&ctx_isp->process_bubble, 0); + if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) { + /* if active and wait list are empty, return */ + spin_lock_bh(&ctx->lock); + if ((list_empty(&ctx->wait_req_list)) && + (list_empty(&ctx->active_req_list))) { + spin_unlock_bh(&ctx->lock); + CAM_DBG(CAM_ISP, "ctx id:%d active,wait list are empty", + ctx->ctx_id); + goto end; + } + spin_unlock_bh(&ctx->lock); + + /* Stop hw first before active list flush */ + CAM_DBG(CAM_ISP, "ctx id:%d try to stop hw", ctx->ctx_id); + stop_args.ctxt_to_hw_map = ctx_isp->hw_ctx; + stop_isp.hw_stop_cmd = CAM_ISP_HW_STOP_AT_FRAME_BOUNDARY; + stop_isp.stop_only = true; + stop_args.args = (void *)&stop_isp; + ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv, + &stop_args); + + spin_lock_bh(&ctx->lock); + CAM_DBG(CAM_ISP, "try to flush wait list"); + rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list, + flush_req); + CAM_DBG(CAM_ISP, "try to flush active list"); + rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list, + flush_req); + ctx_isp->active_req_cnt = 0; + spin_unlock_bh(&ctx->lock); + + CAM_DBG(CAM_ISP, "try to reset hw"); + /* Reset hw */ + reset_args.ctxt_to_hw_map = ctx_isp->hw_ctx; + rc = ctx->hw_mgr_intf->hw_reset(ctx->hw_mgr_intf->hw_mgr_priv, + &reset_args); + if (rc) + goto end; + + CAM_DBG(CAM_ISP, "ctx id%d try to start hw", ctx->ctx_id); + /* Start hw */ + start_isp.hw_config.ctxt_to_hw_map = ctx_isp->hw_ctx; + start_isp.start_only = true; + start_isp.hw_config.priv = NULL; + + rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv, + &start_isp); + } + +end: + ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; return rc; } @@ -2339,7 +2509,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( { struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; - struct cam_isp_ctx_req *req_isp; + struct cam_isp_ctx_req *req_isp = NULL; struct cam_req_mgr_trigger_notify notify; uint64_t request_id = 0; @@ -2394,6 +2564,9 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( jiffies_to_msecs(jiffies); } + if (req_isp && req_isp->hw_update_data.fps) + ctx_isp->fps = req_isp->hw_update_data.fps; + __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); @@ -2669,7 +2842,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( { int rc = 0, i; struct cam_ctx_request *req = NULL; - struct cam_isp_ctx_req *req_isp; + struct cam_isp_ctx_req *req_isp = NULL; uintptr_t packet_addr; struct cam_packet *packet; size_t len = 0; @@ -2758,6 +2931,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( rc = -EFAULT; goto free_cpu_buf; } + req_isp->num_cfg = cfg.num_hw_update_entries; req_isp->num_fence_map_out = cfg.num_out_map_entries; req_isp->num_fence_map_in = cfg.num_in_map_entries; @@ -2814,6 +2988,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( CAM_ERR(CAM_ISP, "Recevied Update in wrong state"); } } + if (rc) goto put_ref; @@ -3595,8 +3770,6 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx, return rc; } - - static int __cam_isp_ctx_handle_irq_in_activated(void *context, uint32_t evt_id, void *evt_data) { diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h index a4f4e5ae0ee9..cb73252363db 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h @@ -34,6 +34,11 @@ */ #define CAM_ISP_CTX_CFG_MAX 22 +/* + * Defalut fps value set to 30 + */ +#define CAM_ISP_CTX_DEFAULT_FPS 30 + /* * Maximum entries in state monitoring array for error logging */ @@ -180,6 +185,9 @@ struct cam_isp_context_req_id_info { * @hw_acquired: Indicate whether HW resources are acquired * @init_received: Indicate whether init config packet is received * @split_acquire: Indicate whether a separate acquire is expected + * @irq_delay_detect: Indicate whether a irq delay has detected or not + * @irq_timestamps: Timestamp from last handled IRQ + * @fps: Current FPS for the activated state. * */ struct cam_isp_context { @@ -209,6 +217,9 @@ struct cam_isp_context { bool hw_acquired; bool init_received; bool split_acquire; + bool irq_delay_detect; + uint64_t irq_timestamps; + uint32_t fps; }; /** diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index cfc902af7a2b..91e1e74f7360 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -146,6 +146,74 @@ static int cam_ife_hw_mgr_is_rdi_res(uint32_t res_id) return rc; } +static const char *cam_ife_hw_mgr_get_res_id( + enum cam_ife_pix_path_res_id csid_res_id) +{ + char *res_name = NULL; + + switch (csid_res_id) { + case CAM_IFE_PIX_PATH_RES_RDI_0: + res_name = "RDI_0"; + break; + case CAM_IFE_PIX_PATH_RES_RDI_1: + res_name = "RDI_1"; + break; + case CAM_IFE_PIX_PATH_RES_RDI_2: + res_name = "RDI_2"; + break; + case CAM_IFE_PIX_PATH_RES_RDI_3: + res_name = "RDI_3"; + break; + case CAM_IFE_PIX_PATH_RES_IPP: + res_name = "IPP"; + break; + case CAM_IFE_PIX_PATH_RES_PPP: + res_name = "PPP"; + break; + case CAM_IFE_PIX_PATH_RES_MAX: + res_name = "Invalid Max res"; + break; + default: + res_name = "Invalid"; + break; + } + return res_name; +} + +static const char *cam_ife_hw_mgr_get_res_type( + enum cam_isp_resource_type csid_res_type) +{ + char *res_type = NULL; + + switch (csid_res_type) { + case CAM_ISP_RESOURCE_UNINT: + res_type = "Unint"; + break; + case CAM_ISP_RESOURCE_SRC: + res_type = "Src"; + break; + case CAM_ISP_RESOURCE_CID: + res_type = "Cid"; + break; + case CAM_ISP_RESOURCE_PIX_PATH: + res_type = "Pix Path"; + break; + case CAM_ISP_RESOURCE_VFE_IN: + res_type = "Vfe In"; + break; + case CAM_ISP_RESOURCE_VFE_OUT: + res_type = "Vfe Out"; + break; + case CAM_ISP_RESOURCE_MAX: + res_type = "Invalid Max res"; + break; + default: + res_type = "Invalid"; + break; + } + return res_type; +} + static int cam_ife_hw_mgr_reset_csid_res( struct cam_ife_hw_mgr_res *isp_hw_res) { @@ -599,6 +667,61 @@ static int cam_ife_hw_mgr_get_ctx( return rc; } +static void cam_ife_hw_mgr_dump_all_ctx( + struct cam_ife_hw_mgr_ctx *ife_ctx) +{ + uint32_t i; + struct cam_ife_hw_mgr_ctx *ctx; + struct cam_ife_hw_mgr_res *hw_mgr; + + mutex_lock(&g_ife_hw_mgr.ctx_mutex); + list_for_each_entry(ctx, &g_ife_hw_mgr.used_ctx_list, list) { + CAM_ERR_RATE_LIMIT(CAM_ISP, + "ctx id:%d dual:%d in src:%d num_base:%d rdi only:%d", + ctx->ctx_index, + ctx->res_list_ife_in.is_dual_vfe, + ctx->res_list_ife_in.res_id, + ctx->num_base, ctx->is_rdi_only_context); + list_for_each_entry(hw_mgr, &ctx->res_list_ife_csid, + list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr->hw_res[i]) + continue; + CAM_ERR_RATE_LIMIT(CAM_ISP, + "csid:%d res_type:%s id:%s state:%d", + hw_mgr->hw_res[i]->hw_intf->hw_idx, + cam_ife_hw_mgr_get_res_type( + hw_mgr->hw_res[i]->res_type), + cam_ife_hw_mgr_get_res_id( + hw_mgr->hw_res[i]->res_id), + hw_mgr->hw_res[i]->res_state); + } + } + list_for_each_entry(hw_mgr, &ctx->res_list_ife_src, + list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr->hw_res[i]) + continue; + CAM_ERR_RATE_LIMIT(CAM_ISP, + "Src IFE:%d res_type:%s id:%s state:%d", + hw_mgr->hw_res[i]->hw_intf->hw_idx, + cam_ife_hw_mgr_get_res_type( + hw_mgr->hw_res[i]->res_type), + cam_ife_hw_mgr_get_res_id( + hw_mgr->hw_res[i]->res_id), + hw_mgr->hw_res[i]->res_state); + } + } + } + CAM_ERR_RATE_LIMIT(CAM_ISP, + "Current ctx id:%d dual:%d in src:%d num_base:%d rdi only:%d", + ife_ctx->ctx_index, + ife_ctx->res_list_ife_in.is_dual_vfe, + ife_ctx->res_list_ife_in.res_id, + ife_ctx->num_base, ife_ctx->is_rdi_only_context); + mutex_unlock(&g_ife_hw_mgr.ctx_mutex); +} + static void cam_ife_mgr_add_base_info( struct cam_ife_hw_mgr_ctx *ctx, enum cam_isp_hw_split_id split_id, @@ -1509,8 +1632,9 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl( &csid_acquire, sizeof(csid_acquire)); if (rc) { CAM_ERR(CAM_ISP, - "Cannot acquire ife csid pxl path rsrc %s", - (is_ipp) ? "IPP" : "PPP"); + "Cannot acquire ife csid pxl path rsrc %s, hw=%d rc=%d", + (is_ipp) ? "IPP" : "PPP", + hw_intf->hw_idx, rc); goto put_res; } @@ -1622,7 +1746,6 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi( "CSID Path reserve failed hw=%d rc=%d cid=%d", hw_intf->hw_idx, rc, cid_res->hw_res[0]->res_id); - goto put_res; } @@ -2018,6 +2141,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) return 0; free_res: + /*Dump all the current acquired resources */ + cam_ife_hw_mgr_dump_all_ctx(ife_ctx); cam_ife_hw_mgr_release_hw_for_ctx(ife_ctx); free_cdm: cam_cdm_release(ife_ctx->cdm_handle); @@ -2172,11 +2297,13 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args) ife_ctx->ctx_in_use = 1; cam_ife_hw_mgr_put_ctx(&ife_hw_mgr->used_ctx_list, &ife_ctx); - CAM_DBG(CAM_ISP, "Exit...(success)"); return 0; + free_res: + /*Dump all the current acquired resources */ + cam_ife_hw_mgr_dump_all_ctx(ife_ctx); cam_ife_hw_mgr_release_hw_for_ctx(ife_ctx); cam_cdm_release(ife_ctx->cdm_handle); free_ctx: @@ -2572,6 +2699,11 @@ static int cam_ife_mgr_pause_hw(struct cam_ife_hw_mgr_ctx *ctx) return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_EXCLUDE); } +static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx) +{ + return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE); +} + /* entry function: stop_hw */ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) { @@ -2925,6 +3057,9 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) CAM_DBG(CAM_ISP, "START IFE OUT ... in ctx id:%d", ctx->ctx_index); + if (start_isp->start_only) + cam_ife_mgr_resume_hw(ctx); + /* start the IFE out devices */ for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) { rc = cam_ife_hw_mgr_start_hw_res( @@ -3025,6 +3160,44 @@ static int cam_ife_mgr_write(void *hw_mgr_priv, void *write_args) return -EPERM; } +static int cam_ife_mgr_reset(void *hw_mgr_priv, void *hw_reset_args) +{ + struct cam_ife_hw_mgr *hw_mgr = hw_mgr_priv; + struct cam_hw_reset_args *reset_args = hw_reset_args; + struct cam_ife_hw_mgr_ctx *ctx; + struct cam_ife_hw_mgr_res *hw_mgr_res; + uint32_t i; + int rc = 0; + + if (!hw_mgr_priv || !hw_reset_args) { + CAM_ERR(CAM_ISP, "Invalid arguments"); + return -EINVAL; + } + + ctx = (struct cam_ife_hw_mgr_ctx *)reset_args->ctxt_to_hw_map; + if (!ctx || !ctx->ctx_in_use) { + CAM_ERR(CAM_ISP, "Invalid context is used"); + return -EPERM; + } + + CAM_DBG(CAM_ISP, "reset csid and vfe hw"); + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, + list) { + rc = cam_ife_hw_mgr_reset_csid_res(hw_mgr_res); + if (rc) { + CAM_ERR(CAM_ISP, "Failed RESET (%d) rc:%d", + hw_mgr_res->res_id, rc); + goto end; + } + } + + for (i = 0; i < ctx->num_base; i++) + rc = cam_ife_mgr_reset_vfe_hw(hw_mgr, ctx->base[i].idx); + +end: + return rc; +} + static int cam_ife_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args) { @@ -3152,6 +3325,54 @@ static int cam_isp_blob_fe_update( return rc; } +static int cam_isp_blob_fps_config( + uint32_t blob_type, + struct cam_isp_generic_blob_info *blob_info, + struct cam_fps_config *fps_config, + struct cam_hw_prepare_update_args *prepare) +{ + struct cam_ife_hw_mgr_ctx *ctx = NULL; + struct cam_ife_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + struct cam_vfe_fps_config_args fps_config_args; + int rc = -EINVAL; + uint32_t i; + + ctx = prepare->ctxt_to_hw_map; + + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + + if (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) { + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf && hw_intf->hw_ops.process_cmd) { + fps_config_args.fps = + fps_config->fps; + fps_config_args.node_res = + hw_mgr_res->hw_res[i]; + + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_ISP_HW_CMD_FPS_CONFIG, + &fps_config_args, + sizeof( + struct cam_vfe_fps_config_args) + ); + if (rc) + CAM_ERR(CAM_ISP, + "Failed fps config:%d", + fps_config->fps); + } else + CAM_WARN(CAM_ISP, "NULL hw_intf!"); + } + } + } + + return rc; +} + static int cam_isp_blob_ubwc_update( uint32_t blob_type, struct cam_isp_generic_blob_info *blob_info, @@ -3528,6 +3749,75 @@ static int cam_isp_blob_clock_update( return rc; } +static int cam_isp_blob_sensor_config( + uint32_t blob_type, + struct cam_isp_generic_blob_info *blob_info, + struct cam_isp_sensor_config *dim_config, + struct cam_hw_prepare_update_args *prepare) +{ + struct cam_ife_hw_mgr_ctx *ctx = NULL; + struct cam_ife_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + struct cam_ife_sensor_dimension_update_args update_args; + int rc = -EINVAL, found = 0; + uint32_t i, j; + struct cam_isp_sensor_dimension *path_config; + + ctx = prepare->ctxt_to_hw_map; + + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + found = 1; + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf && hw_intf->hw_ops.process_cmd) { + path_config = &(dim_config->ipp_path); + update_args.ipp_path.width = + path_config->width; + update_args.ipp_path.height = + path_config->height; + update_args.ipp_path.measure_enabled = + path_config->measure_enabled; + path_config = &(dim_config->ppp_path); + update_args.ppp_path.width = + path_config->width; + update_args.ppp_path.height = + path_config->height; + update_args.ppp_path.measure_enabled = + path_config->measure_enabled; + for (j = 0; j < CAM_IFE_RDI_NUM_MAX; j++) { + path_config = + &(dim_config->rdi_path[j]); + update_args.rdi_path[j].width = + path_config->width; + update_args.rdi_path[j].height = + path_config->height; + update_args.rdi_path[j].measure_enabled = + path_config->measure_enabled; + } + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG, + &update_args, + sizeof( + struct + cam_ife_sensor_dimension_update_args) + ); + if (rc) + CAM_ERR(CAM_ISP, + "Dimension Update failed"); + } else + CAM_ERR(CAM_ISP, "hw_intf is NULL"); + } + if (found) + break; + } + + return rc; +} + + void fill_res_bitmap(uint32_t resource_type, unsigned long *res_bitmap) { @@ -3620,12 +3910,6 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, return -EINVAL; } - if (blob_type >= CAM_ISP_GENERIC_BLOB_TYPE_MAX) { - CAM_WARN(CAM_ISP, "Invalid Blob Type %d Max %d", blob_type, - CAM_ISP_GENERIC_BLOB_TYPE_MAX); - return 0; - } - prepare = blob_info->prepare; if (!prepare) { CAM_ERR(CAM_ISP, "Failed. prepare is NULL, blob_type %d", @@ -3633,7 +3917,6 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, return -EINVAL; } - CAM_DBG(CAM_ISP, "FS2: BLOB Type: %d", blob_type); switch (blob_type) { case CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG: { struct cam_isp_resource_hfr_config *hfr_config; @@ -3866,6 +4149,50 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, rc = cam_isp_blob_init_frame_drop(frame_drop_cfg, prepare); if (rc) CAM_ERR(CAM_ISP, "Init Frame drop Update Failed"); + } + break; + case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG: { + struct cam_isp_sensor_config *csid_dim_config; + + if (blob_size < sizeof(struct cam_isp_sensor_config)) { + CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu", + blob_size, + sizeof(struct cam_isp_sensor_config)); + return -EINVAL; + } + + csid_dim_config = + (struct cam_isp_sensor_config *)blob_data; + + rc = cam_isp_blob_sensor_config(blob_type, blob_info, + csid_dim_config, prepare); + if (rc) + CAM_ERR(CAM_ISP, + "Sensor Dimension Update Failed rc: %d", rc); + } + break; + case CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG: { + struct cam_fps_config *fps_config; + struct cam_isp_prepare_hw_update_data *prepare_hw_data; + + if (blob_size < sizeof(struct cam_fps_config)) { + CAM_ERR(CAM_ISP, + "Invalid fps blob size %u expected %lu", + blob_size, sizeof(struct cam_fps_config)); + return -EINVAL; + } + + fps_config = (struct cam_fps_config *)blob_data; + prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) + prepare->priv; + + prepare_hw_data->fps = fps_config->fps; + + rc = cam_isp_blob_fps_config(blob_type, blob_info, + fps_config, prepare); + if (rc) + CAM_ERR(CAM_ISP, "FPS Update Failed rc: %d", rc); + } break; default: @@ -4025,10 +4352,6 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, return rc; } -static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx) -{ - return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE); -} static int cam_ife_mgr_sof_irq_debug( struct cam_ife_hw_mgr_ctx *ctx, @@ -4766,6 +5089,8 @@ static int cam_ife_hw_mgr_handle_reg_update( break; if (!rup_status) { + rup_event_data.irq_mono_boot_time = + evt_payload->ts.time_usecs; ife_hwr_irq_rup_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_REG_UPDATE, @@ -4795,6 +5120,8 @@ static int cam_ife_hw_mgr_handle_reg_update( if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending)) break; if (!rup_status) { + rup_event_data.irq_mono_boot_time = + evt_payload->ts.time_usecs; /* Send the Reg update hw event */ ife_hwr_irq_rup_cb( ife_hwr_mgr_ctx->common.cb_priv, @@ -5154,6 +5481,8 @@ static int cam_ife_hw_mgr_handle_sof( ife_hw_mgr_ctx, &sof_done_event_data.timestamp, &sof_done_event_data.boot_time); + sof_done_event_data.irq_mono_boot_time = + evt_payload->ts.time_usecs; ife_hw_irq_sof_cb( ife_hw_mgr_ctx->common.cb_priv, @@ -5177,6 +5506,8 @@ static int cam_ife_hw_mgr_handle_sof( ife_hw_mgr_ctx, &sof_done_event_data.timestamp, &sof_done_event_data.boot_time); + sof_done_event_data.irq_mono_boot_time = + evt_payload->ts.time_usecs; ife_hw_irq_sof_cb( ife_hw_mgr_ctx->common.cb_priv, @@ -5262,13 +5593,15 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res( if (atomic_read( &ife_hwr_mgr_ctx->overflow_pending)) break; - if (!eof_status) + if (!eof_status) { + eof_done_event_data.irq_mono_boot_time = + evt_payload->ts.time_usecs; ife_hwr_irq_eof_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_EOF, &eof_done_event_data); + } } - break; /* Handling dual VFE Scenario */ case 1: @@ -5309,11 +5642,14 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res( if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending)) break; - if (!rc) + if (!rc) { + eof_done_event_data.irq_mono_boot_time = + evt_payload->ts.time_usecs; ife_hwr_irq_eof_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_EOF, &eof_done_event_data); + } break; @@ -5413,6 +5749,8 @@ static int cam_ife_hw_mgr_handle_buf_done_for_hw_res( if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending)) break; + buf_done_event_data.irq_mono_boot_time = + evt_payload->ts.time_usecs; /* Report for Successful buf_done event if any */ if (buf_done_event_data.num_handles > 0 && ife_hwr_irq_wm_done_cb) { @@ -5852,6 +6190,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) hw_mgr_intf->hw_prepare_update = cam_ife_mgr_prepare_hw_update; hw_mgr_intf->hw_config = cam_ife_mgr_config_hw; hw_mgr_intf->hw_cmd = cam_ife_mgr_cmd; + hw_mgr_intf->hw_reset = cam_ife_mgr_reset; if (iommu_hdl) *iommu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl; diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h index 096e0f186bbf..1ab9361af1d1 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h @@ -130,6 +130,7 @@ struct cam_isp_bw_config_internal { * @bw_config: BW config information * @bw_config_valid: Flag indicating whether the bw_config at the index * is valid or not + * @fps: fps vaue which has been updated in hw * */ struct cam_isp_prepare_hw_update_data { @@ -137,40 +138,47 @@ struct cam_isp_prepare_hw_update_data { struct cam_isp_bw_config_internal bw_config[CAM_IFE_HW_NUM_MAX]; struct cam_isp_bw_config_internal_ab bw_config_ab[CAM_IFE_HW_NUM_MAX]; bool bw_config_valid[CAM_IFE_HW_NUM_MAX]; + uint32_t fps; }; /** * struct cam_isp_hw_sof_event_data - Event payload for CAM_HW_EVENT_SOF * - * @timestamp: Time stamp for the sof event - * @boot_time: Boot time stamp for the sof event + * @timestamp: Time stamp for the sof event + * @boot_time: Boot time stamp for the sof event + * @irq_mono_boot_time: Time stamp till the execution of IRQ wrt event started * */ struct cam_isp_hw_sof_event_data { uint64_t timestamp; uint64_t boot_time; + uint64_t irq_mono_boot_time; }; /** * struct cam_isp_hw_reg_update_event_data - Event payload for * CAM_HW_EVENT_REG_UPDATE * - * @timestamp: Time stamp for the reg update event + * @timestamp: Time stamp for the reg update event + * @irq_mono_boot_time: Time stamp till the execution of IRQ wrt event started * */ struct cam_isp_hw_reg_update_event_data { uint64_t timestamp; + uint64_t irq_mono_boot_time; }; /** * struct cam_isp_hw_epoch_event_data - Event payload for CAM_HW_EVENT_EPOCH * - * @timestamp: Time stamp for the epoch event + * @timestamp: Time stamp for the epoch event + * @irq_mono_boot_time: Time stamp till the execution of this event started * */ struct cam_isp_hw_epoch_event_data { uint64_t timestamp; + uint64_t irq_mono_boot_time; }; /** @@ -179,6 +187,7 @@ struct cam_isp_hw_epoch_event_data { * @num_handles: Number of resource handeles * @resource_handle: Resource handle array * @timestamp: Timestamp for the buf done event + * @irq_mono_boot_time: Time stamp till the execution of this event started * */ struct cam_isp_hw_done_event_data { @@ -186,16 +195,19 @@ struct cam_isp_hw_done_event_data { uint32_t resource_handle[ CAM_NUM_OUT_PER_COMP_IRQ_MAX]; uint64_t timestamp; + uint64_t irq_mono_boot_time; }; /** * struct cam_isp_hw_eof_event_data - Event payload for CAM_HW_EVENT_EOF * * @timestamp: Timestamp for the eof event + * @irq_mono_boot_time: Time stamp till the execution of this event started * */ struct cam_isp_hw_eof_event_data { uint64_t timestamp; + uint64_t irq_mono_boot_time; }; /** diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile index 25bdc51d369f..719bbe7aa941 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile @@ -8,5 +8,6 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/in ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_smmu/ ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_req_mgr/ +obj-$(CONFIG_SPECTRA_CAMERA) += cam_csid_ppi_dev.o cam_csid_ppi_core.o cam_csid_ppi170.o obj-$(CONFIG_SPECTRA_CAMERA) += cam_ife_csid_dev.o cam_ife_csid_soc.o cam_ife_csid_core.o obj-$(CONFIG_SPECTRA_CAMERA) += cam_ife_csid17x.o cam_ife_csid_lite17x.o diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c new file mode 100644 index 000000000000..2051292be5be --- /dev/null +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c @@ -0,0 +1,58 @@ +/* Copyright (c) 2019, 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 +#include "cam_csid_ppi_core.h" +#include "cam_csid_ppi170.h" +#include "cam_csid_ppi_dev.h" + +#define CAM_PPI_DRV_NAME "ppi_170" +#define CAM_PPI_VERSION_V170 0x10070000 + +static struct cam_csid_ppi_hw_info cam_csid_ppi170_hw_info = { + .ppi_reg = &cam_csid_ppi_170_reg_offset, +}; + +static const struct of_device_id cam_csid_ppi170_dt_match[] = { + { + .compatible = "qcom,ppi170", + .data = &cam_csid_ppi170_hw_info, + }, + {} +}; + +MODULE_DEVICE_TABLE(of, cam_csid_ppi170_dt_match); + +static struct platform_driver cam_csid_ppi170_driver = { + .probe = cam_csid_ppi_probe, + .remove = cam_csid_ppi_remove, + .driver = { + .name = CAM_PPI_DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = cam_csid_ppi170_dt_match, + .suppress_bind_attrs = true, + }, +}; + +static int __init cam_csid_ppi170_init_module(void) +{ + return platform_driver_register(&cam_csid_ppi170_driver); +} + +static void __exit cam_csid_ppi170_exit_module(void) +{ + platform_driver_unregister(&cam_csid_ppi170_driver); +} + +module_init(cam_csid_ppi170_init_module); +MODULE_DESCRIPTION("CAM CSID_PPI170 driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h new file mode 100644 index 000000000000..0ec767204914 --- /dev/null +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2019, 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 _CAM_CSID_PPI_170_H_ +#define _CAM_CSID_PPI_170_H_ + +#include "cam_csid_ppi_core.h" + +static struct cam_csid_ppi_reg_offset cam_csid_ppi_170_reg_offset = { + .ppi_hw_version_addr = 0, + .ppi_module_cfg_addr = 0x60, + .ppi_irq_status_addr = 0x68, + .ppi_irq_mask_addr = 0x6c, + .ppi_irq_set_addr = 0x70, + .ppi_irq_clear_addr = 0x74, + .ppi_irq_cmd_addr = 0x78, + .ppi_rst_cmd_addr = 0x7c, + .ppi_test_bus_ctrl_addr = 0x1f4, + .ppi_debug_addr = 0x1f8, + .ppi_spare_addr = 0x1fc, +}; + +#endif /*_CAM_CSID_PPI_170_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c new file mode 100644 index 000000000000..058a4e955b38 --- /dev/null +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c @@ -0,0 +1,404 @@ +/* Copyright (c) 2019, 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 +#include +#include + +#include "cam_csid_ppi_core.h" +#include "cam_csid_ppi_dev.h" +#include "cam_soc_util.h" +#include "cam_debug_util.h" +#include "cam_io_util.h" + +static int cam_csid_ppi_reset(struct cam_csid_ppi_hw *ppi_hw) +{ + struct cam_hw_soc_info *soc_info; + const struct cam_csid_ppi_reg_offset *ppi_reg; + int rc = 0; + + uint32_t val = 0; + uint32_t clear_mask; + uint32_t status; + + soc_info = &ppi_hw->hw_info->soc_info; + ppi_reg = ppi_hw->ppi_info->ppi_reg; + + CAM_DBG(CAM_ISP, "PPI:%d reset", ppi_hw->hw_intf->hw_idx); + + /* Mask all interrupts */ + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_mask_addr); + + /* clear all interrupts */ + clear_mask = PPI_IRQ_FIFO0_OVERFLOW | PPI_IRQ_FIFO1_OVERFLOW | + PPI_IRQ_FIFO2_OVERFLOW; + cam_io_w_mb(clear_mask, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_clear_addr); + cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_cmd_addr); + + /* perform the top PPI HW registers reset */ + cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_rst_cmd_addr); + + rc = readl_poll_timeout(soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_status_addr, status, + (status & 0x1) == 0x1, 1000, 100000); + if (rc < 0) { + CAM_ERR(CAM_ISP, "PPI:%d ppi_reset fail rc = %d", + ppi_hw->hw_intf->hw_idx, rc); + rc = -ETIMEDOUT; + } + CAM_DBG(CAM_ISP, "PPI: reset status %d", status); + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_mask_addr); + if (val != 0) + CAM_ERR(CAM_ISP, "PPI:%d IRQ value after reset rc = %d", + ppi_hw->hw_intf->hw_idx, val); + + return rc; +} + +static int cam_csid_ppi_enable_hw(struct cam_csid_ppi_hw *ppi_hw) +{ + int rc = 0; + uint32_t i; + uint64_t val; + + const struct cam_csid_ppi_reg_offset *ppi_reg; + struct cam_hw_soc_info *soc_info; + + ppi_reg = ppi_hw->ppi_info->ppi_reg; + soc_info = &ppi_hw->hw_info->soc_info; + + CAM_DBG(CAM_ISP, "PPI:%d init PPI HW", ppi_hw->hw_intf->hw_idx); + + for (i = 0; i < soc_info->num_clk; i++) { + /* Passing zero in clk_rate results in setting no clk_rate */ + rc = cam_soc_util_clk_enable(soc_info->clk[i], + soc_info->clk_name[i], 0); + if (rc) + goto clk_disable; + } + + rc = cam_soc_util_irq_enable(soc_info); + if (rc) + goto clk_disable; + + /* Reset PPI */ + rc = cam_csid_ppi_reset(ppi_hw); + if (rc) + goto irq_disable; + + /* Clear the RST done IRQ */ + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_clear_addr); + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_cmd_addr); + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + ppi_reg->ppi_hw_version_addr); + CAM_DBG(CAM_ISP, "PPI:%d PPI HW version: 0x%x", + ppi_hw->hw_intf->hw_idx, val); + + ppi_hw->device_enabled = 1; + return 0; +irq_disable: + cam_soc_util_irq_disable(soc_info); +clk_disable: + for (i--; i >= 0; i--) { + cam_soc_util_clk_disable(soc_info->clk[i], + soc_info->clk_name[i]); + } + return rc; +} + +static int cam_csid_ppi_disable_hw(struct cam_csid_ppi_hw *ppi_hw) +{ + int rc = 0; + int i; + struct cam_hw_soc_info *soc_info; + const struct cam_csid_ppi_reg_offset *ppi_reg; + uint64_t ppi_cfg_val = 0; + + CAM_DBG(CAM_ISP, "PPI:%d De-init PPI HW", + ppi_hw->hw_intf->hw_idx); + + soc_info = &ppi_hw->hw_info->soc_info; + ppi_reg = ppi_hw->ppi_info->ppi_reg; + + CAM_DBG(CAM_ISP, "%s:Calling PPI Reset\n", __func__); + cam_csid_ppi_reset(ppi_hw); + CAM_DBG(CAM_ISP, "%s:PPI Reset Done\n", __func__); + + /* disable the clocks */ + for (i = 0; i < soc_info->num_clk; i++) { + cam_soc_util_clk_disable(soc_info->clk[i], + soc_info->clk_name[i]); + } + + /* disable the interrupt */ + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_mask_addr); + cam_soc_util_irq_disable(soc_info); + + /* disable lanes */ + for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++) + ppi_cfg_val &= ~PPI_CFG_CPHY_DLX_EN(i); + + cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_module_cfg_addr); + + ppi_hw->device_enabled = 0; + + return rc; +} + +static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args, + uint32_t arg_size) +{ + int i, rc = 0; + uint32_t num_lanes; + uint32_t lanes[CAM_CSID_PPI_HW_MAX] = {0, 0, 0, 0}; + uint32_t cphy; + bool dl0, dl1; + uint32_t ppi_cfg_val = 0; + struct cam_csid_ppi_hw *ppi_hw; + struct cam_hw_info *ppi_hw_info; + const struct cam_csid_ppi_reg_offset *ppi_reg; + struct cam_hw_soc_info *soc_info; + struct cam_csid_ppi_cfg ppi_cfg; + + if (!hw_priv || !init_args || + (arg_size != sizeof(struct cam_csid_ppi_cfg))) { + CAM_ERR(CAM_ISP, "PPI: Invalid args"); + rc = -EINVAL; + goto end; + } + + dl0 = dl1 = false; + ppi_hw_info = (struct cam_hw_info *)hw_priv; + ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info; + ppi_reg = ppi_hw->ppi_info->ppi_reg; + ppi_cfg = *((struct cam_csid_ppi_cfg *)init_args); + + /* Initialize the ppi hardware */ + rc = cam_csid_ppi_enable_hw(ppi_hw); + if (rc) + goto end; + + /* Do lane configuration here*/ + num_lanes = ppi_cfg.lane_num; + /* lane_type = 1 refers to cphy */ + cphy = ppi_cfg.lane_type; + CAM_DBG(CAM_ISP, "lane_cfg 0x%x | num_lanes 0x%x | lane_type 0x%x", + ppi_cfg.lane_cfg, num_lanes, cphy); + + for (i = 0; i < num_lanes; i++) { + lanes[i] = ppi_cfg.lane_cfg & (0x3 << (4 * i)); + (lanes[i] < 2) ? (dl0 = true) : (dl1 = true); + CAM_DBG(CAM_ISP, "lanes[%d] %d", i, lanes[i]); + } + + if (num_lanes) { + if (cphy) { + for (i = 0; i < num_lanes; i++) { + /* Select Cphy */ + ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(lanes[i]); + /* Enable lane Cphy */ + ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(lanes[i]); + } + } else { + if (dl0) + /* Enable lane 0 */ + ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(0); + if (dl1) + /* Enable lane 1 */ + ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(1); + } + } else { + CAM_ERR(CAM_ISP, + "Number of lanes to enable is cannot be zero"); + rc = -1; + goto end; + } + + CAM_DBG(CAM_ISP, "ppi_cfg_val 0x%x", ppi_cfg_val); + soc_info = &ppi_hw->hw_info->soc_info; + cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_module_cfg_addr); +end: + return rc; +} + +static int cam_csid_ppi_deinit_hw(void *hw_priv, void *deinit_args, + uint32_t arg_size) +{ + int rc = 0; + struct cam_csid_ppi_hw *ppi_hw; + struct cam_hw_info *ppi_hw_info; + + CAM_DBG(CAM_ISP, "Enter"); + + if (!hw_priv) { + CAM_ERR(CAM_ISP, "PPI:Invalid arguments"); + rc = -EINVAL; + goto end; + } + + ppi_hw_info = (struct cam_hw_info *)hw_priv; + ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info; + + CAM_DBG(CAM_ISP, "Disabling PPI Hw\n"); + rc = cam_csid_ppi_disable_hw(ppi_hw); + if (rc < 0) + CAM_DBG(CAM_ISP, "%s: Exit with %d\n", __func__, rc); +end: + return rc; +} + +int cam_csid_ppi_hw_probe_init(struct cam_hw_intf *ppi_hw_intf, + uint32_t ppi_idx) +{ + int rc = -EINVAL; + struct cam_hw_info *ppi_hw_info; + struct cam_csid_ppi_hw *csid_ppi_hw = NULL; + + if (ppi_idx >= CAM_CSID_PPI_HW_MAX) { + CAM_ERR(CAM_ISP, "Invalid ppi index:%d", ppi_idx); + goto err; + } + + ppi_hw_info = (struct cam_hw_info *) ppi_hw_intf->hw_priv; + csid_ppi_hw = (struct cam_csid_ppi_hw *) ppi_hw_info->core_info; + + csid_ppi_hw->hw_intf = ppi_hw_intf; + csid_ppi_hw->hw_info = ppi_hw_info; + + CAM_DBG(CAM_ISP, "type %d index %d", + csid_ppi_hw->hw_intf->hw_type, ppi_idx); + + rc = cam_csid_ppi_init_soc_resources(&csid_ppi_hw->hw_info->soc_info, + cam_csid_ppi_irq, csid_ppi_hw); + if (rc < 0) { + CAM_ERR(CAM_ISP, "PPI:%d Failed to init_soc", ppi_idx); + goto err; + } + + csid_ppi_hw->hw_intf->hw_ops.init = cam_csid_ppi_init_hw; + csid_ppi_hw->hw_intf->hw_ops.deinit = cam_csid_ppi_deinit_hw; + return 0; +err: + return rc; +} + +int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info, + irq_handler_t ppi_irq_handler, void *irq_data) +{ + int rc = 0; + + rc = cam_soc_util_get_dt_properties(soc_info); + if (rc) { + CAM_ERR(CAM_ISP, "PPI: Failed to get dt properties"); + goto end; + } + + rc = cam_soc_util_request_platform_resource(soc_info, ppi_irq_handler, + irq_data); + if (rc) { + CAM_ERR(CAM_ISP, + "PPI: Error Request platform resources failed rc=%d", + rc); + goto err; + } +end: + return rc; +err: + cam_soc_util_release_platform_resource(soc_info); + return rc; +} + +irqreturn_t cam_csid_ppi_irq(int irq_num, void *data) +{ + uint32_t irq_status = 0; + uint32_t i, ppi_cfg_val = 0; + bool fatal_err_detected = false; + + struct cam_csid_ppi_hw *ppi_hw; + struct cam_hw_soc_info *soc_info; + const struct cam_csid_ppi_reg_offset *ppi_reg; + + if (!data) { + CAM_ERR(CAM_ISP, "PPI: Invalid arguments"); + return IRQ_HANDLED; + } + + ppi_hw = (struct cam_csid_ppi_hw *)data; + CAM_DBG(CAM_ISP, "PPI %d IRQ Handling", ppi_hw->hw_intf->hw_idx); + ppi_reg = ppi_hw->ppi_info->ppi_reg; + soc_info = &ppi_hw->hw_info->soc_info; + + /* read */ + irq_status = cam_io_r_mb(soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_status_addr); + + /* clear */ + cam_io_w_mb(irq_status, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_clear_addr); + + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_irq_cmd_addr); + + CAM_DBG(CAM_ISP, "PPI %d irq status 0x%x", ppi_hw->hw_intf->hw_idx, + irq_status); + + if (ppi_hw->device_enabled == 1) { + if (irq_status & PPI_IRQ_RST_DONE) { + CAM_DBG(CAM_ISP, "PPI Reset Done"); + goto ret; + } + if ((irq_status & PPI_IRQ_FIFO0_OVERFLOW) || + (irq_status & PPI_IRQ_FIFO1_OVERFLOW) || + (irq_status & PPI_IRQ_FIFO2_OVERFLOW)) { + fatal_err_detected = true; + goto handle_fatal_error; + } + } + +handle_fatal_error: + if (fatal_err_detected) { + CAM_ERR(CAM_ISP, "PPI: %d irq_status:0x%x", + ppi_hw->hw_intf->hw_idx, irq_status); + /* disable lanes */ + for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++) + ppi_cfg_val &= ~PPI_CFG_CPHY_DLX_EN(i); + + cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base + + ppi_reg->ppi_module_cfg_addr); + } +ret: + CAM_DBG(CAM_ISP, "IRQ Handling exit"); + return IRQ_HANDLED; +} + +int cam_csid_ppi_hw_deinit(struct cam_csid_ppi_hw *csid_ppi_hw) +{ + if (!csid_ppi_hw) { + CAM_ERR(CAM_ISP, "Invalid param"); + return -EINVAL; + } + /* release the privdate data memory from resources */ + return cam_soc_util_release_platform_resource( + &csid_ppi_hw->hw_info->soc_info); +} + diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h new file mode 100644 index 000000000000..058c2421b6da --- /dev/null +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h @@ -0,0 +1,103 @@ +/* Copyright (c) 2019, 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 _CAM_CSID_PPI_HW_H_ +#define _CAM_CSID_PPI_HW_H_ + +#include "cam_hw.h" +#include "cam_hw_intf.h" + +#define CAM_CSID_PPI_HW_MAX 4 +#define CAM_CSID_PPI_LANES_MAX 3 + +#define PPI_IRQ_RST_DONE BIT(0) +#define PPI_IRQ_FIFO0_OVERFLOW BIT(1) +#define PPI_IRQ_FIFO1_OVERFLOW BIT(2) +#define PPI_IRQ_FIFO2_OVERFLOW BIT(3) + +#define PPI_IRQ_CMD_SET BIT(0) + +#define PPI_IRQ_CMD_CLEAR BIT(0) + +#define PPI_RST_CONTROL BIT(0) +/* + * Select the PHY (CPHY set '1' or DPHY set '0') + */ +#define PPI_CFG_CPHY_DLX_SEL(X) ((X < 2) ? BIT(X) : 0) + +#define PPI_CFG_CPHY_DLX_EN(X) BIT(4+X) + +struct cam_csid_ppi_reg_offset { + uint32_t ppi_hw_version_addr; + uint32_t ppi_module_cfg_addr; + + uint32_t ppi_irq_status_addr; + uint32_t ppi_irq_mask_addr; + uint32_t ppi_irq_set_addr; + uint32_t ppi_irq_clear_addr; + uint32_t ppi_irq_cmd_addr; + uint32_t ppi_rst_cmd_addr; + uint32_t ppi_test_bus_ctrl_addr; + uint32_t ppi_debug_addr; + uint32_t ppi_spare_addr; +}; + +/** + * struct cam_csid_ppi_hw_info- ppi HW info + * + * @ppi_reg: ppi register offsets + * + */ +struct cam_csid_ppi_hw_info { + const struct cam_csid_ppi_reg_offset *ppi_reg; +}; + +/** + * struct cam_csid_ppi_hw- ppi hw device resources data + * + * @hw_intf: contain the ppi hw interface information + * @hw_info: ppi hw device information + * @ppi_info: ppi hw specific information + * @device_enabled Device enabled will set once ppi powered on and + * initial configuration are done. + * @lock_state ppi spin lock + * + */ +struct cam_csid_ppi_hw { + struct cam_hw_intf *hw_intf; + struct cam_hw_info *hw_info; + struct cam_csid_ppi_hw_info *ppi_info; + uint32_t device_enabled; +}; + +/** + * struct cam_csid_ppi_cfg - ppi lane configuration data + * @lane_type: lane type: c-phy or d-phy + * @lane_num : active lane number + * @lane_cfg: lane configurations: 4 bits per lane + * + */ +struct cam_csid_ppi_cfg { + uint32_t lane_type; + uint32_t lane_num; + uint32_t lane_cfg; +}; + +int cam_csid_ppi_hw_probe_init(struct cam_hw_intf *ppi_hw_intf, + uint32_t ppi_idx); +int cam_csid_ppi_hw_deinit(struct cam_csid_ppi_hw *csid_ppi_hw); +int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info, + irq_handler_t ppi_irq_handler, void *irq_data); +int cam_csid_ppi_deinit_soc_resources(struct cam_hw_soc_info *soc_info); +int cam_csid_ppi_hw_init(struct cam_hw_intf **csid_ppi_hw, + uint32_t hw_idx); +#endif /* _CAM_CSID_PPI_HW_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c new file mode 100644 index 000000000000..1a4e14525bc3 --- /dev/null +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c @@ -0,0 +1,147 @@ +/* Copyright (c) 2019, 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 +#include +#include + +#include "cam_isp_hw.h" +#include "cam_hw_intf.h" +#include "cam_csid_ppi_core.h" +#include "cam_csid_ppi_dev.h" +#include "cam_debug_util.h" + +static struct cam_hw_intf *cam_csid_ppi_hw_list[CAM_CSID_PPI_HW_MAX] = { + 0, 0, 0, 0}; +static char ppi_dev_name[8]; + +int cam_csid_ppi_probe(struct platform_device *pdev) +{ + struct cam_hw_intf *ppi_hw_intf; + struct cam_hw_info *ppi_hw_info; + struct cam_csid_ppi_hw *ppi_dev = NULL; + const struct of_device_id *match_dev = NULL; + struct cam_csid_ppi_hw_info *ppi_hw_data = NULL; + uint32_t ppi_dev_idx; + int rc = 0; + + CAM_DBG(CAM_ISP, "PPI probe called"); + + ppi_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL); + if (!ppi_hw_intf) { + rc = -ENOMEM; + goto err; + } + + ppi_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL); + if (!ppi_hw_info) { + rc = -ENOMEM; + goto free_hw_intf; + } + + ppi_dev = kzalloc(sizeof(struct cam_csid_ppi_hw), GFP_KERNEL); + if (!ppi_dev) { + rc = -ENOMEM; + goto free_hw_info; + } + + /* get csid ppi hw index */ + of_property_read_u32(pdev->dev.of_node, "cell-index", &ppi_dev_idx); + + /* get csid ppi hw information */ + match_dev = of_match_device(pdev->dev.driver->of_match_table, + &pdev->dev); + if (!match_dev) { + CAM_ERR(CAM_ISP, "No matching table for the CSID PPI HW!"); + rc = -EINVAL; + goto free_dev; + } + + memset(ppi_dev_name, 0, sizeof(ppi_dev_name)); + snprintf(ppi_dev_name, sizeof(ppi_dev_name), "ppi%1u", ppi_dev_idx); + + ppi_hw_intf->hw_idx = ppi_dev_idx; + ppi_hw_intf->hw_priv = ppi_hw_info; + + ppi_hw_info->core_info = ppi_dev; + ppi_hw_info->soc_info.pdev = pdev; + ppi_hw_info->soc_info.dev = &pdev->dev; + ppi_hw_info->soc_info.dev_name = ppi_dev_name; + ppi_hw_info->soc_info.index = ppi_dev_idx; + + ppi_hw_data = (struct cam_csid_ppi_hw_info *)match_dev->data; + /* need to setup the pdev before call the csid ppi hw probe init */ + ppi_dev->ppi_info = ppi_hw_data; + + rc = cam_csid_ppi_hw_probe_init(ppi_hw_intf, ppi_dev_idx); + if (rc) { + CAM_ERR(CAM_ISP, "PPI: Probe init failed!"); + goto free_dev; + } + + platform_set_drvdata(pdev, ppi_dev); + CAM_DBG(CAM_ISP, "PPI:%d probe successful", + ppi_hw_intf->hw_idx); + + if (ppi_hw_intf->hw_idx < CAM_CSID_PPI_HW_MAX) + cam_csid_ppi_hw_list[ppi_hw_intf->hw_idx] = ppi_hw_intf; + else + goto free_dev; + + return 0; +free_dev: + kfree(ppi_dev); +free_hw_info: + kfree(ppi_hw_info); +free_hw_intf: + kfree(ppi_hw_intf); +err: + return rc; +} + +int cam_csid_ppi_remove(struct platform_device *pdev) +{ + struct cam_csid_ppi_hw *ppi_dev = NULL; + struct cam_hw_intf *ppi_hw_intf; + struct cam_hw_info *ppi_hw_info; + + ppi_dev = (struct cam_csid_ppi_hw *)platform_get_drvdata(pdev); + ppi_hw_intf = ppi_dev->hw_intf; + ppi_hw_info = ppi_dev->hw_info; + + CAM_DBG(CAM_ISP, "PPI:%d remove", ppi_dev->hw_intf->hw_idx); + + cam_csid_ppi_hw_deinit(ppi_dev); + + /* release the ppi device memory */ + kfree(ppi_dev); + kfree(ppi_hw_info); + kfree(ppi_hw_intf); + return 0; +} + +int cam_csid_ppi_hw_init(struct cam_hw_intf **csid_ppi_hw, + uint32_t hw_idx) +{ + int rc = 0; + + if (cam_csid_ppi_hw_list[hw_idx]) { + *csid_ppi_hw = cam_csid_ppi_hw_list[hw_idx]; + } else { + *csid_ppi_hw = NULL; + rc = -1; + } + + return rc; +} +EXPORT_SYMBOL(cam_csid_ppi_hw_init); + diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h new file mode 100644 index 000000000000..b2ebeaf92947 --- /dev/null +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2019, 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 _CAM_CSID_PPI_DEV_H_ +#define _CAM_CSID_PPI_DEV_H_ + +#include "cam_isp_hw.h" + +irqreturn_t cam_csid_ppi_irq(int irq_num, void *data); +int cam_csid_ppi_probe(struct platform_device *pdev); +int cam_csid_ppi_remove(struct platform_device *pdev); + +#endif /*_CAM_CSID_PPI_DEV_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h index 576e8cb8d3b8..6254b97c436a 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h @@ -293,6 +293,10 @@ static struct cam_ife_csid_common_reg_offset .ppp_irq_mask_all = 0x0, .measure_en_hbi_vbi_cnt_mask = 0xC, .format_measure_en_val = 1, + .format_measure_height_mask_val = 0xFFFF, + .format_measure_height_shift_val = 0x10, + .format_measure_width_mask_val = 0xFFFF, + .format_measure_width_shift_val = 0x0, }; static struct cam_ife_csid_reg_offset cam_ife_csid_170_reg_offset = { diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h index 42f0f290a166..ed2857bd78ed 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h @@ -334,6 +334,10 @@ static struct cam_ife_csid_common_reg_offset .ppp_irq_mask_all = 0xFFFF, .measure_en_hbi_vbi_cnt_mask = 0xC, .format_measure_en_val = 1, + .format_measure_height_mask_val = 0xFFFF, + .format_measure_height_shift_val = 0x10, + .format_measure_width_mask_val = 0xFFFF, + .format_measure_width_shift_val = 0x0, }; static struct cam_ife_csid_reg_offset cam_ife_csid_175_reg_offset = { diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h index 8a78fe0b9b0d..d430ceef3360 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h @@ -350,6 +350,10 @@ static struct cam_ife_csid_common_reg_offset .ppp_irq_mask_all = 0xFFFF, .measure_en_hbi_vbi_cnt_mask = 0xC, .format_measure_en_val = 1, + .format_measure_height_mask_val = 0xFFFF, + .format_measure_height_shift_val = 0x10, + .format_measure_width_mask_val = 0xFFFF, + .format_measure_width_shift_val = 0x0, }; static struct cam_ife_csid_reg_offset cam_ife_csid_175_200_reg_offset = { diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index 3431a640ed79..7541d06e7ede 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -16,6 +16,7 @@ #include #include "cam_ife_csid_core.h" +#include "cam_csid_ppi_core.h" #include "cam_isp_hw.h" #include "cam_soc_util.h" #include "cam_io_util.h" @@ -78,7 +79,7 @@ static int cam_ife_csid_is_ipp_ppp_format_supported( static int cam_ife_csid_get_format_rdi( uint32_t in_format, uint32_t out_format, - uint32_t *decode_fmt, uint32_t *plain_fmt) + uint32_t *decode_fmt, uint32_t *plain_fmt, uint32_t *in_bpp) { int rc = 0; @@ -96,6 +97,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 6; break; case CAM_FORMAT_MIPI_RAW_8: switch (out_format) { @@ -111,6 +113,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 8; break; case CAM_FORMAT_MIPI_RAW_10: switch (out_format) { @@ -126,6 +129,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 10; break; case CAM_FORMAT_MIPI_RAW_12: switch (out_format) { @@ -140,6 +144,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 12; break; case CAM_FORMAT_MIPI_RAW_14: switch (out_format) { @@ -154,6 +159,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 14; break; case CAM_FORMAT_MIPI_RAW_16: switch (out_format) { @@ -168,6 +174,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 16; break; case CAM_FORMAT_MIPI_RAW_20: switch (out_format) { @@ -182,6 +189,7 @@ static int cam_ife_csid_get_format_rdi( rc = -EINVAL; break; } + *in_bpp = 20; break; case CAM_FORMAT_DPCM_10_6_10: *decode_fmt = 0x7; @@ -566,10 +574,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw, init_completion(complete); reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all; - /* Enable the Test gen before reset */ - cam_io_w_mb(1, csid_hw->hw_info->soc_info.reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_ctrl_addr); - /* Reset the corresponding ife csid path */ cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base + reset_strb_addr); @@ -584,10 +588,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw, rc = -ETIMEDOUT; } - /* Disable Test Gen after reset*/ - cam_io_w_mb(0, soc_info->reg_map[0].mem_base + - csid_reg->tpg_reg->csid_tpg_ctrl_addr); - end: return rc; @@ -1166,6 +1166,11 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw) for (i = 0; i < CAM_IFE_PIX_PATH_RES_MAX; i++) csid_hw->res_sof_cnt[i] = 0; + csid_hw->ipp_path_config.measure_enabled = 0; + csid_hw->ppp_path_config.measure_enabled = 0; + for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) + csid_hw->rdi_path_config[i].measure_enabled = 0; + csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; csid_hw->error_irq_count = 0; csid_hw->first_sof_ts = 0; @@ -1422,10 +1427,12 @@ static int cam_ife_csid_enable_csi2( struct cam_isp_resource_node *res) { int rc = 0; - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; - struct cam_ife_csid_cid_data *cid_data; + const struct cam_ife_csid_reg_offset *csid_reg; + struct cam_hw_soc_info *soc_info; + struct cam_ife_csid_cid_data *cid_data; + struct cam_csid_ppi_cfg ppi_lane_cfg; uint32_t val = 0; + uint32_t ppi_index = 0; csid_reg = csid_hw->csid_info->csid_reg; soc_info = &csid_hw->hw_info->soc_info; @@ -1516,6 +1523,24 @@ static int cam_ife_csid_enable_csi2( cam_io_w_mb(val, soc_info->reg_map[0].mem_base + csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); + ppi_index = csid_hw->csi2_rx_cfg.phy_sel; + if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) { + ppi_lane_cfg.lane_type = csid_hw->csi2_rx_cfg.lane_type; + ppi_lane_cfg.lane_num = csid_hw->csi2_rx_cfg.lane_num; + ppi_lane_cfg.lane_cfg = csid_hw->csi2_rx_cfg.lane_cfg; + + CAM_DBG(CAM_ISP, "ppi_index to init %d", ppi_index); + rc = csid_hw->ppi_hw_intf[ppi_index]->hw_ops.init( + csid_hw->ppi_hw_intf[ppi_index]->hw_priv, + &ppi_lane_cfg, + sizeof(struct cam_csid_ppi_cfg)); + if (rc < 0) { + CAM_ERR(CAM_ISP, "PPI:%d Init Failed", + ppi_index); + return rc; + } + } + return 0; } @@ -1523,8 +1548,10 @@ static int cam_ife_csid_disable_csi2( struct cam_ife_csid_hw *csid_hw, struct cam_isp_resource_node *res) { - const struct cam_ife_csid_reg_offset *csid_reg; - struct cam_hw_soc_info *soc_info; + int rc = 0; + const struct cam_ife_csid_reg_offset *csid_reg; + struct cam_hw_soc_info *soc_info; + uint32_t ppi_index = 0; if (res->res_id >= CAM_IFE_CSID_CID_MAX) { CAM_ERR(CAM_ISP, "CSID:%d Invalid res id :%d", @@ -1555,6 +1582,19 @@ static int cam_ife_csid_disable_csi2( res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; + ppi_index = csid_hw->csi2_rx_cfg.phy_sel; + if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) { + /* De-Initialize the PPI bridge */ + CAM_DBG(CAM_ISP, "ppi_index to de-init %d\n", ppi_index); + rc = csid_hw->ppi_hw_intf[ppi_index]->hw_ops.deinit( + csid_hw->ppi_hw_intf[ppi_index]->hw_priv, + NULL, 0); + if (rc < 0) { + CAM_ERR(CAM_ISP, "PPI:%d De-Init Failed", ppi_index); + return rc; + } + } + return 0; } @@ -1589,6 +1629,7 @@ static int cam_ife_csid_init_config_pxl_path( const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL; bool is_ipp; uint32_t decode_format = 0, plain_format = 0, val = 0; + struct cam_isp_sensor_dimension *path_config; path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; @@ -1597,9 +1638,11 @@ static int cam_ife_csid_init_config_pxl_path( if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { is_ipp = true; pxl_reg = csid_reg->ipp_reg; + path_config = &(csid_hw->ipp_path_config); } else { is_ipp = false; pxl_reg = csid_reg->ppp_reg; + path_config = &(csid_hw->ppp_path_config); } if (!pxl_reg) { @@ -1668,6 +1711,24 @@ static int cam_ife_csid_init_config_pxl_path( } } + /* configure pixel format measure */ + if (path_config->measure_enabled) { + val = (((path_config->height & + csid_reg->cmn_reg->format_measure_height_mask_val) << + csid_reg->cmn_reg->format_measure_height_shift_val) | + (path_config->width & + csid_reg->cmn_reg->format_measure_width_mask_val)); + CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x", + csid_hw->hw_intf->hw_idx, val); + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_format_measure_cfg1_addr); + + /* enable pixel and line counter */ + cam_io_w_mb(3, soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_format_measure_cfg0_addr); + } + /* set frame drop pattern to 0 and period to 1 */ cam_io_w_mb(1, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_frm_drop_period_addr); @@ -1813,6 +1874,7 @@ static int cam_ife_csid_enable_pxl_path( const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL; bool is_ipp; uint32_t val = 0, path_status; + struct cam_isp_sensor_dimension *path_config; path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; csid_reg = csid_hw->csid_info->csid_reg; @@ -1821,9 +1883,11 @@ static int cam_ife_csid_enable_pxl_path( if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { is_ipp = true; pxl_reg = csid_reg->ipp_reg; + path_config = &(csid_hw->ipp_path_config); } else { is_ipp = false; pxl_reg = csid_reg->ppp_reg; + path_config = &(csid_hw->ppp_path_config); } if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) { @@ -1884,6 +1948,10 @@ static int cam_ife_csid_enable_pxl_path( if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) val |= CSID_PATH_INFO_INPUT_EOF; + if (path_config->measure_enabled) + val |= (CSID_PATH_ERROR_PIX_COUNT | + CSID_PATH_ERROR_LINE_COUNT); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + pxl_reg->csid_pxl_irq_mask_addr); @@ -1984,7 +2052,7 @@ static int cam_ife_csid_init_config_rdi_path( struct cam_ife_csid_path_cfg *path_data; const struct cam_ife_csid_reg_offset *csid_reg; struct cam_hw_soc_info *soc_info; - uint32_t path_format = 0, plain_fmt = 0, val = 0, id; + uint32_t path_format = 0, plain_fmt = 0, val = 0, id, in_bpp = 0; uint32_t format_measure_addr; path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; @@ -1999,7 +2067,7 @@ static int cam_ife_csid_init_config_rdi_path( } rc = cam_ife_csid_get_format_rdi(path_data->in_format, - path_data->out_format, &path_format, &plain_fmt); + path_data->out_format, &path_format, &plain_fmt, &in_bpp); if (rc) return rc; @@ -2048,6 +2116,32 @@ static int cam_ife_csid_init_config_rdi_path( CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x", csid_hw->hw_intf->hw_idx, val); } + + /* configure pixel format measure */ + if (csid_hw->rdi_path_config[id].measure_enabled) { + val = ((csid_hw->rdi_path_config[id].height & + csid_reg->cmn_reg->format_measure_height_mask_val) << + csid_reg->cmn_reg->format_measure_height_shift_val); + + if (path_format == 0xF) + val |= (((csid_hw->rdi_path_config[id].width * + in_bpp) / 8) & + csid_reg->cmn_reg->format_measure_width_mask_val); + else + val |= (csid_hw->rdi_path_config[id].width & + csid_reg->cmn_reg->format_measure_width_mask_val); + + CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x", + csid_hw->hw_intf->hw_idx, val); + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg1_addr); + + /* enable pixel and line counter */ + cam_io_w_mb(3, soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr); + } + /* set frame drop pattern to 0 and period to 1 */ cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr); @@ -2220,6 +2314,10 @@ static int cam_ife_csid_enable_rdi_path( if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ) val |= CSID_PATH_INFO_INPUT_EOF; + if (csid_hw->rdi_path_config[id].measure_enabled) + val |= (CSID_PATH_ERROR_PIX_COUNT | + CSID_PATH_ERROR_LINE_COUNT); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr); @@ -2673,6 +2771,13 @@ static int cam_ife_csid_release(void *hw_priv, case CAM_ISP_RESOURCE_PIX_PATH: res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; cam_ife_csid_reset_init_frame_drop(csid_hw); + if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) + csid_hw->ipp_path_config.measure_enabled = 0; + else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP) + csid_hw->ppp_path_config.measure_enabled = 0; + else + csid_hw->rdi_path_config[res->res_id].measure_enabled + = 0; break; default: CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d", @@ -3103,6 +3208,57 @@ static int cam_ife_csid_set_csid_clock( return 0; } +static int cam_ife_csid_set_sensor_dimension( + struct cam_ife_csid_hw *csid_hw, void *cmd_args) +{ + struct cam_ife_sensor_dimension_update_args *dimension_update = NULL; + uint32_t i; + + if (!csid_hw) + return -EINVAL; + + dimension_update = + (struct cam_ife_sensor_dimension_update_args *)cmd_args; + csid_hw->ipp_path_config.measure_enabled = + dimension_update->ipp_path.measure_enabled; + if (dimension_update->ipp_path.measure_enabled) { + csid_hw->ipp_path_config.width = + dimension_update->ipp_path.width; + csid_hw->ipp_path_config.height = + dimension_update->ipp_path.height; + CAM_DBG(CAM_ISP, "CSID ipp path width %d height %d", + csid_hw->ipp_path_config.width, + csid_hw->ipp_path_config.height); + } + csid_hw->ppp_path_config.measure_enabled = + dimension_update->ppp_path.measure_enabled; + if (dimension_update->ppp_path.measure_enabled) { + csid_hw->ppp_path_config.width = + dimension_update->ppp_path.width; + csid_hw->ppp_path_config.height = + dimension_update->ppp_path.height; + CAM_DBG(CAM_ISP, "CSID ppp path width %d height %d", + csid_hw->ppp_path_config.width, + csid_hw->ppp_path_config.height); + } + for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) { + csid_hw->rdi_path_config[i].measure_enabled + = dimension_update->rdi_path[i].measure_enabled; + if (csid_hw->rdi_path_config[i].measure_enabled) { + csid_hw->rdi_path_config[i].width = + dimension_update->rdi_path[i].width; + csid_hw->rdi_path_config[i].height = + dimension_update->rdi_path[i].height; + CAM_DBG(CAM_ISP, + "CSID rdi path[%d] width %d height %d", + i, csid_hw->rdi_path_config[i].width, + csid_hw->rdi_path_config[i].height); + } + } + + return 0; +} + static int cam_ife_csid_process_cmd(void *hw_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { @@ -3140,6 +3296,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv, case CAM_IFE_CSID_SET_INIT_FRAME_DROP: rc = cam_ife_csid_set_init_frame_drop(csid_hw, cmd_args); break; + case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG: + rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args); + break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); @@ -3162,20 +3321,19 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) const struct cam_ife_csid_rdi_reg_offset *rdi_reg; uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0; uint32_t irq_status_rdi[4] = {0, 0, 0, 0}; - uint32_t val, irq_status_ppp = 0; + uint32_t val, val2, irq_status_ppp = 0; bool fatal_err_detected = false; uint32_t sof_irq_debug_en = 0; unsigned long flags; - csid_hw = (struct cam_ife_csid_hw *)data; - - CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx); - if (!data) { CAM_ERR(CAM_ISP, "CSID: Invalid arguments"); return IRQ_HANDLED; } + csid_hw = (struct cam_ife_csid_hw *)data; + CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx); + csid_reg = csid_hw->csid_info->csid_reg; soc_info = &csid_hw->hw_info->soc_info; csi2_reg = csid_reg->csi2_reg; @@ -3218,7 +3376,7 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) cam_io_w_mb(1, soc_info->reg_map[0].mem_base + csid_reg->cmn_reg->csid_irq_cmd_addr); - CAM_DBG(CAM_ISP, + CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID %d irq status 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", csid_hw->hw_intf->hw_idx, irq_status_top, irq_status_rx, irq_status_ipp, irq_status_ppp, @@ -3455,6 +3613,25 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) csid_reg->ipp_reg->csid_pxl_ctrl_addr); } } + + if ((irq_status_ipp & CSID_PATH_ERROR_PIX_COUNT) || + (irq_status_ipp & CSID_PATH_ERROR_LINE_COUNT)) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ipp_reg->csid_pxl_format_measure0_addr); + + CAM_ERR(CAM_ISP, + "CSID:%d irq_status_ipp:0x%x", + csid_hw->hw_intf->hw_idx, irq_status_ipp); + CAM_ERR(CAM_ISP, + "Expected sz 0x%x*0x%x actual sz 0x%x*0x%x", + csid_hw->ipp_path_config.height, + csid_hw->ipp_path_config.width, + ((val >> + csid_reg->cmn_reg->format_measure_height_shift_val) & + csid_reg->cmn_reg->format_measure_height_mask_val), + val & + csid_reg->cmn_reg->format_measure_width_mask_val); + } } /*read PPP errors */ @@ -3536,6 +3713,25 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) csid_reg->ppp_reg->csid_pxl_ctrl_addr); } } + + if ((irq_status_ppp & CSID_PATH_ERROR_PIX_COUNT) || + (irq_status_ppp & CSID_PATH_ERROR_LINE_COUNT)) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->ppp_reg->csid_pxl_format_measure0_addr); + + CAM_ERR(CAM_ISP, + "CSID:%d irq_status_ppp:0x%x", + csid_hw->hw_intf->hw_idx, irq_status_ppp); + CAM_ERR(CAM_ISP, + "Expected sz 0x%x*0x%x actual sz 0x%x*0x%x", + csid_hw->ppp_path_config.height, + csid_hw->ppp_path_config.width, + ((val >> + csid_reg->cmn_reg->format_measure_height_shift_val) & + csid_reg->cmn_reg->format_measure_height_mask_val), + val & + csid_reg->cmn_reg->format_measure_width_mask_val); + } } for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { @@ -3602,6 +3798,31 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data) soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr); } + + if ((irq_status_rdi[i] & CSID_PATH_ERROR_PIX_COUNT) || + (irq_status_rdi[i] & CSID_PATH_ERROR_LINE_COUNT)) { + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->csid_rdi_format_measure0_addr); + val2 = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[i]->csid_rdi_format_measure_cfg1_addr + ); + CAM_ERR(CAM_ISP, + "CSID:%d irq_status_rdi[%d]:0x%x", + csid_hw->hw_intf->hw_idx, i, + irq_status_rdi[i]); + CAM_ERR(CAM_ISP, + "Expected sz 0x%x*0x%x actual sz 0x%x*0x%x", + ((val2 >> + csid_reg->cmn_reg->format_measure_height_shift_val) & + csid_reg->cmn_reg->format_measure_height_mask_val), + val2 & + csid_reg->cmn_reg->format_measure_width_mask_val, + ((val >> + csid_reg->cmn_reg->format_measure_height_shift_val) & + csid_reg->cmn_reg->format_measure_height_mask_val), + val & + csid_reg->cmn_reg->format_measure_width_mask_val); + } } if (csid_hw->irq_debug_cnt >= CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX) { @@ -3638,7 +3859,6 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, CAM_DBG(CAM_ISP, "type %d index %d", ife_csid_hw->hw_intf->hw_type, csid_idx); - ife_csid_hw->device_enabled = 0; ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN; mutex_init(&ife_csid_hw->hw_info->hw_mutex); @@ -3653,7 +3873,6 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++) init_completion(&ife_csid_hw->csid_rdin_complete[i]); - rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info, cam_ife_csid_irq, ife_csid_hw); if (rc < 0) { @@ -3747,8 +3966,27 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, ife_csid_hw->csid_debug = 0; ife_csid_hw->error_irq_count = 0; ife_csid_hw->first_sof_ts = 0; + ife_csid_hw->ipp_path_config.measure_enabled = 0; + ife_csid_hw->ppp_path_config.measure_enabled = 0; + for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) + ife_csid_hw->rdi_path_config[i].measure_enabled = 0; - return 0; + /* Check if ppi bridge is present or not? */ + ife_csid_hw->ppi_enable = of_property_read_bool( + csid_hw_info->soc_info.pdev->dev.of_node, + "ppi-enable"); + + if (!ife_csid_hw->ppi_enable) + return 0; + + /* Initialize the PPI bridge */ + for (i = 0; i < CAM_CSID_PPI_HW_MAX; i++) { + rc = cam_csid_ppi_hw_init(&ife_csid_hw->ppi_hw_intf[i], i); + if (rc < 0) { + CAM_ERR(CAM_ISP, "PPI init failed for PPI %d", i); + break; + } + } err: if (rc) { kfree(ife_csid_hw->ipp_res.res_priv); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h index 9b4d5c3d6add..f2173f13f0c4 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h @@ -16,6 +16,7 @@ #include "cam_hw.h" #include "cam_ife_csid_hw_intf.h" #include "cam_ife_csid_soc.h" +#include "cam_csid_ppi_core.h" #define CAM_IFE_CSID_HW_RES_MAX 4 #define CAM_IFE_CSID_CID_RES_MAX 4 @@ -309,6 +310,10 @@ struct cam_ife_csid_common_reg_offset { uint32_t ppp_irq_mask_all; uint32_t measure_en_hbi_vbi_cnt_mask; uint32_t format_measure_en_val; + uint32_t format_measure_width_shift_val; + uint32_t format_measure_width_mask_val; + uint32_t format_measure_height_shift_val; + uint32_t format_measure_height_mask_val; }; /** @@ -468,6 +473,11 @@ struct cam_ife_csid_path_cfg { * @csid_debug: csid debug information to enable the SOT, EOT, * SOF, EOF, measure etc in the csid hw * @clk_rate Clock rate + * @ipp_path ipp path configuration + * @ppp_path ppp path configuration + * @rdi_path RDI path configuration + * @hbi Horizontal blanking + * @vbi Vertical blanking * @sof_irq_triggered: Flag is set on receiving event to enable sof irq * incase of SOF freeze. * @irq_debug_cnt: Counter to track sof irq's when above flag is set. @@ -481,7 +491,9 @@ struct cam_ife_csid_path_cfg { * @res_sof_cnt path resource sof count value. it used for initial * frame drop * @first_sof_ts flag to mark the first sof has been registered - * + * @ppi_hw_intf interface to ppi hardware + * @ppi_enabled flag to specify if the hardware has ppi bridge + * or not */ struct cam_ife_csid_hw { struct cam_hw_intf *hw_intf; @@ -504,6 +516,11 @@ struct cam_ife_csid_hw { struct completion csid_rdin_complete[CAM_IFE_CSID_RDI_MAX]; uint64_t csid_debug; uint64_t clk_rate; + struct cam_isp_sensor_dimension ipp_path_config; + struct cam_isp_sensor_dimension ppp_path_config; + struct cam_isp_sensor_dimension rdi_path_config[4]; + uint32_t hbi; + uint32_t vbi; bool sof_irq_triggered; uint32_t irq_debug_cnt; uint32_t error_irq_count; @@ -513,6 +530,8 @@ struct cam_ife_csid_hw { uint32_t init_frame_drop; uint32_t res_sof_cnt[CAM_IFE_PIX_PATH_RES_MAX]; uint32_t first_sof_ts; + struct cam_hw_intf *ppi_hw_intf[CAM_CSID_PPI_HW_MAX]; + bool ppi_enable; }; int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h index 0c45bd1268b9..8d340207a0a1 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h @@ -158,6 +158,7 @@ enum cam_ife_csid_cmd_type { CAM_IFE_CSID_SET_CSID_DEBUG, CAM_IFE_CSID_SOF_IRQ_DEBUG, CAM_IFE_CSID_SET_INIT_FRAME_DROP, + CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG, CAM_IFE_CSID_CMD_MAX, }; @@ -181,5 +182,17 @@ struct cam_ife_csid_clock_update_args { uint64_t clk_rate; }; +/* + * struct cam_ife_sensor_dim_update_args: + * + * @ppp_path: expected ppp path configuration + * @ipp_path: expected ipp path configuration + * @rdi_path: expected rdi path configuration + */ +struct cam_ife_sensor_dimension_update_args { + struct cam_isp_sensor_dimension ppp_path; + struct cam_isp_sensor_dimension ipp_path; + struct cam_isp_sensor_dimension rdi_path[4]; +}; #endif /* _CAM_CSID_HW_INTF_H_ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index b23014773022..d90030d9ed16 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -20,17 +20,21 @@ #include "cam_irq_controller.h" #include +#define CAM_ISP_FPS_60 60 + /* * struct cam_isp_timestamp: * * @mono_time: Monotonic boot time * @vt_time: AV Timer time * @ticks: Qtimer ticks + * @time_usecs: time in micro seconds */ struct cam_isp_timestamp { struct timeval mono_time; struct timeval vt_time; uint64_t ticks; + uint64_t time_usecs; }; /* @@ -105,6 +109,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_FE_UPDATE_IN_RD, CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD, CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, + CAM_ISP_HW_CMD_FPS_CONFIG, CAM_ISP_HW_CMD_MAX, }; diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h index 9d6bcb71bb69..3bcedc948a18 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h @@ -177,6 +177,17 @@ struct cam_vfe_clock_update_args { uint64_t clk_rate; }; +/* + * struct cam_vfe_fps_config_args: + * + * @node_res: Resource to get the fps value + * @fps: FPS value to configure EPOCH + */ +struct cam_vfe_fps_config_args { + struct cam_isp_resource_node *node_res; + uint32_t fps; +}; + /* * struct cam_vfe_bw_update_args: * diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c index a26c11264d2c..162ddadd744f 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c @@ -444,6 +444,8 @@ void cam_isp_hw_get_timestamp(struct cam_isp_timestamp *time_stamp) get_monotonic_boottime(&ts); time_stamp->mono_time.tv_sec = ts.tv_sec; time_stamp->mono_time.tv_usec = ts.tv_nsec/1000; + time_stamp->time_usecs = ts.tv_sec * 1000000 + + time_stamp->mono_time.tv_usec; } static int cam_vfe_irq_top_half(uint32_t evt_id, @@ -761,6 +763,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_BW_UPDATE: case CAM_ISP_HW_CMD_BW_CONTROL: case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: + case CAM_ISP_HW_CMD_FPS_CONFIG: rc = core_info->vfe_top->hw_ops.process_cmd( core_info->vfe_top->top_priv, cmd_type, cmd_args, arg_size); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c index 4e9a97501749..a70f0bbd1340 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c @@ -44,6 +44,7 @@ struct cam_vfe_mux_camif_data { bool enable_sof_irq_debug; uint32_t irq_debug_cnt; uint32_t camif_debug; + uint32_t fps; }; static int cam_vfe_camif_validate_pix_pattern(uint32_t pattern) @@ -265,9 +266,15 @@ static int cam_vfe_camif_resource_start( case CAM_CPAS_TITAN_170_V110: case CAM_CPAS_TITAN_170_V120: default: - epoch0_irq_mask = (((rsrc_data->last_line - + if (rsrc_data->fps == CAM_ISP_FPS_60) { + epoch0_irq_mask = ((rsrc_data->last_line - + rsrc_data->first_line) / 2) + + rsrc_data->first_line; + } else { + epoch0_irq_mask = (((rsrc_data->last_line - rsrc_data->first_line) * 2) / 3) + rsrc_data->first_line; + } epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg & 0xFFFF; computed_epoch_line_cfg = (epoch0_irq_mask << 16) | @@ -514,6 +521,20 @@ static int cam_vfe_camif_sof_irq_debug( return 0; } +static int cam_vfe_camif_set_fps_config( + struct cam_isp_resource_node *rsrc_node, void *cmd_args) +{ + struct cam_vfe_mux_camif_data *camif_priv = NULL; + struct cam_vfe_fps_config_args *fps_args = cmd_args; + + camif_priv = + (struct cam_vfe_mux_camif_data *)rsrc_node->res_priv; + + camif_priv->fps = fps_args->fps; + + return 0; + +} static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) @@ -545,6 +566,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node, case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP: rc = cam_vfe_camif_irq_reg_dump(rsrc_node); break; + case CAM_ISP_HW_CMD_FPS_CONFIG: + rc = cam_vfe_camif_set_fps_config(rsrc_node, cmd_args); + break; default: CAM_ERR(CAM_ISP, "unsupported process command:%d", cmd_type); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c index b0ac94b895f1..9d03cbad7ff0 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c @@ -283,6 +283,22 @@ static int cam_vfe_top_fs_update( return 0; } +static int cam_vfe_top_fps_config( + struct cam_vfe_top_ver2_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + struct cam_vfe_fps_config_args *cmd_update = NULL; + + cmd_update = + (struct cam_vfe_fps_config_args *)cmd_args; + + if (cmd_update->node_res->process_cmd) + return cmd_update->node_res->process_cmd(cmd_update->node_res, + CAM_ISP_HW_CMD_FPS_CONFIG, cmd_args, arg_size); + + return 0; +} + static int cam_vfe_top_clock_update( struct cam_vfe_top_ver2_priv *top_priv, void *cmd_args, uint32_t arg_size) @@ -740,6 +756,10 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type, rc = cam_vfe_get_irq_register_dump(top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_FPS_CONFIG: + rc = cam_vfe_top_fps_config(top_priv, cmd_args, + arg_size); + break; default: rc = -EINVAL; CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type); diff --git a/include/uapi/media/cam_isp.h b/include/uapi/media/cam_isp.h index 7489b72031b7..50d95c4da9d8 100644 --- a/include/uapi/media/cam_isp.h +++ b/include/uapi/media/cam_isp.h @@ -84,14 +84,16 @@ #define CAM_ISP_DSP_MODE_ROUND 2 /* ISP Generic Cmd Buffer Blob types */ -#define CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG 0 -#define CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG 1 -#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG 2 -#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG 3 -#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 4 -#define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5 -#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 6 -#define CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP 10 +#define CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG 0 +#define CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG 1 +#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG 2 +#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG 3 +#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 4 +#define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5 +#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 6 +#define CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP 10 +#define CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG 11 +#define CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG 12 /* Per Path Usage Data */ #define CAM_ISP_USAGE_INVALID 0 @@ -464,6 +466,36 @@ struct cam_fe_config { uint32_t latency_buf_size; } __attribute__((packed)); +/** + * struct cam_isp_sensor_path_dimension + * + * @width expected width + * @height expected height + * @measure_enabled flag to indicate if pixel measurement is to be enabled + */ +struct cam_isp_sensor_dimension { + uint32_t width; + uint32_t height; + uint32_t measure_enabled; +} __attribute__((packed)); + +/** + * struct cam_isp_sensor_config - Sensor Dimension configuration + * + * @pix_path: expected ppp path configuration + * @pix_path: expected ipp path configuration + * @rdi_path: expected rdi path configuration + * @hbi: HBI value + * @vbi: VBI value + */ +struct cam_isp_sensor_config { + struct cam_isp_sensor_dimension ppp_path; + struct cam_isp_sensor_dimension ipp_path; + struct cam_isp_sensor_dimension rdi_path[4]; + uint32_t hbi; + uint32_t vbi; +} __attribute__((packed)); + /* Acquire Device/HW v2 */ /** @@ -489,6 +521,15 @@ struct cam_isp_acquire_hw_info { uint64_t data; }; +/** + * struct cam_fps_config - FPS blob support + * + * @fps: FPS value + */ +struct cam_fps_config { + uint32_t fps; +} __attribute__((packed)); + #define CAM_ISP_ACQUIRE_COMMON_VER0 0x1000 #define CAM_ISP_ACQUIRE_COMMON_SIZE_VER0 0x0 From 83d3bd35d804d513640fe6f533d3ef49924df1d2 Mon Sep 17 00:00:00 2001 From: xiaolin Date: Tue, 27 Aug 2019 23:00:46 +0800 Subject: [PATCH 270/281] ARM: dts: Create the regulator VDD node for PCIE0 We use the gpio90 to control the VDD for PCIE0 but it causes the wrong pin status. And we can use the regulator-fixed framework to enable this VDD for PCIE0 and fixed the wrong pin status. Change-Id: I26b419f95300c2334c3de575939197b47373cd70 Signed-off-by: xiaolin --- arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi index 47638e3e57d4..5e1291a54df3 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-v2.1-rb3.dtsi @@ -98,10 +98,8 @@ }; &pcie0 { - pinctrl-names = "default", "slot_power_on"; - pinctrl-1 = <&pcie0_3v3_on &pcie0_1v5_on>; - 3v3_gpio = <&tlmm 90 0>; - 1v5_gpio = <&tlmm 90 0>; + vreg-pcie-supply = <&pcie_vcc_eldo>; + qcom,vreg-pcie-voltage-level = <3300000 3300000 24000>; status = "ok"; }; @@ -250,6 +248,16 @@ gpio = <&tlmm 89 0>; enable-active-high; }; + + pcie_vcc_eldo: pcie-gpio-regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "pcie_vcc_eldo"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&tlmm 90 0>; + enable-active-high; + }; + }; &qupv3_se10_i2c { From a95d897e81e13b698db434d9c17dda69e0cd7241 Mon Sep 17 00:00:00 2001 From: Arun Kumar Neelakantam Date: Wed, 28 Aug 2019 11:53:09 +0530 Subject: [PATCH 271/281] soc: qcom: glink_smem: Add block_signal flag to tx_wakeup READ_NOTIFY command is not written into FIFO again due incorrect wakeup of tasks in TX blocked queue. Add valid "tx_blocked_signal_sent" check before calling tx_wakeup. Change-Id: Iec011746f555a49ea1635dcae4cd8162d9b619bd Signed-off-by: Arun Kumar Neelakantam --- drivers/soc/qcom/glink_smem_native_xprt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c index e7f689ad4e05..4cdf6130b0f9 100644 --- a/drivers/soc/qcom/glink_smem_native_xprt.c +++ b/drivers/soc/qcom/glink_smem_native_xprt.c @@ -907,9 +907,8 @@ static void tx_wakeup_worker(struct edge_info *einfo) einfo->tx_resume_needed = false; trigger_resume = true; } - } - if (waitqueue_active(&einfo->tx_blocked_queue)) { /* tx waiting ?*/ - trigger_wakeup = true; + if (waitqueue_active(&einfo->tx_blocked_queue))/* tx waiting ?*/ + trigger_wakeup = true; } spin_unlock_irqrestore(&einfo->write_lock, flags); if (trigger_wakeup) @@ -963,8 +962,9 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx) einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if); } - if ((atomic_ctx) && ((einfo->tx_resume_needed) || - (waitqueue_active(&einfo->tx_blocked_queue)))) /* tx waiting ?*/ + if ((atomic_ctx) && ((einfo->tx_resume_needed) + || (einfo->tx_blocked_signal_sent) + || (waitqueue_active(&einfo->tx_blocked_queue)))) /* tx waiting ?*/ tx_wakeup_worker(einfo); /* From 0ebb2de2e4e2c79acc9b807b9211a22bc981d857 Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Tue, 20 Aug 2019 13:52:32 +0530 Subject: [PATCH 272/281] fs: crypto: free allocated memory after usage Memory allocated for raw key generation for file name/data should be freed after usage which otherwise will lead to memory leak. Change-Id: I51c79957a58f33288dd011aac9b415d2b0261d1a Signed-off-by: Neeraj Soni --- fs/crypto/keyinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c index cfe9117dd4e7..837a3de08f65 100755 --- a/fs/crypto/keyinfo.c +++ b/fs/crypto/keyinfo.c @@ -615,6 +615,7 @@ int fscrypt_get_encryption_info(struct inode *inode) if (res == -ENOKEY) res = 0; put_crypt_info(crypt_info); + kzfree(raw_key); return res; } EXPORT_SYMBOL(fscrypt_get_encryption_info); From 702cec976c863388c784eff37a71fa3ee8bb84d7 Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Tue, 13 Aug 2019 17:12:33 +0800 Subject: [PATCH 273/281] sched/walt: Avoid walt irq work in offlined cpu Avoid walt irq work in offlined cpu. Change-Id: Ia4410562f66bfa57daa15d8c0a785a2c7a95f2a0 Signed-off-by: Maria Yu --- kernel/sched/sched.h | 10 ++++++++++ kernel/sched/walt.c | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 8b351c8624b9..e8faa552b684 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -2975,3 +2975,13 @@ find_first_cpu_bit(struct task_struct *p, const cpumask_t *search_cpus, #else #define find_first_cpu_bit(...) -1 #endif + +#ifdef CONFIG_SMP +static inline void sched_irq_work_queue(struct irq_work *work) +{ + if (likely(cpu_online(raw_smp_processor_id()))) + irq_work_queue(work); + else + irq_work_queue_on(work, cpumask_any(cpu_online_mask)); +} +#endif diff --git a/kernel/sched/walt.c b/kernel/sched/walt.c index 9a85525bb4a3..c34311bb30cd 100644 --- a/kernel/sched/walt.c +++ b/kernel/sched/walt.c @@ -893,7 +893,7 @@ void fixup_busy_time(struct task_struct *p, int new_cpu) if (!same_freq_domain(new_cpu, task_cpu(p))) { src_rq->notif_pending = true; dest_rq->notif_pending = true; - irq_work_queue(&walt_migration_irq_work); + sched_irq_work_queue(&walt_migration_irq_work); } if (p == src_rq->ed_task) { @@ -1956,7 +1956,7 @@ static inline void run_walt_irq_work(u64 old_window_start, struct rq *rq) result = atomic64_cmpxchg(&walt_irq_work_lastq_ws, old_window_start, rq->window_start); if (result == old_window_start) - irq_work_queue(&walt_cpufreq_irq_work); + sched_irq_work_queue(&walt_cpufreq_irq_work); } /* Reflect task activity on its demand and cpu's busy time statistics */ From 1d2db9ab99a9abd0d9dcb320e6e0d266e21884f9 Mon Sep 17 00:00:00 2001 From: Maria Yu Date: Tue, 13 Aug 2019 17:25:28 +0800 Subject: [PATCH 274/281] cpufreq: schedutil: Queue sugov irq work on policy online cpu Got never update frequency if scheduled the irq work on an offlined cpu and it will always pending. Queue sugov irq work on any online cpu if current cpu is offline. Change-Id: I33fc691917b5866488b6aeb11ed902a2753130b2 Signed-off-by: Maria Yu --- kernel/sched/cpufreq_schedutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 0745029cf262..cfe4f40d5819 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -154,7 +154,7 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time, trace_cpu_frequency(next_freq, smp_processor_id()); } else { sg_policy->work_in_progress = true; - irq_work_queue(&sg_policy->irq_work); + sched_irq_work_queue(&sg_policy->irq_work); } } From 07b9c75b395230a0bcd101e0d6ec7c0518e49267 Mon Sep 17 00:00:00 2001 From: xiaolin Date: Tue, 27 Aug 2019 23:11:12 +0800 Subject: [PATCH 275/281] msm: pcie: Add the regulator node for PCI-E client It is better to control the gpio90 with regulator-fixed framework, which can offer the VDD for PCI-E client. We make it more modularized in this way.Also it is more suitable for adjusting the powering position to the beginning of enumerating, which can save more powering at RBSC. Change-Id: Ie49faa663bb99ddf8d40b0810725508cd44c77e7 Signed-off-by: xiaolin --- drivers/pci/host/pci-msm.c | 51 ++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c index a1dab5515c46..b8a8a92d6d05 100644 --- a/drivers/pci/host/pci-msm.c +++ b/drivers/pci/host/pci-msm.c @@ -517,6 +517,7 @@ struct msm_pcie_dev_t { struct platform_device *pdev; struct pci_dev *dev; struct regulator *gdsc; + struct regulator *vreg_pcie; struct regulator *gdsc_smmu; struct msm_pcie_vreg_info_t vreg[MSM_PCIE_MAX_VREG]; struct msm_pcie_gpio_info_t gpio[MSM_PCIE_MAX_GPIO]; @@ -633,7 +634,6 @@ struct msm_pcie_dev_t { bool use_pinctrl; struct pinctrl *pinctrl; struct pinctrl_state *pins_default; - struct pinctrl_state *pins_power_on; struct pinctrl_state *pins_sleep; struct msm_pcie_device_info pcidev_table[MAX_DEVICE_NUM]; }; @@ -3422,6 +3422,18 @@ static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, } } + dev->vreg_pcie = devm_regulator_get(&pdev->dev, "vreg-pcie"); + + if (IS_ERR(dev->vreg_pcie)) { + PCIE_ERR(dev, "PCIe: RC%d Failed to get %s VREG_PCIE:%ld\n", + dev->rc_idx, dev->pdev->name, PTR_ERR(dev->gdsc)); + if (PTR_ERR(dev->vreg_pcie) == -EPROBE_DEFER) + PCIE_DBG(dev, "PCIe: EPROBE_DEFER for %s VREG_PCIE\n", + dev->pdev->name); + ret = PTR_ERR(dev->vreg_pcie); + goto out; + } + dev->gdsc = devm_regulator_get(&pdev->dev, "gdsc-vdd"); if (IS_ERR(dev->gdsc)) { @@ -4287,6 +4299,19 @@ int msm_pcie_enumerate(u32 rc_idx) } if (!dev->enumerated) { + + /*Open the PCIE VCC before enable the pcie */ + if (dev->vreg_pcie) { + ret = regulator_enable(dev->vreg_pcie); + + if (ret) { + PCIE_ERR(dev, + "PCIe: fail to open vcc for RC%d (%s)\n", + dev->rc_idx, dev->pdev->name); + return ret; + } + } + ret = msm_pcie_enable(dev, PM_ALL); /* kick start ARM PCI configuration framework */ @@ -6013,16 +6038,6 @@ static int msm_pcie_probe(struct platform_device *pdev) msm_pcie_dev[rc_idx].pins_default = NULL; } - msm_pcie_dev[rc_idx].pins_power_on = - pinctrl_lookup_state(msm_pcie_dev[rc_idx].pinctrl, - "slot_power_on"); - if (IS_ERR(msm_pcie_dev[rc_idx].pins_power_on)) { - PCIE_ERR(&msm_pcie_dev[rc_idx], - "PCIe: RC%d could not get pinctrl power_on state\n", - rc_idx); - msm_pcie_dev[rc_idx].pins_power_on = NULL; - } - msm_pcie_dev[rc_idx].pins_sleep = pinctrl_lookup_state(msm_pcie_dev[rc_idx].pinctrl, "sleep"); @@ -6050,11 +6065,6 @@ static int msm_pcie_probe(struct platform_device *pdev) msm_pcie_sysfs_init(&msm_pcie_dev[rc_idx]); msm_pcie_dev[rc_idx].drv_ready = true; - if (msm_pcie_dev[rc_idx].use_pinctrl && - msm_pcie_dev[rc_idx].pins_power_on) { - pinctrl_select_state(msm_pcie_dev[rc_idx].pinctrl, - msm_pcie_dev[rc_idx].pins_power_on); - } if (msm_pcie_dev[rc_idx].boot_option & MSM_PCIE_NO_PROBE_ENUMERATION) { @@ -6122,6 +6132,15 @@ static int msm_pcie_remove(struct platform_device *pdev) msm_pcie_gpio_deinit(&msm_pcie_dev[rc_idx]); msm_pcie_release_resources(&msm_pcie_dev[rc_idx]); + /*Close the PCIE VCC when remove the pcie*/ + if (msm_pcie_dev[rc_idx].vreg_pcie) { + ret = regulator_disable(msm_pcie_dev[rc_idx].vreg_pcie); + + if (ret) + pr_err("%s: PCIe: fail to close VCC.\n", __func__); + + } + out: mutex_unlock(&pcie_drv.drv_lock); From 0a30c8eff8a43a1f58d6e7ad66bdf4006322d0d4 Mon Sep 17 00:00:00 2001 From: Pavankumar Vijapur Date: Thu, 22 Aug 2019 14:25:10 +0530 Subject: [PATCH 276/281] ARM: dts: msm: Add telematics specific dts files for sa415m Add dts for telematics CDT that will be used for telematics use case on MTP and CDP devices. Change-Id: I6f7b3c4e7a0e1cf574ad414cff13bbb551a4a8df Signed-off-by: Pavankumar Vijapur --- arch/arm/boot/dts/qcom/Makefile | 10 +++++-- arch/arm/boot/dts/qcom/sa415m-cdp.dts | 32 +++++++++++++++++++++ arch/arm/boot/dts/qcom/sa415m-mtp-256.dts | 30 +++++++++++++++++++ arch/arm/boot/dts/qcom/sa415m-v2-cdp.dts | 33 +++++++++++++++++++++ arch/arm/boot/dts/qcom/sa415m-v2-mtp.dts | 35 +++++++++++++++++++++++ 5 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 arch/arm/boot/dts/qcom/sa415m-cdp.dts create mode 100644 arch/arm/boot/dts/qcom/sa415m-mtp-256.dts create mode 100644 arch/arm/boot/dts/qcom/sa415m-v2-cdp.dts create mode 100644 arch/arm/boot/dts/qcom/sa415m-v2-mtp.dts diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index ff0ae9a96e54..d1edfd97372b 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -3,7 +3,6 @@ dtb-$(CONFIG_ARCH_SDXPOORWILLS) += sdxpoorwills-rumi.dtb \ sdxpoorwills-cdp.dtb \ sdxpoorwills-mtp.dtb \ sdxpoorwills-atp.dtb \ - sa415m-ttp.dtb \ sdxpoorwills-cdp-256.dtb \ sdxpoorwills-mtp-256.dtb \ sdxpoorwills-dualwifi-cdp.dtb \ @@ -16,12 +15,17 @@ dtb-$(CONFIG_ARCH_SDXPOORWILLS) += sdxpoorwills-rumi.dtb \ sdxpoorwills-v2-cdp.dtb \ sdxpoorwills-v2-dualwifi-mtp.dtb \ sdxpoorwills-v2-dualwifi-cdp.dtb \ + sdxpoorwills-v2-pcie-ep-mtp-256.dtb \ + sdxpoorwills-v2-pcie-ep-mtp.dtb \ + sa415m-ttp.dtb \ sa415m-ccard.dtb \ sa415m-ccard-pcie-ep.dtb \ sa415m-ccard-usb-ep.dtb \ sa415m-ttp-usb-ep.dtb \ - sdxpoorwills-v2-pcie-ep-mtp-256.dtb \ - sdxpoorwills-v2-pcie-ep-mtp.dtb + sa415m-mtp-256.dtb \ + sa415m-cdp.dtb \ + sa415m-v2-cdp.dtb \ + sa415m-v2-mtp.dtb dtb-$(CONFIG_ARCH_MDM9650) += mdm9650-nand-mtp.dtb \ mdm9650-ttp.dtb \ diff --git a/arch/arm/boot/dts/qcom/sa415m-cdp.dts b/arch/arm/boot/dts/qcom/sa415m-cdp.dts new file mode 100644 index 000000000000..b9e7d4947c6e --- /dev/null +++ b/arch/arm/boot/dts/qcom/sa415m-cdp.dts @@ -0,0 +1,32 @@ +/* Copyright (c) 2019, 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 "sdxpoorwills-cdp.dtsi" +#include "sdxpoorwills-display.dtsi" +#include "qpic-panel-ili-hvga.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA415M CDP"; + compatible = "qcom,sdxpoorwills-cdp", + "qcom,sdxpoorwills", "qcom,cdp"; + qcom,board-id = <1 0x104>; +}; + +&blsp1_uart2b_hs { + status = "okay"; +}; + +&mss_mem { + reg = <0x86400000 0x9300000>; +}; diff --git a/arch/arm/boot/dts/qcom/sa415m-mtp-256.dts b/arch/arm/boot/dts/qcom/sa415m-mtp-256.dts new file mode 100644 index 000000000000..09a8ea0a3b5c --- /dev/null +++ b/arch/arm/boot/dts/qcom/sa415m-mtp-256.dts @@ -0,0 +1,30 @@ +/* Copyright (c) 2019, 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 "sdxpoorwills-mtp-256.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA415M MTP (256MB)"; + compatible = "qcom,sdxpoorwills-mtp", + "qcom,sdxpoorwills", "qcom,mtp"; + qcom,board-id = <8 0x106>; +}; + +&blsp1_uart2b_hs { + status = "okay"; +}; + +&mss_mem { + reg = <0x86400000 0x9300000>; +}; diff --git a/arch/arm/boot/dts/qcom/sa415m-v2-cdp.dts b/arch/arm/boot/dts/qcom/sa415m-v2-cdp.dts new file mode 100644 index 000000000000..c8b78915dac0 --- /dev/null +++ b/arch/arm/boot/dts/qcom/sa415m-v2-cdp.dts @@ -0,0 +1,33 @@ +/* Copyright (c) 2019, 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 "sdxpoorwills-cdp.dtsi" +#include "sdxpoorwills-v2.dtsi" +#include "sdxpoorwills-display.dtsi" +#include "qpic-panel-ili-hvga.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA415M CDP V2"; + compatible = "qcom,sdxpoorwills-cdp", + "qcom,sdxpoorwills", "qcom,cdp"; + qcom,board-id = <1 0x104>; +}; + +&blsp1_uart2b_hs { + status = "okay"; +}; + +&mss_mem { + reg = <0x86400000 0x9300000>; +}; diff --git a/arch/arm/boot/dts/qcom/sa415m-v2-mtp.dts b/arch/arm/boot/dts/qcom/sa415m-v2-mtp.dts new file mode 100644 index 000000000000..c7cbbd1ba1f5 --- /dev/null +++ b/arch/arm/boot/dts/qcom/sa415m-v2-mtp.dts @@ -0,0 +1,35 @@ +/* Copyright (c) 2019, 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 "sdxpoorwills-mtp.dtsi" +#include "sdxpoorwills-v2.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA415M MTP V2"; + compatible = "qcom,sdxpoorwills-mtp", + "qcom,sdxpoorwills", "qcom,mtp"; + qcom,board-id = <8 0x106>; +}; + +&qcom_seecom { + status = "okay"; +}; + +&blsp1_uart2b_hs { + status = "okay"; +}; + +&mss_mem { + reg = <0x86400000 0x9300000>; +}; From 0ba22eb92a78405907150b227153c255b9221f27 Mon Sep 17 00:00:00 2001 From: Venu Raidu Date: Thu, 29 Aug 2019 21:59:10 -0700 Subject: [PATCH 277/281] Revert "msm: camera_v2: CPP AXI reset at close" This reverts commit 55f035b2004acccb513bd9f940bfa7b2a2df88b5. AB/IB voting is not required to reset CPP AXI/HW during camera close. Change-Id: Ie4c1ca47dd11799489c13b1f55d5524a5f4481af Signed-off-by: Venu Raidu --- drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index 576d5d6742dd..35e25b38474b 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -1571,12 +1571,6 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) pr_debug("DEBUG_R1: 0x%x\n", msm_camera_io_r(cpp_dev->cpp_hw_base + 0x8C)); - /* Update bandwidth usage to enable AXI/ABH clock, - * which will help to reset CPP AXI.Bandwidth will be - * made zero at cpp_release_hardware. - */ - msm_cpp_update_bandwidth(cpp_dev, 0x1000, 0x1000); - /* mask IRQ status */ msm_camera_io_w(0xB, cpp_dev->cpp_hw_base + 0xC); From d1a5a8645d94d1e2d367f3a3bc1b0957fb7c3d59 Mon Sep 17 00:00:00 2001 From: jiangjia Date: Fri, 30 Aug 2019 14:14:42 +0800 Subject: [PATCH 278/281] input: touchscreen: cyttsp5: use workqueue to call resume The fb_notifier calling resume is blocking the wakeup of screen, schedule a work to resume the touch screen when turning on the fb. This could reduce the latency when waking up the phone. Change-Id: I0d0d93972e6d775082f9453fb5dc984a56701f73 Signed-off-by: Jiangjiang Shen --- .../input/touchscreen/cyttsp5/cyttsp5_core.c | 24 ++++++++++++++----- .../input/touchscreen/cyttsp5/cyttsp5_regs.h | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c index 44bb9ba6507e..f2b2bce3e138 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c @@ -3765,6 +3765,7 @@ static int cyttsp5_core_sleep_(struct cyttsp5_core_data *cd) /* Ensure watchdog and startup works stopped */ cyttsp5_stop_wd_timer(cd); cancel_work_sync(&cd->startup_work); + cancel_work_sync(&cd->resume_work); cyttsp5_stop_wd_timer(cd); if (cd->cpdata->flags & CY_CORE_FLAG_POWEROFF_ON_SLEEP) @@ -5965,6 +5966,19 @@ void *cyttsp5_get_module_data(struct device *dev, struct cyttsp5_module *module) } EXPORT_SYMBOL(cyttsp5_get_module_data); +static void cyttsp5_resume_work(struct work_struct *work) +{ + struct cyttsp5_core_data *cd = container_of(work, + struct cyttsp5_core_data, resume_work); + + #ifdef USE_FB_SUSPEND_RESUME + cyttsp5_core_resume(cd->dev); + cd->wake_initiated_by_device = 0; + #endif + call_atten_cb(cd, CY_ATTEN_RESUME, 0); + cd->fb_state = FB_ON; +} + #ifdef CONFIG_HAS_EARLYSUSPEND static void cyttsp5_early_suspend(struct early_suspend *h) { @@ -6008,12 +6022,7 @@ static int fb_notifier_callback(struct notifier_block *self, case FB_BLANK_UNBLANK: dev_dbg(cd->dev, "%s: UNBLANK!\n", __func__); if (cd->fb_state != FB_ON) { - #ifdef USE_FB_SUSPEND_RESUME - cyttsp5_core_resume(cd->dev); - cd->wake_initiated_by_device = 0; - #endif - call_atten_cb(cd, CY_ATTEN_RESUME, 0); - cd->fb_state = FB_ON; + schedule_work(&cd->resume_work); } break; @@ -6305,6 +6314,7 @@ int cyttsp5_probe(const struct cyttsp5_bus_ops *ops, struct device *dev, /* Initialize works */ INIT_WORK(&cd->startup_work, cyttsp5_startup_work_function); + INIT_WORK(&cd->resume_work, cyttsp5_resume_work); INIT_WORK(&cd->watchdog_work, cyttsp5_watchdog_work); /* Initialize HID specific data */ @@ -6448,6 +6458,7 @@ int cyttsp5_probe(const struct cyttsp5_bus_ops *ops, struct device *dev, pm_runtime_disable(dev); device_init_wakeup(dev, 0); cancel_work_sync(&cd->startup_work); + cancel_work_sync(&cd->resume_work); cyttsp5_stop_wd_timer(cd); remove_sysfs_interfaces(dev); error_attr_create: @@ -6498,6 +6509,7 @@ int cyttsp5_release(struct cyttsp5_core_data *cd) pm_runtime_disable(dev); cancel_work_sync(&cd->startup_work); + cancel_work_sync(&cd->resume_work); cyttsp5_stop_wd_timer(cd); diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h b/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h index e7b16db91b1f..69870ef62976 100644 --- a/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h +++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_regs.h @@ -991,6 +991,7 @@ struct cyttsp5_core_data { struct notifier_block pm_notifier; #endif struct work_struct startup_work; + struct work_struct resume_work; struct cyttsp5_sysinfo sysinfo; void *exclusive_dev; int exclusive_waits; From 51e69715e4a3f0bbaca9e4bacbf972a26cd4f64b Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Fri, 30 Aug 2019 12:23:07 +0530 Subject: [PATCH 279/281] hwmon: qpnp-adc: Correct return statement in VADC HC read API Remove return statement in case of failure to write to calibration peripheral and replace with goto statement to ensure mutex is released. Change-Id: Iea91c80f5049d4ad7cb43a9ce8e7338ad522624d Signed-off-by: Jishnu Prakash --- drivers/hwmon/qpnp-adc-voltage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c index 086e706a242e..772aac1e9ebd 100644 --- a/drivers/hwmon/qpnp-adc-voltage.c +++ b/drivers/hwmon/qpnp-adc-voltage.c @@ -749,7 +749,7 @@ int32_t qpnp_vadc_hc_read(struct qpnp_vadc_chip *vadc, QPNP_VADC_CAL_DELAY_CTL_1, &val, 1); if (rc < 0) { pr_err("qpnp adc write cal_delay failed with %d\n", rc); - return rc; + goto fail_unlock; } } From 677362c91df98b2815b951773331955e336b1f5e Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Fri, 30 Aug 2019 10:50:25 -0700 Subject: [PATCH 280/281] qseecom: check invalid handle for app loaded query request Check if the handle data type received from userspace is valid for app loaded query request to avoid the offset boundary check for qseecom_send_modfd_resp is bypassed. Change-Id: I5f3611a8f830d6904213781c5ba70cfc0ba3e2e0 Signed-off-by: Zhen Kong --- drivers/misc/qseecom.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 6f90263ab80d..8a76b649f09c 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -7534,6 +7534,13 @@ static long qseecom_ioctl(struct file *file, break; } case QSEECOM_IOCTL_APP_LOADED_QUERY_REQ: { + if ((data->type != QSEECOM_GENERIC) && + (data->type != QSEECOM_CLIENT_APP)) { + pr_err("app loaded query req: invalid handle (%d)\n", + data->type); + ret = -EINVAL; + break; + } data->type = QSEECOM_CLIENT_APP; mutex_lock(&app_access_lock); atomic_inc(&data->ioctl_count); From 1f01db5a42ccd3123517a9d5730024719abf095d Mon Sep 17 00:00:00 2001 From: Tingwei Zhang Date: Tue, 10 Sep 2019 13:58:33 +0800 Subject: [PATCH 281/281] Revert "HID: core: move Usage Page concatenation to Main item" This reverts commit 1410277e190084f1de51f8656215d508d9132086. Upstream commit causes issue in report parsing leading to device registration failure. Change-Id: Ia1615c1330157de1d7583f60902552b888b95404 Signed-off-by: Tingwei Zhang --- drivers/hid/hid-core.c | 36 ++++++++++++------------------------ include/linux/hid.h | 1 - 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d030731d2a51..81efba580279 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -200,14 +200,13 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) * Add a usage to the temporary parser table. */ -static int hid_add_usage(struct hid_parser *parser, unsigned usage, u8 size) +static int hid_add_usage(struct hid_parser *parser, unsigned usage) { if (parser->local.usage_index >= HID_MAX_USAGES) { hid_err(parser->device, "usage index exceeded\n"); return -1; } parser->local.usage[parser->local.usage_index] = usage; - parser->local.usage_size[parser->local.usage_index] = size; parser->local.collection_index[parser->local.usage_index] = parser->collection_stack_ptr ? parser->collection_stack[parser->collection_stack_ptr - 1] : 0; @@ -464,7 +463,10 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) return 0; } - return hid_add_usage(parser, data, item->size); + if (item->size <= 2) + data = (parser->global.usage_page << 16) + data; + + return hid_add_usage(parser, data); case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: @@ -473,6 +475,9 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) return 0; } + if (item->size <= 2) + data = (parser->global.usage_page << 16) + data; + parser->local.usage_minimum = data; return 0; @@ -483,6 +488,9 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) return 0; } + if (item->size <= 2) + data = (parser->global.usage_page << 16) + data; + count = data - parser->local.usage_minimum; if (count + parser->local.usage_index >= HID_MAX_USAGES) { /* @@ -502,7 +510,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) } for (n = parser->local.usage_minimum; n <= data; n++) - if (hid_add_usage(parser, n, item->size)) { + if (hid_add_usage(parser, n)) { dbg_hid("hid_add_usage failed\n"); return -1; } @@ -516,22 +524,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) return 0; } -/* - * Concatenate Usage Pages into Usages where relevant: - * As per specification, 6.2.2.8: "When the parser encounters a main item it - * concatenates the last declared Usage Page with a Usage to form a complete - * usage value." - */ - -static void hid_concatenate_usage_page(struct hid_parser *parser) -{ - int i; - - for (i = 0; i < parser->local.usage_index; i++) - if (parser->local.usage_size[i] <= 2) - parser->local.usage[i] += parser->global.usage_page << 16; -} - /* * Process a main item. */ @@ -541,8 +533,6 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) __u32 data; int ret; - hid_concatenate_usage_page(parser); - data = item_udata(item); switch (item->tag) { @@ -756,8 +746,6 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) __u32 data; int i; - hid_concatenate_usage_page(parser); - data = item_udata(item); switch (item->tag) { diff --git a/include/linux/hid.h b/include/linux/hid.h index 04bdf5477ec5..fab65b61d6d4 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -374,7 +374,6 @@ struct hid_global { struct hid_local { unsigned usage[HID_MAX_USAGES]; /* usage array */ - u8 usage_size[HID_MAX_USAGES]; /* usage size array */ unsigned collection_index[HID_MAX_USAGES]; /* collection index array */ unsigned usage_index; unsigned usage_minimum;