Merge "defconfig: msm: Enable CONFIG_DEBUG_PREEMPT on SDM845"
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index 71556ba..e1136da 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -312,8 +312,8 @@
reg = <0x8fe40000 0xc0000>,
<0x17811008 0x4>;
reg-names = "smem", "irq-reg-base";
- qcom,irq-mask = <0x1000>;
- interrupts = <GIC_SPI 111 IRQ_TYPE_EDGE_RISING>;
+ qcom,irq-mask = <0x8000>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_EDGE_RISING>;
label = "mpss";
};
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index 877406f..0d35667 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -217,6 +217,7 @@
CONFIG_QCOM_DLOAD_MODE=y
CONFIG_POWER_SUPPLY=y
CONFIG_SMB138X_CHARGER=y
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
CONFIG_THERMAL_QPNP=y
CONFIG_THERMAL_TSENS=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index d860595..6c24910 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -210,6 +210,7 @@
CONFIG_QCOM_DLOAD_MODE=y
CONFIG_POWER_SUPPLY=y
CONFIG_SMB138X_CHARGER=y
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
CONFIG_THERMAL_QPNP=y
CONFIG_THERMAL_TSENS=y
diff --git a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
index 8e152b0..0320bd9 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
@@ -53,7 +53,27 @@
};
&qupv3_se3_i2c {
- status = "disabled";
+ status = "ok";
+ nq@28 {
+ compatible = "qcom,nq-nci";
+ reg = <0x28>;
+ qcom,nq-irq = <&tlmm 44 0x00>;
+ qcom,nq-ven = <&tlmm 12 0x00>;
+ qcom,nq-firm = <&tlmm 43 0x00>;
+ qcom,nq-clkreq = <&pm660_gpios 4 0x00>;
+ qcom,nq-esepwr = <&tlmm 116 0x00>;
+ interrupt-parent = <&tlmm>;
+ qcom,clk-src = "BBCLK3";
+ interrupts = <44 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>;
+ clocks = <&clock_rpmh RPMH_LN_BB_CLK3>;
+ clock-names = "ref_clk";
+ };
};
&qupv3_se10_i2c {
diff --git a/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi b/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
index d054164..980ade2 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
@@ -625,20 +625,20 @@
};
port@6 {
- reg = <10>;
- tpda_in_tpdm_qm: endpoint {
+ reg = <11>;
+ tpda_in_tpdm_north: endpoint {
slave-mode;
remote-endpoint =
- <&tpdm_qm_out_tpda>;
+ <&tpdm_north_out_tpda>;
};
};
port@7 {
- reg = <11>;
- tpda_in_tpdm_north: endpoint {
+ reg = <12>;
+ tpda_in_tpdm_qm: endpoint {
slave-mode;
remote-endpoint =
- <&tpdm_north_out_tpda>;
+ <&tpdm_qm_out_tpda>;
};
};
@@ -1995,7 +1995,7 @@
};
port@2 {
- reg = <1>;
+ reg = <2>;
funnel_apss_merg_in_tpda_olc: endpoint {
slave-mode;
remote-endpoint =
@@ -2004,7 +2004,7 @@
};
port@3 {
- reg = <3>;
+ reg = <4>;
funnel_apss_merg_in_tpda_apss: endpoint {
slave-mode;
remote-endpoint =
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index 016917b..57408d2 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -54,7 +54,27 @@
};
&qupv3_se3_i2c {
- status = "disabled";
+ status = "ok";
+ nq@28 {
+ compatible = "qcom,nq-nci";
+ reg = <0x28>;
+ qcom,nq-irq = <&tlmm 44 0x00>;
+ qcom,nq-ven = <&tlmm 12 0x00>;
+ qcom,nq-firm = <&tlmm 43 0x00>;
+ qcom,nq-clkreq = <&pm660_gpios 4 0x00>;
+ qcom,nq-esepwr = <&tlmm 116 0x00>;
+ interrupt-parent = <&tlmm>;
+ qcom,clk-src = "BBCLK3";
+ interrupts = <44 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>;
+ clocks = <&clock_rpmh RPMH_LN_BB_CLK3>;
+ clock-names = "ref_clk";
+ };
};
&qupv3_se10_i2c {
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
index 2bf00fb..2ddab5b 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
@@ -908,7 +908,7 @@
qupv3_se12_2uart_active: qupv3_se12_2uart_active {
mux {
pins = "gpio51", "gpio52";
- function = "qup9";
+ function = "qup12";
};
config {
@@ -1371,6 +1371,70 @@
};
};
+ nfc {
+ nfc_int_active: nfc_int_active {
+ /* active state */
+ mux {
+ /* GPIO 44 NFC Read Interrupt */
+ pins = "gpio44";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio44";
+ drive-strength = <2>; /* 2 MA */
+ bias-pull-up;
+ };
+ };
+
+ nfc_int_suspend: nfc_int_suspend {
+ /* sleep state */
+ mux {
+ /* GPIO 44 NFC Read Interrupt */
+ pins = "gpio44";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio44";
+ drive-strength = <2>; /* 2 MA */
+ bias-pull-up;
+ };
+ };
+
+ nfc_enable_active: nfc_enable_active {
+ /* active state */
+ mux {
+ /* 12: NFC ENABLE 43: FW DNLD */
+ /* 116: ESE Enable */
+ pins = "gpio12", "gpio43", "gpio116";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio12", "gpio43", "gpio116";
+ drive-strength = <2>; /* 2 MA */
+ bias-pull-up;
+ };
+ };
+
+ nfc_enable_suspend: nfc_enable_suspend {
+ /* sleep state */
+ mux {
+ /* 12: NFC ENABLE 43: FW DNLD */
+ /* 116: ESE Enable */
+ pins = "gpio12", "gpio43", "gpio116";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio12", "gpio43", "gpio116";
+ drive-strength = <2>; /* 2 MA */
+ bias-disable;
+ };
+ };
+ };
+
/* WSA speaker reset pins */
spkr_1_sd_n {
spkr_1_sd_n_sleep: spkr_1_sd_n_sleep {
@@ -1651,6 +1715,14 @@
};
&pm660_gpios {
+ nfc_clk {
+ nfc_clk_default: nfc_clk_default {
+ pins = "gpio4";
+ function = "normal";
+ input-enable;
+ power-source = <1>;
+ };
+ };
smb_shutdown_default: smb_shutdown_default {
pins = "gpio11";
function = "normal";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm670-qrd.dtsi
index 616980c..5fc4065 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-qrd.dtsi
@@ -28,7 +28,27 @@
};
&qupv3_se3_i2c {
- status = "disabled";
+ status = "ok";
+ nq@28 {
+ compatible = "qcom,nq-nci";
+ reg = <0x28>;
+ qcom,nq-irq = <&tlmm 44 0x00>;
+ qcom,nq-ven = <&tlmm 12 0x00>;
+ qcom,nq-firm = <&tlmm 43 0x00>;
+ qcom,nq-clkreq = <&pm660_gpios 4 0x00>;
+ qcom,nq-esepwr = <&tlmm 116 0x00>;
+ interrupt-parent = <&tlmm>;
+ qcom,clk-src = "BBCLK3";
+ interrupts = <44 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>;
+ clocks = <&clock_rpmh RPMH_LN_BB_CLK3>;
+ clock-names = "ref_clk";
+ };
};
&qupv3_se10_i2c {
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 61df4ce..02bf8c7 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -347,23 +347,14 @@
CPU_COST_0: core-cost0 {
busy-cost-data = <
300000 14
- 403200 18
- 480000 21
576000 25
- 652800 27
748800 31
- 825600 40
- 902400 43
- 979200 46
- 1056000 50
- 1132800 53
- 1228800 57
+ 998400 46
+ 1209600 57
1324800 84
- 1420800 90
1516800 96
1612800 114
- 1689600 135
- 1766400 141
+ 1708000 139
>;
idle-cost-data = <
12 10 8 6
@@ -372,32 +363,23 @@
CPU_COST_1: core-cost1 {
busy-cost-data = <
300000 256
- 403200 271
- 480000 282
- 576000 296
652800 307
- 748800 321
825600 332
- 902400 369
979200 382
- 1056000 395
1132800 408
- 1209600 421
- 1286400 434
1363200 448
- 1459200 567
- 1536000 586
- 1612800 604
- 1689600 622
- 1766400 641
+ 1563000 586
+ 1747200 641
1843200 659
- 1920000 678
1996800 696
- 2092800 876
+ 2054400 876
2169600 900
- 2246400 924
- 2323200 948
+ 2208000 924
+ 2361600 948
2400000 1170
+ 2457600 1200
+ 2515200 1300
+ 2611200 1400
>;
idle-cost-data = <
100 80 60 40
@@ -406,23 +388,14 @@
CLUSTER_COST_0: cluster-cost0 {
busy-cost-data = <
300000 5
- 403200 7
- 480000 7
576000 7
- 652800 8
748800 8
- 825600 9
- 902400 9
- 979200 9
- 1056000 10
- 1132800 10
- 1228800 10
+ 998400 9
+ 1209600 10
1324800 13
- 1420800 14
1516800 15
1612800 16
- 1689600 19
- 1766400 19
+ 1708000 19
>;
idle-cost-data = <
4 3 2 1
@@ -431,32 +404,23 @@
CLUSTER_COST_1: cluster-cost1 {
busy-cost-data = <
300000 25
- 403200 27
- 480000 28
- 576000 29
652800 30
- 748800 32
825600 33
- 902400 36
979200 38
- 1056000 39
1132800 40
- 1209600 42
- 1286400 43
1363200 44
- 1459200 56
- 1536000 58
- 1612800 60
- 1689600 62
- 1766400 64
+ 1563000 58
+ 1747200 64
1843200 65
- 1920000 67
1996800 69
- 2092800 87
+ 2054400 87
2169600 90
- 2246400 92
- 2323200 94
+ 2208000 92
+ 2361600 94
2400000 117
+ 2457600 120
+ 2515200 130
+ 2611200 140
>;
idle-cost-data = <
4 3 2 1
diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig
index cdfa1eb..0300ef5 100644
--- a/arch/arm64/configs/sdm845-perf_defconfig
+++ b/arch/arm64/configs/sdm845-perf_defconfig
@@ -7,6 +7,9 @@
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_SCHED_WALT=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_RCU_EXPERT=y
CONFIG_RCU_FAST_NO_HZ=y
CONFIG_RCU_NOCB_CPU=y
@@ -237,6 +240,7 @@
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_QSEECOM=y
+CONFIG_UID_SYS_STATS=y
CONFIG_MEMORY_STATE_TIME=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 6f76e20..8f80e99 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -1432,7 +1432,7 @@
* _sde_crtc_blend_setup - configure crtc mixers
* @crtc: Pointer to drm crtc structure
*/
-static void _sde_crtc_blend_setup(struct drm_crtc *crtc)
+static void _sde_crtc_blend_setup(struct drm_crtc *crtc, bool add_planes)
{
struct sde_crtc *sde_crtc;
struct sde_crtc_state *sde_crtc_state;
@@ -1478,7 +1478,8 @@
/* initialize stage cfg */
memset(&sde_crtc->stage_cfg, 0, sizeof(struct sde_hw_stage_cfg));
- _sde_crtc_blend_setup_mixer(crtc, sde_crtc, mixer);
+ if (add_planes)
+ _sde_crtc_blend_setup_mixer(crtc, sde_crtc, mixer);
for (i = 0; i < sde_crtc->num_mixers; i++) {
const struct sde_rect *lm_roi = &sde_crtc_state->lm_roi[i];
@@ -3093,7 +3094,7 @@
if (unlikely(!sde_crtc->num_mixers))
return;
- _sde_crtc_blend_setup(crtc);
+ _sde_crtc_blend_setup(crtc, true);
_sde_crtc_dest_scaler_setup(crtc);
/*
@@ -3384,7 +3385,104 @@
}
}
-void sde_crtc_commit_kickoff(struct drm_crtc *crtc)
+/**
+ * _sde_crtc_reset_hw - attempt hardware reset on errors
+ * @crtc: Pointer to DRM crtc instance
+ * @old_state: Pointer to crtc state for previous commit
+ * Returns: Zero if current commit should still be attempted
+ */
+static int _sde_crtc_reset_hw(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+ struct drm_plane *plane_halt[MAX_PLANES];
+ struct drm_plane *plane;
+ const struct drm_plane_state *pstate;
+ struct sde_crtc *sde_crtc;
+ struct sde_hw_ctl *ctl;
+ signed int i, plane_count;
+ int rc;
+
+ if (!crtc || !old_state)
+ return -EINVAL;
+ sde_crtc = to_sde_crtc(crtc);
+
+ for (i = 0; i < sde_crtc->num_mixers; ++i) {
+ ctl = sde_crtc->mixers[i].hw_ctl;
+ if (!ctl || !ctl->ops.reset)
+ continue;
+
+ rc = ctl->ops.reset(ctl);
+ if (rc) {
+ SDE_DEBUG("crtc%d: ctl%d reset failure\n",
+ crtc->base.id, ctl->idx - CTL_0);
+ SDE_EVT32(DRMID(crtc), ctl->idx - CTL_0,
+ SDE_EVTLOG_ERROR);
+ break;
+ }
+ }
+
+ /* early out if simple ctl reset succeeded */
+ if (i == sde_crtc->num_mixers) {
+ SDE_EVT32(DRMID(crtc), i);
+ return false;
+ }
+
+ SDE_DEBUG("crtc%d: issuing hard reset\n", DRMID(crtc));
+
+ /* force all components in the system into reset at the same time */
+ for (i = 0; i < sde_crtc->num_mixers; ++i) {
+ ctl = sde_crtc->mixers[i].hw_ctl;
+ if (!ctl || !ctl->ops.hard_reset)
+ continue;
+
+ SDE_EVT32(DRMID(crtc), ctl->idx - CTL_0);
+ ctl->ops.hard_reset(ctl, true);
+ }
+
+ plane_count = 0;
+ drm_atomic_crtc_state_for_each_plane(plane, old_state) {
+ if (plane_count >= ARRAY_SIZE(plane_halt))
+ break;
+
+ plane_halt[plane_count++] = plane;
+ sde_plane_halt_requests(plane, true);
+ sde_plane_set_revalidate(plane, true);
+ }
+
+ /* reset both previous... */
+ for_each_plane_in_state(old_state->state, plane, pstate, i) {
+ if (pstate->crtc != crtc)
+ continue;
+
+ sde_plane_reset_rot(plane, (struct drm_plane_state *)pstate);
+ }
+
+ /* ...and current rotation attempts, if applicable */
+ drm_atomic_crtc_for_each_plane(plane, crtc) {
+ pstate = plane->state;
+ if (!pstate)
+ continue;
+
+ sde_plane_reset_rot(plane, (struct drm_plane_state *)pstate);
+ }
+
+ /* take h/w components out of reset */
+ for (i = plane_count - 1; i >= 0; --i)
+ sde_plane_halt_requests(plane_halt[i], false);
+
+ for (i = 0; i < sde_crtc->num_mixers; ++i) {
+ ctl = sde_crtc->mixers[i].hw_ctl;
+ if (!ctl || !ctl->ops.hard_reset)
+ continue;
+
+ ctl->ops.hard_reset(ctl, false);
+ }
+
+ return -EAGAIN;
+}
+
+void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_encoder *encoder;
struct drm_device *dev;
@@ -3392,7 +3490,7 @@
struct msm_drm_private *priv;
struct sde_kms *sde_kms;
struct sde_crtc_state *cstate;
- bool is_error;
+ bool is_error, reset_req;
int ret;
if (!crtc) {
@@ -3403,6 +3501,7 @@
sde_crtc = to_sde_crtc(crtc);
sde_kms = _sde_crtc_get_kms(crtc);
is_error = false;
+ reset_req = false;
if (!sde_kms || !sde_kms->dev || !sde_kms->dev->dev_private) {
SDE_ERROR("invalid argument\n");
@@ -3439,7 +3538,8 @@
params.inline_rotate_prefill = cstate->sbuf_prefill_line;
params.affected_displays = _sde_crtc_get_displays_affected(crtc,
crtc->state);
- sde_encoder_prepare_for_kickoff(encoder, ¶ms);
+ if (sde_encoder_prepare_for_kickoff(encoder, ¶ms))
+ reset_req = true;
/*
* For inline ASYNC modes, the flush bits are not written
@@ -3462,6 +3562,20 @@
if (_sde_crtc_commit_kickoff_rot(crtc, cstate))
is_error = true;
+ /*
+ * Optionally attempt h/w recovery if any errors were detected while
+ * preparing for the kickoff
+ */
+ if (reset_req) {
+ if (_sde_crtc_reset_hw(crtc, old_state))
+ is_error = true;
+
+ /* force offline rotation mode since the commit has no pipes */
+ if (is_error)
+ cstate->sbuf_cfg.rot_op_mode =
+ SDE_CTL_ROT_OP_MODE_OFFLINE;
+ }
+
/* wait for frame_event_done completion */
SDE_ATRACE_BEGIN("wait_for_frame_done_event");
ret = _sde_crtc_wait_for_frame_done(crtc);
@@ -3502,14 +3616,16 @@
sde_vbif_clear_errors(sde_kms);
- if (is_error)
+ if (is_error) {
_sde_crtc_remove_pipe_flush(sde_crtc);
+ _sde_crtc_blend_setup(crtc, false);
+ }
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->crtc != crtc)
continue;
- sde_encoder_kickoff(encoder, is_error);
+ sde_encoder_kickoff(encoder, false);
}
reinit_completion(&sde_crtc->frame_done_comp);
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
index 704095a..cdf2ed1 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.h
@@ -508,8 +508,10 @@
/**
* sde_crtc_commit_kickoff - trigger kickoff of the commit for this crtc
* @crtc: Pointer to drm crtc object
+ * @old_state: Pointer to drm crtc old state object
*/
-void sde_crtc_commit_kickoff(struct drm_crtc *crtc);
+void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state);
/**
* sde_crtc_prepare_commit - callback to prepare for output fences
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 8855859..1616705 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -2466,11 +2466,12 @@
phys->ops.trigger_flush(phys);
if (ctl->ops.get_pending_flush)
- SDE_EVT32(DRMID(drm_enc), phys->intf_idx, pending_kickoff_cnt,
- ctl->idx, ctl->ops.get_pending_flush(ctl));
+ SDE_EVT32(DRMID(drm_enc), phys->intf_idx - INTF_0,
+ pending_kickoff_cnt, ctl->idx - CTL_0,
+ ctl->ops.get_pending_flush(ctl));
else
- SDE_EVT32(DRMID(drm_enc), phys->intf_idx, ctl->idx,
- pending_kickoff_cnt);
+ SDE_EVT32(DRMID(drm_enc), phys->intf_idx - INTF_0,
+ ctl->idx - CTL_0, pending_kickoff_cnt);
}
/**
@@ -2529,7 +2530,7 @@
ctl = phys_enc->hw_ctl;
if (ctl && ctl->ops.trigger_start) {
ctl->ops.trigger_start(ctl);
- SDE_EVT32(DRMID(phys_enc->parent), ctl->idx);
+ SDE_EVT32(DRMID(phys_enc->parent), ctl->idx - CTL_0);
}
}
@@ -2594,12 +2595,6 @@
}
}
- rc = ctl->ops.reset(ctl);
- if (rc) {
- SDE_ERROR_ENC(sde_enc, "ctl %d reset failure\n", ctl->idx);
- SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
- }
-
phys_enc->enable_state = SDE_ENC_ENABLED;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
index 0777e9c..d00400d 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
@@ -296,6 +296,7 @@
* @hw_intf: Hardware interface to the intf registers
* @timing_params: Current timing parameter
* @rot_fetch: Prefill for inline rotation
+ * @error_count: Number of consecutive kickoffs that experienced an error
* @rot_fetch_valid: true if rot_fetch is updated (reset in enc enable)
*/
struct sde_encoder_phys_vid {
@@ -303,6 +304,7 @@
struct sde_hw_intf *hw_intf;
struct intf_timing_params timing_params;
struct intf_prog_fetch rot_fetch;
+ int error_count;
bool rot_fetch_valid;
};
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 cb73904..164f2e1 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
@@ -32,7 +32,7 @@
#define to_sde_encoder_phys_cmd(x) \
container_of(x, struct sde_encoder_phys_cmd, base)
-#define PP_TIMEOUT_MAX_TRIALS 10
+#define PP_TIMEOUT_MAX_TRIALS 2
/*
* Tearcheck sync start and continue thresholds are empirically found
@@ -418,26 +418,26 @@
to_sde_encoder_phys_cmd(phys_enc);
u32 frame_event = SDE_ENCODER_FRAME_EVENT_ERROR
| SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE;
- bool do_log = false;
if (!phys_enc || !phys_enc->hw_pp || !phys_enc->hw_ctl)
return -EINVAL;
cmd_enc->pp_timeout_report_cnt++;
- if (cmd_enc->pp_timeout_report_cnt == PP_TIMEOUT_MAX_TRIALS) {
- frame_event |= SDE_ENCODER_FRAME_EVENT_PANEL_DEAD;
- do_log = true;
- } else if (cmd_enc->pp_timeout_report_cnt == 1) {
- do_log = true;
- }
SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
cmd_enc->pp_timeout_report_cnt,
atomic_read(&phys_enc->pending_kickoff_cnt),
frame_event);
- /* to avoid flooding, only log first time, and "dead" time */
- if (do_log) {
+ if (cmd_enc->pp_timeout_report_cnt >= PP_TIMEOUT_MAX_TRIALS) {
+ cmd_enc->pp_timeout_report_cnt = PP_TIMEOUT_MAX_TRIALS;
+ frame_event |= SDE_ENCODER_FRAME_EVENT_PANEL_DEAD;
+
+ sde_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR);
+ SDE_DBG_DUMP("panic");
+ sde_encoder_helper_register_irq(phys_enc, INTR_IDX_RDPTR);
+ } else if (cmd_enc->pp_timeout_report_cnt == 1) {
+ /* to avoid flooding, only log first time, and "dead" time */
SDE_ERROR_CMDENC(cmd_enc,
"pp:%d kickoff timed out ctl %d cnt %d koff_cnt %d\n",
phys_enc->hw_pp->idx - PINGPONG_0,
@@ -448,7 +448,8 @@
SDE_EVT32(DRMID(phys_enc->parent), SDE_EVTLOG_FATAL);
sde_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR);
- SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
+ SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus");
+ sde_encoder_helper_register_irq(phys_enc, INTR_IDX_RDPTR);
}
atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
index 8076319..eef249a 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
@@ -33,6 +33,9 @@
#define to_sde_encoder_phys_vid(x) \
container_of(x, struct sde_encoder_phys_vid, base)
+/* maximum number of consecutive kickoff errors */
+#define KICKOFF_MAX_ERRORS 2
+
static bool sde_encoder_phys_vid_is_master(
struct sde_encoder_phys *phys_enc)
{
@@ -789,8 +792,30 @@
if (rc) {
SDE_ERROR_VIDENC(vid_enc, "ctl %d reset failure: %d\n",
ctl->idx, rc);
- sde_encoder_helper_unregister_irq(phys_enc, INTR_IDX_VSYNC);
- SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus", "panic");
+
+ ++vid_enc->error_count;
+ if (vid_enc->error_count >= KICKOFF_MAX_ERRORS) {
+ vid_enc->error_count = KICKOFF_MAX_ERRORS;
+
+ sde_encoder_helper_unregister_irq(
+ phys_enc, INTR_IDX_VSYNC);
+ SDE_DBG_DUMP("panic");
+ sde_encoder_helper_register_irq(
+ phys_enc, INTR_IDX_VSYNC);
+ } else if (vid_enc->error_count == 1) {
+ SDE_EVT32(DRMID(phys_enc->parent), SDE_EVTLOG_FATAL);
+
+ sde_encoder_helper_unregister_irq(
+ phys_enc, INTR_IDX_VSYNC);
+ SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus");
+ sde_encoder_helper_register_irq(
+ phys_enc, INTR_IDX_VSYNC);
+ }
+
+ /* request a ctl reset before the next flush */
+ phys_enc->enable_state = SDE_ENC_ERR_NEEDS_HW_RESET;
+ } else {
+ vid_enc->error_count = 0;
}
programmable_rot_fetch_config(phys_enc, params->inline_rotate_prefill);
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
index 88f821d..ea4ca4f 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
@@ -30,6 +30,7 @@
#define CTL_START 0x01C
#define CTL_PREPARE 0x0d0
#define CTL_SW_RESET 0x030
+#define CTL_SW_RESET_OVERRIDE 0x060
#define CTL_LAYER_EXTN_OFFSET 0x40
#define CTL_ROT_TOP 0x0C0
#define CTL_ROT_FLUSH 0x0C4
@@ -345,7 +346,7 @@
{
struct sde_hw_blk_reg_map *c = &ctx->hw;
- pr_debug("issuing hw ctl reset for ctl:%d\n", ctx->idx);
+ pr_debug("issuing hw ctl reset for ctl:%d\n", ctx->idx - CTL_0);
SDE_REG_WRITE(c, CTL_SW_RESET, 0x1);
if (sde_hw_ctl_poll_reset_status(ctx, SDE_REG_RESET_TIMEOUT_US))
return -EINVAL;
@@ -353,6 +354,15 @@
return 0;
}
+static void sde_hw_ctl_hard_reset(struct sde_hw_ctl *ctx, bool enable)
+{
+ struct sde_hw_blk_reg_map *c = &ctx->hw;
+
+ pr_debug("hw ctl hard reset for ctl:%d, %d\n",
+ ctx->idx - CTL_0, enable);
+ SDE_REG_WRITE(c, CTL_SW_RESET_OVERRIDE, enable);
+}
+
static int sde_hw_ctl_wait_reset_status(struct sde_hw_ctl *ctx)
{
struct sde_hw_blk_reg_map *c = &ctx->hw;
@@ -586,6 +596,7 @@
ops->trigger_pending = sde_hw_ctl_trigger_pending;
ops->setup_intf_cfg = sde_hw_ctl_intf_cfg;
ops->reset = sde_hw_ctl_reset_control;
+ ops->hard_reset = sde_hw_ctl_hard_reset;
ops->wait_reset_status = sde_hw_ctl_wait_reset_status;
ops->clear_all_blendstages = sde_hw_ctl_clear_all_blendstages;
ops->setup_blendstage = sde_hw_ctl_setup_blendstage;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_ctl.h b/drivers/gpu/drm/msm/sde/sde_hw_ctl.h
index bad80f0..fe4e194 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_ctl.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_ctl.h
@@ -152,6 +152,13 @@
int (*reset)(struct sde_hw_ctl *c);
+ /**
+ * hard_reset - force reset on ctl_path
+ * @ctx : ctl path ctx pointer
+ * @enable : whether to enable/disable hard reset
+ */
+ void (*hard_reset)(struct sde_hw_ctl *c, bool enable);
+
/*
* wait_reset_status - checks ctl reset status
* @ctx : ctl path ctx pointer
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index c2fe10a..f6f04fd 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -532,7 +532,7 @@
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
if (crtc->state->active) {
SDE_EVT32(DRMID(crtc));
- sde_crtc_commit_kickoff(crtc);
+ sde_crtc_commit_kickoff(crtc, old_crtc_state);
}
}
}
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index 8aab213..2faceea 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -4473,15 +4473,6 @@
return ret;
}
-static int sde_plane_set_property(struct drm_plane *plane,
- struct drm_property *property, uint64_t val)
-{
- SDE_DEBUG("\n");
-
- return sde_plane_atomic_set_property(plane,
- plane->state, property, val);
-}
-
static int sde_plane_atomic_get_property(struct drm_plane *plane,
const struct drm_plane_state *state,
struct drm_property *property, uint64_t *val)
@@ -4885,7 +4876,7 @@
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = sde_plane_destroy,
- .set_property = sde_plane_set_property,
+ .set_property = drm_atomic_helper_plane_set_property,
.atomic_set_property = sde_plane_atomic_set_property,
.atomic_get_property = sde_plane_atomic_get_property,
.reset = sde_plane_reset,
diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c
index 7f9a797..4b900e2 100644
--- a/drivers/power/supply/qcom/battery.c
+++ b/drivers/power/supply/qcom/battery.c
@@ -61,6 +61,7 @@
struct delayed_work status_change_work;
struct work_struct pl_disable_forever_work;
struct work_struct pl_taper_work;
+ struct delayed_work pl_awake_work;
bool taper_work_running;
struct power_supply *main_psy;
struct power_supply *pl_psy;
@@ -568,6 +569,14 @@
vote(chip->hvdcp_hw_inov_dis_votable, PL_VOTER, false, 0);
}
+static void pl_awake_work(struct work_struct *work)
+{
+ struct pl_data *chip = container_of(work,
+ struct pl_data, pl_awake_work.work);
+
+ vote(chip->pl_awake_votable, PL_VOTER, false, 0);
+}
+
static bool is_main_available(struct pl_data *chip)
{
if (chip->main_psy)
@@ -595,6 +604,10 @@
total_fcc_ua = get_effective_result_locked(chip->fcc_votable);
if (chip->pl_mode != POWER_SUPPLY_PL_NONE && !pl_disable) {
+ /* keep system awake to talk to slave charger through i2c */
+ cancel_delayed_work_sync(&chip->pl_awake_work);
+ vote(chip->pl_awake_votable, PL_VOTER, true, 0);
+
/* enable parallel charging */
rc = power_supply_get_property(chip->pl_psy,
POWER_SUPPLY_PROP_CHARGE_TYPE, &pval);
@@ -698,6 +711,10 @@
}
rerun_election(chip->fv_votable);
+
+ cancel_delayed_work_sync(&chip->pl_awake_work);
+ schedule_delayed_work(&chip->pl_awake_work,
+ msecs_to_jiffies(5000));
}
pl_dbg(chip, PR_PARALLEL, "parallel charging %s\n",
@@ -1075,6 +1092,7 @@
INIT_DELAYED_WORK(&chip->status_change_work, status_change_work);
INIT_WORK(&chip->pl_taper_work, pl_taper_work);
INIT_WORK(&chip->pl_disable_forever_work, pl_disable_forever_work);
+ INIT_DELAYED_WORK(&chip->pl_awake_work, pl_awake_work);
rc = pl_register_notifier(chip);
if (rc < 0) {
@@ -1128,6 +1146,7 @@
cancel_delayed_work_sync(&chip->status_change_work);
cancel_work_sync(&chip->pl_taper_work);
cancel_work_sync(&chip->pl_disable_forever_work);
+ cancel_delayed_work_sync(&chip->pl_awake_work);
power_supply_unreg_notifier(&chip->nb);
destroy_votable(chip->pl_enable_votable_indirect);
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 84a52db..f1d4ca2 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -372,6 +372,14 @@
}
EXPORT_SYMBOL_GPL(rtc_set_alarm);
+static void rtc_alarm_disable(struct rtc_device *rtc)
+{
+ if (!rtc->ops || !rtc->ops->alarm_irq_enable)
+ return;
+
+ rtc->ops->alarm_irq_enable(rtc->dev.parent, false);
+}
+
/* Called once per device from rtc_device_register */
int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
@@ -399,7 +407,11 @@
rtc->aie_timer.enabled = 1;
timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node);
+ } else if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 >=
+ rtc->aie_timer.node.expires.tv64)){
+ rtc_alarm_disable(rtc);
}
+
mutex_unlock(&rtc->ops_lock);
return err;
}
@@ -790,14 +802,6 @@
return 0;
}
-static void rtc_alarm_disable(struct rtc_device *rtc)
-{
- if (!rtc->ops || !rtc->ops->alarm_irq_enable)
- return;
-
- rtc->ops->alarm_irq_enable(rtc->dev.parent, false);
-}
-
/**
* rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue
* @rtc rtc device
diff --git a/drivers/soc/qcom/qbt1000.c b/drivers/soc/qcom/qbt1000.c
index e4ada03..86f314a 100644
--- a/drivers/soc/qcom/qbt1000.c
+++ b/drivers/soc/qcom/qbt1000.c
@@ -150,18 +150,17 @@
uint32_t *rsp_len)
{
/* 64 bytes alignment for QSEECOM */
- *cmd_len = ALIGN(*cmd_len, 64);
- *rsp_len = ALIGN(*rsp_len, 64);
+ uint64_t aligned_cmd_len = ALIGN((uint64_t)*cmd_len, 64);
+ uint64_t aligned_rsp_len = ALIGN((uint64_t)*rsp_len, 64);
- if (((uint64_t)*rsp_len + (uint64_t)*cmd_len)
- > (uint64_t)g_app_buf_size) {
- pr_err("buffer too small to hold cmd=%d and rsp=%d\n",
- *cmd_len, *rsp_len);
+ if ((aligned_rsp_len + aligned_cmd_len) > (uint64_t)g_app_buf_size)
return -ENOMEM;
- }
*cmd = hdl->sbuf;
+ *cmd_len = aligned_cmd_len;
*rsp = hdl->sbuf + *cmd_len;
+ *rsp_len = aligned_rsp_len;
+
return 0;
}
@@ -318,6 +317,12 @@
drvdata = file->private_data;
+ if (IS_ERR(priv_arg)) {
+ dev_err(drvdata->dev, "%s: invalid user space pointer %lu\n",
+ __func__, arg);
+ return -EINVAL;
+ }
+
mutex_lock(&drvdata->mutex);
pr_debug("qbt1000_ioctl %d\n", cmd);
@@ -362,6 +367,7 @@
}
pr_debug("app %s load before\n", app.name);
+ app.name[MAX_NAME_SIZE - 1] = '\0';
/* start the TZ app */
rc = qseecom_start_app(
@@ -375,7 +381,8 @@
pr_err("App %s failed to set bw\n", app.name);
}
} else {
- pr_err("app %s failed to load\n", app.name);
+ dev_err(drvdata->dev, "%s: Fingerprint Trusted App failed to load\n",
+ __func__);
goto end;
}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index f4f378c..4f4f7e8 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1436,6 +1436,48 @@
if (r == req) {
/* wait until it is processed */
dwc3_stop_active_transfer(dwc, dep->number, true);
+
+ /*
+ * If request was already started, this means we had to
+ * stop the transfer. With that we also need to ignore
+ * all TRBs used by the request, however TRBs can only
+ * be modified after completion of END_TRANSFER
+ * command. So what we do here is that we wait for
+ * END_TRANSFER completion and only after that, we jump
+ * over TRBs by clearing HWO and incrementing dequeue
+ * pointer.
+ *
+ * Note that we have 2 possible types of transfers here:
+ *
+ * i) Linear buffer request
+ * ii) SG-list based request
+ *
+ * SG-list based requests will have r->num_pending_sgs
+ * set to a valid number (> 0). Linear requests,
+ * normally use a single TRB.
+ *
+ * All of these cases need to be taken into
+ * consideration so we don't mess up our TRB ring
+ * pointers.
+ */
+ if (!r->trb)
+ goto out1;
+
+ if (r->num_pending_sgs) {
+ struct dwc3_trb *trb;
+ int i = 0;
+
+ for (i = 0; i < r->num_pending_sgs; i++) {
+ trb = r->trb + i;
+ trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
+ dwc3_ep_inc_deq(dep);
+ }
+ } else {
+ struct dwc3_trb *trb = r->trb;
+
+ trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
+ dwc3_ep_inc_deq(dep);
+ }
goto out1;
}
dev_err(dwc->dev, "request %pK was not queued to %s\n",
@@ -1447,6 +1489,7 @@
out1:
dbg_event(dep->number, "DEQUEUE", 0);
/* giveback the request */
+ dep->queued_requests--;
dwc3_gadget_giveback(dep, req, -ECONNRESET);
out0:
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c
index b513446..05ae01e 100644
--- a/kernel/time/tick-oneshot.c
+++ b/kernel/time/tick-oneshot.c
@@ -33,6 +33,7 @@
* We don't need the clock event device any more, stop it.
*/
clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT_STOPPED);
+ dev->next_event.tv64 = KTIME_MAX;
return 0;
}