History

Merge https://gitlab.freedesktop.org/drm/msm into drm-next

On the display side, cleanups and fixes to enabled modifiers (QCOM_COMPRESSED). And otherwise mostly misc fixes all around.

Dave Airlie committed 7 years ago

Commit a5f2faf2 parents 71f4e45 860433e29 files · +399 −873Browse files

Unified · Split

29 files
  1. Documentation/devicetree/bindings/display/msm/gmu.txt +59 −0
  2. Documentation/devicetree/bindings/display/msm/gpu.txt +39 −3
  3. MAINTAINERS +2 −1
  4. drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +2 −7
  5. drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +0 −2
  6. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +10 −22
  7. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +1 −12
  8. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +1 −2
  9. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +2 −3
  10. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +2 −3
  11. drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c +2 −35
  12. drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h +0 −14
  13. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +4 −0
  14. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +6 −13
  15. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h +72 −148
  16. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +0 −44
  17. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h +0 −44
  18. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +0 −7
  19. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +0 −1
  20. drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +36 −29
  21. drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +21 −15
  22. drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +34 −17
  23. drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h +0 −27
  24. drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +46 −279
  25. drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +1 −27
  26. drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +11 −17
  27. drivers/gpu/drm/msm/msm_drv.c +34 −92
  28. drivers/gpu/drm/msm/msm_drv.h +1 −9
  29. include/drm/drm_dp_helper.h +13 −0
Documentation/devicetree/bindings/display/msm/gmu.txt+59−0
@@ -0,0 +1,59 @@
1Qualcomm adreno/snapdragon GMU (Graphics management unit)
2
3The GMU is a programmable power controller for the GPU. the CPU controls the
4GMU which in turn handles power controls for the GPU.
5
6Required properties:
7- compatible: "qcom,adreno-gmu-XYZ.W", "qcom,adreno-gmu"
8 for example: "qcom,adreno-gmu-630.2", "qcom,adreno-gmu"
9 Note that you need to list the less specific "qcom,adreno-gmu"
10 for generic matches and the more specific identifier to identify
11 the specific device.
12- reg: Physical base address and length of the GMU registers.
13- reg-names: Matching names for the register regions
14 * "gmu"
15 * "gmu_pdc"
16 * "gmu_pdc_seg"
17- interrupts: The interrupt signals from the GMU.
18- interrupt-names: Matching names for the interrupts
19 * "hfi"
20 * "gmu"
21- clocks: phandles to the device clocks
22- clock-names: Matching names for the clocks
23 * "gmu"
24 * "cxo"
25 * "axi"
26 * "mnoc"
27- power-domains: should be <&clock_gpucc GPU_CX_GDSC>
28- iommus: phandle to the adreno iommu
29- operating-points-v2: phandle to the OPP operating points
30
31Example:
32
33/ {
34 ...
35
36 gmu: gmu@506a000 {
37 compatible="qcom,adreno-gmu-630.2", "qcom,adreno-gmu";
38
39 reg = <0x506a000 0x30000>,
40 <0xb280000 0x10000>,
41 <0xb480000 0x10000>;
42 reg-names = "gmu", "gmu_pdc", "gmu_pdc_seq";
43
44 interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
45 <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
46 interrupt-names = "hfi", "gmu";
47
48 clocks = <&gpucc GPU_CC_CX_GMU_CLK>,
49 <&gpucc GPU_CC_CXO_CLK>,
50 <&gcc GCC_DDRSS_GPU_AXI_CLK>,
51 <&gcc GCC_GPU_MEMNOC_GFX_CLK>;
52 clock-names = "gmu", "cxo", "axi", "memnoc";
53
54 power-domains = <&gpucc GPU_CX_GDSC>;
55 iommus = <&adreno_smmu 5>;
56
57 operating-points-v2 = <&gmu_opp_table>;
58 };
59};
Documentation/devicetree/bindings/display/msm/gpu.txt+39−3
@@ -10,14 +10,23 @@ Required properties: · 9 unmodified lines
10 If "amd,imageon" is used, there should be no top level msm device.10 If "amd,imageon" is used, there should be no top level msm device.
11- reg: Physical base address and length of the controller's registers.11- reg: Physical base address and length of the controller's registers.
12- interrupts: The interrupt signal from the gpu.12- interrupts: The interrupt signal from the gpu.
13- clocks: device clocks13- clocks: device clocks (if applicable)
14 See ../clocks/clock-bindings.txt for details.14 See ../clocks/clock-bindings.txt for details.
15- clock-names: the following clocks are required:15- clock-names: the following clocks are required by a3xx, a4xx and a5xx
16 cores:
16 * "core"17 * "core"
17 * "iface"18 * "iface"
18 * "mem_iface"19 * "mem_iface"
20 For GMU attached devices the GPU clocks are not used and are not required. The
21 following devices should not list clocks:
22 - qcom,adreno-630.2
23- iommus: optional phandle to an adreno iommu instance
24- operating-points-v2: optional phandle to the OPP operating points
25- qcom,gmu: For GMU attached devices a phandle to the GMU device that will
26 control the power for the GPU. Applicable targets:
27 - qcom,adreno-630.2
19 28
20Example:29Example 3xx/4xx/a5xx:
21 30
22/ {31/ {
23 ...32 ...
@@ -37,3 +46,30 @@ Example: · 13 unmodified lines
37 <&mmcc MMSS_IMEM_AHB_CLK>;46 <&mmcc MMSS_IMEM_AHB_CLK>;
38 };47 };
39};48};
49
50Example a6xx (with GMU):
51
52/ {
53 ...
54
55 gpu@5000000 {
56 compatible = "qcom,adreno-630.2", "qcom,adreno";
57 #stream-id-cells = <16>;
58
59 reg = <0x5000000 0x40000>, <0x509e000 0x10>;
60 reg-names = "kgsl_3d0_reg_memory", "cx_mem";
61
62 /*
63 * Look ma, no clocks! The GPU clocks and power are
64 * controlled entirely by the GMU
65 */
66
67 interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
68
69 iommus = <&adreno_smmu 0>;
70
71 operating-points-v2 = <&gpu_opp_table>;
72
73 qcom,gmu = <&gmu>;
74 };
75};
MAINTAINERS+2−1
@@ -4851,10 +4851,11 @@ F: Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt · 4850 unmodified lines
4851 4851
4852DRM DRIVER FOR MSM ADRENO GPU4852DRM DRIVER FOR MSM ADRENO GPU
4853M: Rob Clark <robdclark@gmail.com>4853M: Rob Clark <robdclark@gmail.com>
4854M: Sean Paul <sean@poorly.run>
4854L: linux-arm-msm@vger.kernel.org4855L: linux-arm-msm@vger.kernel.org
4855L: dri-devel@lists.freedesktop.org4856L: dri-devel@lists.freedesktop.org
4856L: freedreno@lists.freedesktop.org4857L: freedreno@lists.freedesktop.org
4857T: git git://people.freedesktop.org/~robclark/linux4858T: git https://gitlab.freedesktop.org/drm/msm.git
4858S: Maintained4859S: Maintained
4859F: drivers/gpu/drm/msm/4860F: drivers/gpu/drm/msm/
4860F: include/uapi/drm/msm_drm.h4861F: include/uapi/drm/msm_drm.h
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c+2−7
@@ -465,8 +465,6 @@ static void _dpu_crtc_setup_mixer_for_encoder( · 464 unmodified lines
465 return;465 return;
466 }466 }
467 467
468 mixer->encoder = enc;
469
470 cstate->num_mixers++;468 cstate->num_mixers++;
471 DPU_DEBUG("setup mixer %d: lm %d\n",469 DPU_DEBUG("setup mixer %d: lm %d\n",
472 i, mixer->hw_lm->idx - LM_0);470 i, mixer->hw_lm->idx - LM_0);
@@ -718,11 +716,8 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) · 245 unmodified lines
718 * may delay and flush at an irq event (e.g. ppdone)716 * may delay and flush at an irq event (e.g. ppdone)
719 */717 */
720 drm_for_each_encoder_mask(encoder, crtc->dev,718 drm_for_each_encoder_mask(encoder, crtc->dev,
721 crtc->state->encoder_mask) {719 crtc->state->encoder_mask)
722 struct dpu_encoder_kickoff_params params = { 0 };720 dpu_encoder_prepare_for_kickoff(encoder, async);
723 dpu_encoder_prepare_for_kickoff(encoder, &params, async);
724 }
725
726 721
727 if (!async) {722 if (!async) {
728 /* wait for frame_event_done completion */723 /* wait for frame_event_done completion */
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h+0−2
@@ -84,14 +84,12 @@ struct dpu_crtc_smmu_state_data { · 83 unmodified lines
84 * struct dpu_crtc_mixer: stores the map for each virtual pipeline in the CRTC84 * struct dpu_crtc_mixer: stores the map for each virtual pipeline in the CRTC
85 * @hw_lm: LM HW Driver context85 * @hw_lm: LM HW Driver context
86 * @lm_ctl: CTL Path HW driver context86 * @lm_ctl: CTL Path HW driver context
87 * @encoder: Encoder attached to this lm & ctl
88 * @mixer_op_mode: mixer blending operation mode87 * @mixer_op_mode: mixer blending operation mode
89 * @flush_mask: mixer flush mask for ctl, mixer and pipe88 * @flush_mask: mixer flush mask for ctl, mixer and pipe
90 */89 */
91struct dpu_crtc_mixer {90struct dpu_crtc_mixer {
92 struct dpu_hw_mixer *hw_lm;91 struct dpu_hw_mixer *hw_lm;
93 struct dpu_hw_ctl *lm_ctl;92 struct dpu_hw_ctl *lm_ctl;
94 struct drm_encoder *encoder;
95 u32 mixer_op_mode;93 u32 mixer_op_mode;
96 u32 flush_mask;94 u32 flush_mask;
97};95};
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c+10−22
@@ -205,7 +205,7 @@ struct dpu_encoder_virt { · 204 unmodified lines
205 bool idle_pc_supported;205 bool idle_pc_supported;
206 struct mutex rc_lock;206 struct mutex rc_lock;
207 enum dpu_enc_rc_states rc_state;207 enum dpu_enc_rc_states rc_state;
208 struct kthread_delayed_work delayed_off_work;208 struct delayed_work delayed_off_work;
209 struct kthread_work vsync_event_work;209 struct kthread_work vsync_event_work;
210 struct msm_display_topology topology;210 struct msm_display_topology topology;
211 bool mode_set_complete;211 bool mode_set_complete;
@@ -742,7 +742,6 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, · 530 unmodified lines
742{742{
743 struct dpu_encoder_virt *dpu_enc;743 struct dpu_encoder_virt *dpu_enc;
744 struct msm_drm_private *priv;744 struct msm_drm_private *priv;
745 struct msm_drm_thread *disp_thread;
746 bool is_vid_mode = false;745 bool is_vid_mode = false;
747 746
748 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||747 if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
@@ -755,12 +754,6 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, · 6 unmodified lines
755 is_vid_mode = dpu_enc->disp_info.capabilities &754 is_vid_mode = dpu_enc->disp_info.capabilities &
756 MSM_DISPLAY_CAP_VID_MODE;755 MSM_DISPLAY_CAP_VID_MODE;
757 756
758 if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
759 DPU_ERROR("invalid crtc index\n");
760 return -EINVAL;
761 }
762 disp_thread = &priv->disp_thread[drm_enc->crtc->index];
763
764 /*757 /*
765 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET758 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET
766 * events and return early for other events (ie wb display).759 * events and return early for other events (ie wb display).
@@ -777,8 +770,7 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, · 10 unmodified lines
777 switch (sw_event) {770 switch (sw_event) {
778 case DPU_ENC_RC_EVENT_KICKOFF:771 case DPU_ENC_RC_EVENT_KICKOFF:
779 /* cancel delayed off work, if any */772 /* cancel delayed off work, if any */
780 if (kthread_cancel_delayed_work_sync(773 if (cancel_delayed_work_sync(&dpu_enc->delayed_off_work))
781 &dpu_enc->delayed_off_work))
782 DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n",774 DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n",
783 sw_event);775 sw_event);
784 776
@@ -837,10 +829,8 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, · 52 unmodified lines
837 return 0;829 return 0;
838 }830 }
839 831
840 kthread_queue_delayed_work(832 queue_delayed_work(priv->wq, &dpu_enc->delayed_off_work,
841 &disp_thread->worker,833 msecs_to_jiffies(dpu_enc->idle_timeout));
842 &dpu_enc->delayed_off_work,
843 msecs_to_jiffies(dpu_enc->idle_timeout));
844 834
845 trace_dpu_enc_rc(DRMID(drm_enc), sw_event,835 trace_dpu_enc_rc(DRMID(drm_enc), sw_event,
846 dpu_enc->idle_pc_supported, dpu_enc->rc_state,836 dpu_enc->idle_pc_supported, dpu_enc->rc_state,
@@ -849,8 +839,7 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, · 2 unmodified lines
849 839
850 case DPU_ENC_RC_EVENT_PRE_STOP:840 case DPU_ENC_RC_EVENT_PRE_STOP:
851 /* cancel delayed off work, if any */841 /* cancel delayed off work, if any */
852 if (kthread_cancel_delayed_work_sync(842 if (cancel_delayed_work_sync(&dpu_enc->delayed_off_work))
853 &dpu_enc->delayed_off_work))
854 DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n",843 DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n",
855 sw_event);844 sw_event);
856 845
@@ -1368,7 +1357,7 @@ static void dpu_encoder_frame_done_callback( · 511 unmodified lines
1368 }1357 }
1369}1358}
1370 1359
1371static void dpu_encoder_off_work(struct kthread_work *work)1360static void dpu_encoder_off_work(struct work_struct *work)
1372{1361{
1373 struct dpu_encoder_virt *dpu_enc = container_of(work,1362 struct dpu_encoder_virt *dpu_enc = container_of(work,
1374 struct dpu_encoder_virt, delayed_off_work.work);1363 struct dpu_encoder_virt, delayed_off_work.work);
@@ -1756,15 +1745,14 @@ static void dpu_encoder_vsync_event_work_handler(struct kthread_work *work) · 381 unmodified lines
1756 nsecs_to_jiffies(ktime_to_ns(wakeup_time)));1745 nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
1757}1746}
1758 1747
1759void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,1748void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, bool async)
1760 struct dpu_encoder_kickoff_params *params, bool async)
1761{1749{
1762 struct dpu_encoder_virt *dpu_enc;1750 struct dpu_encoder_virt *dpu_enc;
1763 struct dpu_encoder_phys *phys;1751 struct dpu_encoder_phys *phys;
1764 bool needs_hw_reset = false;1752 bool needs_hw_reset = false;
1765 unsigned int i;1753 unsigned int i;
1766 1754
1767 if (!drm_enc || !params) {1755 if (!drm_enc) {
1768 DPU_ERROR("invalid args\n");1756 DPU_ERROR("invalid args\n");
1769 return;1757 return;
1770 }1758 }
@@ -1778,7 +1766,7 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, · 7 unmodified lines
1778 phys = dpu_enc->phys_encs[i];1766 phys = dpu_enc->phys_encs[i];
1779 if (phys) {1767 if (phys) {
1780 if (phys->ops.prepare_for_kickoff)1768 if (phys->ops.prepare_for_kickoff)
1781 phys->ops.prepare_for_kickoff(phys, params);1769 phys->ops.prepare_for_kickoff(phys);
1782 if (phys->enable_state == DPU_ENC_ERR_NEEDS_HW_RESET)1770 if (phys->enable_state == DPU_ENC_ERR_NEEDS_HW_RESET)
1783 needs_hw_reset = true;1771 needs_hw_reset = true;
1784 }1772 }
@@ -2193,7 +2181,7 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, · 408 unmodified lines
2193 2181
2194 2182
2195 mutex_init(&dpu_enc->rc_lock);2183 mutex_init(&dpu_enc->rc_lock);
2196 kthread_init_delayed_work(&dpu_enc->delayed_off_work,2184 INIT_DELAYED_WORK(&dpu_enc->delayed_off_work,
2197 dpu_encoder_off_work);2185 dpu_encoder_off_work);
2198 dpu_enc->idle_timeout = IDLE_TIMEOUT;2186 dpu_enc->idle_timeout = IDLE_TIMEOUT;
2199 2187
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h+1−12
@@ -37,15 +37,6 @@ struct dpu_encoder_hw_resources { · 36 unmodified lines
37 enum dpu_intf_mode intfs[INTF_MAX];37 enum dpu_intf_mode intfs[INTF_MAX];
38};38};
39 39
40/**
41 * dpu_encoder_kickoff_params - info encoder requires at kickoff
42 * @affected_displays: bitmask, bit set means the ROI of the commit lies within
43 * the bounds of the physical display at the bit index
44 */
45struct dpu_encoder_kickoff_params {
46 unsigned long affected_displays;
47};
48
49/**40/**
50 * dpu_encoder_get_hw_resources - Populate table of required hardware resources41 * dpu_encoder_get_hw_resources - Populate table of required hardware resources
51 * @encoder: encoder pointer42 * @encoder: encoder pointer
@@ -88,11 +79,9 @@ void dpu_encoder_register_frame_event_callback(struct drm_encoder *encoder, · 36 unmodified lines
88 * Immediately: if no previous commit is outstanding.79 * Immediately: if no previous commit is outstanding.
89 * Delayed: Block until next trigger can be issued.80 * Delayed: Block until next trigger can be issued.
90 * @encoder: encoder pointer81 * @encoder: encoder pointer
91 * @params: kickoff time parameters
92 * @async: true if this is an asynchronous commit82 * @async: true if this is an asynchronous commit
93 */83 */
94void dpu_encoder_prepare_for_kickoff(struct drm_encoder *encoder,84void dpu_encoder_prepare_for_kickoff(struct drm_encoder *encoder, bool async);
95 struct dpu_encoder_kickoff_params *params, bool async);
96 85
97/**86/**
98 * dpu_encoder_trigger_kickoff_pending - Clear the flush bits from previous87 * dpu_encoder_trigger_kickoff_pending - Clear the flush bits from previous
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h+1−2
@@ -144,8 +144,7 @@ struct dpu_encoder_phys_ops { · 143 unmodified lines
144 int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc);144 int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc);
145 int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc);145 int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc);
146 int (*wait_for_vblank)(struct dpu_encoder_phys *phys_enc);146 int (*wait_for_vblank)(struct dpu_encoder_phys *phys_enc);
147 void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc,147 void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc);
148 struct dpu_encoder_kickoff_params *params);
149 void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc);148 void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc);
150 void (*trigger_start)(struct dpu_encoder_phys *phys_enc);149 void (*trigger_start)(struct dpu_encoder_phys *phys_enc);
151 bool (*needs_single_flush)(struct dpu_encoder_phys *phys_enc);150 bool (*needs_single_flush)(struct dpu_encoder_phys *phys_enc);
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c+2−3
@@ -594,8 +594,7 @@ static void dpu_encoder_phys_cmd_get_hw_resources( · 593 unmodified lines
594}594}
595 595
596static void dpu_encoder_phys_cmd_prepare_for_kickoff(596static void dpu_encoder_phys_cmd_prepare_for_kickoff(
597 struct dpu_encoder_phys *phys_enc,597 struct dpu_encoder_phys *phys_enc)
598 struct dpu_encoder_kickoff_params *params)
599{598{
600 struct dpu_encoder_phys_cmd *cmd_enc =599 struct dpu_encoder_phys_cmd *cmd_enc =
601 to_dpu_encoder_phys_cmd(phys_enc);600 to_dpu_encoder_phys_cmd(phys_enc);
@@ -693,7 +692,7 @@ static int dpu_encoder_phys_cmd_wait_for_commit_done( · 91 unmodified lines
693 692
694 /* required for both controllers */693 /* required for both controllers */
695 if (!rc && cmd_enc->serialize_wait4pp)694 if (!rc && cmd_enc->serialize_wait4pp)
696 dpu_encoder_phys_cmd_prepare_for_kickoff(phys_enc, NULL);695 dpu_encoder_phys_cmd_prepare_for_kickoff(phys_enc);
697 696
698 return rc;697 return rc;
699}698}
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c+2−3
@@ -587,14 +587,13 @@ static int dpu_encoder_phys_vid_wait_for_vblank( · 586 unmodified lines
587}587}
588 588
589static void dpu_encoder_phys_vid_prepare_for_kickoff(589static void dpu_encoder_phys_vid_prepare_for_kickoff(
590 struct dpu_encoder_phys *phys_enc,590 struct dpu_encoder_phys *phys_enc)
591 struct dpu_encoder_kickoff_params *params)
592{591{
593 struct dpu_encoder_phys_vid *vid_enc;592 struct dpu_encoder_phys_vid *vid_enc;
594 struct dpu_hw_ctl *ctl;593 struct dpu_hw_ctl *ctl;
595 int rc;594 int rc;
596 595
597 if (!phys_enc || !params) {596 if (!phys_enc) {
598 DPU_ERROR("invalid encoder/parameters\n");597 DPU_ERROR("invalid encoder/parameters\n");
599 return;598 return;
600 }599 }
drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c+2−35
@@ -263,13 +263,13 @@ static const struct dpu_format dpu_format_map[] = { · 262 unmodified lines
263 263
264 INTERLEAVED_RGB_FMT(RGB565,264 INTERLEAVED_RGB_FMT(RGB565,
265 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,265 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
266 C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,266 C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
267 false, 2, 0,267 false, 2, 0,
268 DPU_FETCH_LINEAR, 1),268 DPU_FETCH_LINEAR, 1),
269 269
270 INTERLEAVED_RGB_FMT(BGR565,270 INTERLEAVED_RGB_FMT(BGR565,
271 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,271 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
272 C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,272 C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
273 false, 2, 0,273 false, 2, 0,
274 DPU_FETCH_LINEAR, 1),274 DPU_FETCH_LINEAR, 1),
275 275
@@ -1137,36 +1137,3 @@ const struct msm_format *dpu_get_msm_format( · 861 unmodified lines
1137 return &fmt->base;1137 return &fmt->base;
1138 return NULL;1138 return NULL;
1139}1139}
1140
1141uint32_t dpu_populate_formats(
1142 const struct dpu_format_extended *format_list,
1143 uint32_t *pixel_formats,
1144 uint64_t *pixel_modifiers,
1145 uint32_t pixel_formats_max)
1146{
1147 uint32_t i, fourcc_format;
1148
1149 if (!format_list || !pixel_formats)
1150 return 0;
1151
1152 for (i = 0, fourcc_format = 0;
1153 format_list->fourcc_format && i < pixel_formats_max;
1154 ++format_list) {
1155 /* verify if listed format is in dpu_format_map? */
1156
1157 /* optionally return modified formats */
1158 if (pixel_modifiers) {
1159 /* assume same modifier for all fb planes */
1160 pixel_formats[i] = format_list->fourcc_format;
1161 pixel_modifiers[i++] = format_list->modifier;
1162 } else {
1163 /* assume base formats grouped together */
1164 if (fourcc_format != format_list->fourcc_format) {
1165 fourcc_format = format_list->fourcc_format;
1166 pixel_formats[i++] = fourcc_format;
1167 }
1168 }
1169 }
1170
1171 return i;
1172}
drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h+0−14
@@ -40,20 +40,6 @@ const struct msm_format *dpu_get_msm_format( · 39 unmodified lines
40 const uint32_t format,40 const uint32_t format,
41 const uint64_t modifiers);41 const uint64_t modifiers);
42 42
43/**
44 * dpu_populate_formats - populate the given array with fourcc codes supported
45 * @format_list: pointer to list of possible formats
46 * @pixel_formats: array to populate with fourcc codes
47 * @pixel_modifiers: array to populate with drm modifiers, can be NULL
48 * @pixel_formats_max: length of pixel formats array
49 * Return: number of elements populated
50 */
51uint32_t dpu_populate_formats(
52 const struct dpu_format_extended *format_list,
53 uint32_t *pixel_formats,
54 uint64_t *pixel_modifiers,
55 uint32_t pixel_formats_max);
56
57/**43/**
58 * dpu_format_check_modified_format - validate format and buffers for44 * dpu_format_check_modified_format - validate format and buffers for
59 * dpu non-standard, i.e. modified format45 * dpu non-standard, i.e. modified format
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c+4−0
@@ -151,7 +151,9 @@ static const struct dpu_sspp_blks_common sdm845_sspp_common = { · 150 unmodified lines
151 .id = DPU_SSPP_CSC_10BIT, \151 .id = DPU_SSPP_CSC_10BIT, \
152 .base = 0x1a00, .len = 0x100,}, \152 .base = 0x1a00, .len = 0x100,}, \
153 .format_list = plane_formats_yuv, \153 .format_list = plane_formats_yuv, \
154 .num_formats = ARRAY_SIZE(plane_formats_yuv), \
154 .virt_format_list = plane_formats, \155 .virt_format_list = plane_formats, \
156 .virt_num_formats = ARRAY_SIZE(plane_formats), \
155 }157 }
156 158
157#define _DMA_SBLK(num, sdma_pri) \159#define _DMA_SBLK(num, sdma_pri) \
@@ -163,7 +165,9 @@ static const struct dpu_sspp_blks_common sdm845_sspp_common = { · 5 unmodified lines
163 .src_blk = {.name = STRCAT("sspp_src_", num), \165 .src_blk = {.name = STRCAT("sspp_src_", num), \
164 .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \166 .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
165 .format_list = plane_formats, \167 .format_list = plane_formats, \
168 .num_formats = ARRAY_SIZE(plane_formats), \
166 .virt_format_list = plane_formats, \169 .virt_format_list = plane_formats, \
170 .virt_num_formats = ARRAY_SIZE(plane_formats), \
167 }171 }
168 172
169static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = _VIG_SBLK("0", 5);173static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = _VIG_SBLK("0", 5);
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h+6−13
@@ -251,17 +251,6 @@ struct dpu_pp_blk { · 250 unmodified lines
251 u32 version;251 u32 version;
252};252};
253 253
254/**
255 * struct dpu_format_extended - define dpu specific pixel format+modifier
256 * @fourcc_format: Base FOURCC pixel format code
257 * @modifier: 64-bit drm format modifier, same modifier must be applied to all
258 * framebuffer planes
259 */
260struct dpu_format_extended {
261 uint32_t fourcc_format;
262 uint64_t modifier;
263};
264
265/**254/**
266 * enum dpu_qos_lut_usage - define QoS LUT use cases255 * enum dpu_qos_lut_usage - define QoS LUT use cases
267 */256 */
@@ -348,7 +337,9 @@ struct dpu_sspp_blks_common { · 80 unmodified lines
348 * @pcc_blk:337 * @pcc_blk:
349 * @igc_blk:338 * @igc_blk:
350 * @format_list: Pointer to list of supported formats339 * @format_list: Pointer to list of supported formats
340 * @num_formats: Number of supported formats
351 * @virt_format_list: Pointer to list of supported formats for virtual planes341 * @virt_format_list: Pointer to list of supported formats for virtual planes
342 * @virt_num_formats: Number of supported formats for virtual planes
352 */343 */
353struct dpu_sspp_sub_blks {344struct dpu_sspp_sub_blks {
354 const struct dpu_sspp_blks_common *common;345 const struct dpu_sspp_blks_common *common;
@@ -366,8 +357,10 @@ struct dpu_sspp_sub_blks { · 11 unmodified lines
366 struct dpu_pp_blk pcc_blk;357 struct dpu_pp_blk pcc_blk;
367 struct dpu_pp_blk igc_blk;358 struct dpu_pp_blk igc_blk;
368 359
369 const struct dpu_format_extended *format_list;360 const u32 *format_list;
370 const struct dpu_format_extended *virt_format_list;361 u32 num_formats;
362 const u32 *virt_format_list;
363 u32 virt_num_formats;
371};364};
372 365
373/**366/**
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h+72−148
@@ -12,157 +12,81 @@ · 11 unmodified lines
12 12
13#include "dpu_hw_mdss.h"13#include "dpu_hw_mdss.h"
14 14
15static const struct dpu_format_extended plane_formats[] = {15static const uint32_t qcom_compressed_supported_formats[] = {
16 {DRM_FORMAT_ARGB8888, 0},16 DRM_FORMAT_ABGR8888,
17 {DRM_FORMAT_ABGR8888, 0},17 DRM_FORMAT_XBGR8888,
18 {DRM_FORMAT_RGBA8888, 0},18 DRM_FORMAT_BGR565,
19 {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED},
20 {DRM_FORMAT_BGRA8888, 0},
21 {DRM_FORMAT_XRGB8888, 0},
22 {DRM_FORMAT_RGBX8888, 0},
23 {DRM_FORMAT_BGRX8888, 0},
24 {DRM_FORMAT_XBGR8888, 0},
25 {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED},
26 {DRM_FORMAT_RGB888, 0},
27 {DRM_FORMAT_BGR888, 0},
28 {DRM_FORMAT_RGB565, 0},
29 {DRM_FORMAT_BGR565, DRM_FORMAT_MOD_QCOM_COMPRESSED},
30 {DRM_FORMAT_BGR565, 0},
31 {DRM_FORMAT_ARGB1555, 0},
32 {DRM_FORMAT_ABGR1555, 0},
33 {DRM_FORMAT_RGBA5551, 0},
34 {DRM_FORMAT_BGRA5551, 0},
35 {DRM_FORMAT_XRGB1555, 0},
36 {DRM_FORMAT_XBGR1555, 0},
37 {DRM_FORMAT_RGBX5551, 0},
38 {DRM_FORMAT_BGRX5551, 0},
39 {DRM_FORMAT_ARGB4444, 0},
40 {DRM_FORMAT_ABGR4444, 0},
41 {DRM_FORMAT_RGBA4444, 0},
42 {DRM_FORMAT_BGRA4444, 0},
43 {DRM_FORMAT_XRGB4444, 0},
44 {DRM_FORMAT_XBGR4444, 0},
45 {DRM_FORMAT_RGBX4444, 0},
46 {DRM_FORMAT_BGRX4444, 0},
47 {0, 0},
48};19};
49 20
50static const struct dpu_format_extended plane_formats_yuv[] = {21static const uint32_t plane_formats[] = {
51 {DRM_FORMAT_ARGB8888, 0},22 DRM_FORMAT_ARGB8888,
52 {DRM_FORMAT_ABGR8888, 0},23 DRM_FORMAT_ABGR8888,
53 {DRM_FORMAT_RGBA8888, 0},24 DRM_FORMAT_RGBA8888,
54 {DRM_FORMAT_BGRX8888, 0},25 DRM_FORMAT_BGRA8888,
55 {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED},26 DRM_FORMAT_XRGB8888,
56 {DRM_FORMAT_BGRA8888, 0},27 DRM_FORMAT_RGBX8888,
57 {DRM_FORMAT_XRGB8888, 0},28 DRM_FORMAT_BGRX8888,
58 {DRM_FORMAT_XBGR8888, 0},29 DRM_FORMAT_XBGR8888,
59 {DRM_FORMAT_RGBX8888, 0},30 DRM_FORMAT_RGB888,
60 {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED},31 DRM_FORMAT_BGR888,
61 {DRM_FORMAT_RGB888, 0},32 DRM_FORMAT_RGB565,
62 {DRM_FORMAT_BGR888, 0},33 DRM_FORMAT_BGR565,
63 {DRM_FORMAT_RGB565, 0},34 DRM_FORMAT_ARGB1555,
64 {DRM_FORMAT_BGR565, DRM_FORMAT_MOD_QCOM_COMPRESSED},35 DRM_FORMAT_ABGR1555,
65 {DRM_FORMAT_BGR565, 0},36 DRM_FORMAT_RGBA5551,
66 {DRM_FORMAT_ARGB1555, 0},37 DRM_FORMAT_BGRA5551,
67 {DRM_FORMAT_ABGR1555, 0},38 DRM_FORMAT_XRGB1555,
68 {DRM_FORMAT_RGBA5551, 0},39 DRM_FORMAT_XBGR1555,
69 {DRM_FORMAT_BGRA5551, 0},40 DRM_FORMAT_RGBX5551,
70 {DRM_FORMAT_XRGB1555, 0},41 DRM_FORMAT_BGRX5551,
71 {DRM_FORMAT_XBGR1555, 0},42 DRM_FORMAT_ARGB4444,
72 {DRM_FORMAT_RGBX5551, 0},43 DRM_FORMAT_ABGR4444,
73 {DRM_FORMAT_BGRX5551, 0},44 DRM_FORMAT_RGBA4444,
74 {DRM_FORMAT_ARGB4444, 0},45 DRM_FORMAT_BGRA4444,
75 {DRM_FORMAT_ABGR4444, 0},46 DRM_FORMAT_XRGB4444,
76 {DRM_FORMAT_RGBA4444, 0},47 DRM_FORMAT_XBGR4444,
77 {DRM_FORMAT_BGRA4444, 0},48 DRM_FORMAT_RGBX4444,
78 {DRM_FORMAT_XRGB4444, 0},49 DRM_FORMAT_BGRX4444,
79 {DRM_FORMAT_XBGR4444, 0},
80 {DRM_FORMAT_RGBX4444, 0},
81 {DRM_FORMAT_BGRX4444, 0},
82
83 {DRM_FORMAT_NV12, 0},
84 {DRM_FORMAT_NV12, DRM_FORMAT_MOD_QCOM_COMPRESSED},
85 {DRM_FORMAT_NV21, 0},
86 {DRM_FORMAT_NV16, 0},
87 {DRM_FORMAT_NV61, 0},
88 {DRM_FORMAT_VYUY, 0},
89 {DRM_FORMAT_UYVY, 0},
90 {DRM_FORMAT_YUYV, 0},
91 {DRM_FORMAT_YVYU, 0},
92 {DRM_FORMAT_YUV420, 0},
93 {DRM_FORMAT_YVU420, 0},
94 {0, 0},
95};
96
97static const struct dpu_format_extended cursor_formats[] = {
98 {DRM_FORMAT_ARGB8888, 0},
99 {DRM_FORMAT_ABGR8888, 0},
100 {DRM_FORMAT_RGBA8888, 0},
101 {DRM_FORMAT_BGRA8888, 0},
102 {DRM_FORMAT_XRGB8888, 0},
103 {DRM_FORMAT_ARGB1555, 0},
104 {DRM_FORMAT_ABGR1555, 0},
105 {DRM_FORMAT_RGBA5551, 0},
106 {DRM_FORMAT_BGRA5551, 0},
107 {DRM_FORMAT_ARGB4444, 0},
108 {DRM_FORMAT_ABGR4444, 0},
109 {DRM_FORMAT_RGBA4444, 0},
110 {DRM_FORMAT_BGRA4444, 0},
111 {0, 0},
112};50};
113 51
114static const struct dpu_format_extended wb2_formats[] = {52static const uint32_t plane_formats_yuv[] = {
115 {DRM_FORMAT_RGB565, 0},53 DRM_FORMAT_ARGB8888,
116 {DRM_FORMAT_BGR565, DRM_FORMAT_MOD_QCOM_COMPRESSED},54 DRM_FORMAT_ABGR8888,
117 {DRM_FORMAT_RGB888, 0},55 DRM_FORMAT_RGBA8888,
118 {DRM_FORMAT_ARGB8888, 0},56 DRM_FORMAT_BGRX8888,
119 {DRM_FORMAT_RGBA8888, 0},57 DRM_FORMAT_BGRA8888,
120 {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED},58 DRM_FORMAT_XRGB8888,
121 {DRM_FORMAT_XRGB8888, 0},59 DRM_FORMAT_XBGR8888,
122 {DRM_FORMAT_RGBX8888, 0},60 DRM_FORMAT_RGBX8888,
123 {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_QCOM_COMPRESSED},61 DRM_FORMAT_RGB888,
124 {DRM_FORMAT_ARGB1555, 0},62 DRM_FORMAT_BGR888,
125 {DRM_FORMAT_RGBA5551, 0},63 DRM_FORMAT_RGB565,
126 {DRM_FORMAT_XRGB1555, 0},64 DRM_FORMAT_BGR565,
127 {DRM_FORMAT_RGBX5551, 0},65 DRM_FORMAT_ARGB1555,
128 {DRM_FORMAT_ARGB4444, 0},66 DRM_FORMAT_ABGR1555,
129 {DRM_FORMAT_RGBA4444, 0},67 DRM_FORMAT_RGBA5551,
130 {DRM_FORMAT_RGBX4444, 0},68 DRM_FORMAT_BGRA5551,
131 {DRM_FORMAT_XRGB4444, 0},69 DRM_FORMAT_XRGB1555,
132 70 DRM_FORMAT_XBGR1555,
133 {DRM_FORMAT_BGR565, 0},71 DRM_FORMAT_RGBX5551,
134 {DRM_FORMAT_BGR888, 0},72 DRM_FORMAT_BGRX5551,
135 {DRM_FORMAT_ABGR8888, 0},73 DRM_FORMAT_ARGB4444,
136 {DRM_FORMAT_BGRA8888, 0},74 DRM_FORMAT_ABGR4444,
137 {DRM_FORMAT_BGRX8888, 0},75 DRM_FORMAT_RGBA4444,
138 {DRM_FORMAT_XBGR8888, 0},76 DRM_FORMAT_BGRA4444,
139 {DRM_FORMAT_ABGR1555, 0},77 DRM_FORMAT_XRGB4444,
140 {DRM_FORMAT_BGRA5551, 0},78 DRM_FORMAT_XBGR4444,
141 {DRM_FORMAT_XBGR1555, 0},79 DRM_FORMAT_RGBX4444,
142 {DRM_FORMAT_BGRX5551, 0},80 DRM_FORMAT_BGRX4444,
143 {DRM_FORMAT_ABGR4444, 0},
144 {DRM_FORMAT_BGRA4444, 0},
145 {DRM_FORMAT_BGRX4444, 0},
146 {DRM_FORMAT_XBGR4444, 0},
147
148 {DRM_FORMAT_YUV420, 0},
149 {DRM_FORMAT_NV12, 0},
150 {DRM_FORMAT_NV12, DRM_FORMAT_MOD_QCOM_COMPRESSED},
151 {DRM_FORMAT_NV16, 0},
152 {DRM_FORMAT_YUYV, 0},
153
154 {0, 0},
155};
156 81
157static const struct dpu_format_extended rgb_10bit_formats[] = {82 DRM_FORMAT_NV12,
158 {DRM_FORMAT_BGRA1010102, 0},83 DRM_FORMAT_NV21,
159 {DRM_FORMAT_BGRX1010102, 0},84 DRM_FORMAT_NV16,
160 {DRM_FORMAT_RGBA1010102, 0},85 DRM_FORMAT_NV61,
161 {DRM_FORMAT_RGBX1010102, 0},86 DRM_FORMAT_VYUY,
162 {DRM_FORMAT_ABGR2101010, 0},87 DRM_FORMAT_UYVY,
163 {DRM_FORMAT_ABGR2101010, DRM_FORMAT_MOD_QCOM_COMPRESSED},88 DRM_FORMAT_YUYV,
164 {DRM_FORMAT_XBGR2101010, 0},89 DRM_FORMAT_YVYU,
165 {DRM_FORMAT_XBGR2101010, DRM_FORMAT_MOD_QCOM_COMPRESSED},90 DRM_FORMAT_YUV420,
166 {DRM_FORMAT_ARGB2101010, 0},91 DRM_FORMAT_YVU420,
167 {DRM_FORMAT_XRGB2101010, 0},
168};92};
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c+0−44
@@ -170,10 +170,6 @@ · 169 unmodified lines
170/**170/**
171 * AD4 interrupt status bit definitions171 * AD4 interrupt status bit definitions
172 */172 */
173#define DPU_INTR_BRIGHTPR_UPDATED BIT(4)
174#define DPU_INTR_DARKENH_UPDATED BIT(3)
175#define DPU_INTR_STREN_OUTROI_UPDATED BIT(2)
176#define DPU_INTR_STREN_INROI_UPDATED BIT(1)
177#define DPU_INTR_BACKLIGHT_UPDATED BIT(0)173#define DPU_INTR_BACKLIGHT_UPDATED BIT(0)
178/**174/**
179 * struct dpu_intr_reg - array of DPU register sets175 * struct dpu_intr_reg - array of DPU register sets
@@ -782,18 +778,6 @@ static int dpu_hw_intr_irqidx_lookup(enum dpu_intr_type intr_type, · 602 unmodified lines
782 return -EINVAL;778 return -EINVAL;
783}779}
784 780
785static void dpu_hw_intr_set_mask(struct dpu_hw_intr *intr, uint32_t reg_off,
786 uint32_t mask)
787{
788 if (!intr)
789 return;
790
791 DPU_REG_WRITE(&intr->hw, reg_off, mask);
792
793 /* ensure register writes go through */
794 wmb();
795}
796
797static void dpu_hw_intr_dispatch_irq(struct dpu_hw_intr *intr,781static void dpu_hw_intr_dispatch_irq(struct dpu_hw_intr *intr,
798 void (*cbfunc)(void *, int),782 void (*cbfunc)(void *, int),
799 void *arg)783 void *arg)
@@ -1004,18 +988,6 @@ static int dpu_hw_intr_disable_irqs(struct dpu_hw_intr *intr) · 204 unmodified lines
1004 return 0;988 return 0;
1005}989}
1006 990
1007static int dpu_hw_intr_get_valid_interrupts(struct dpu_hw_intr *intr,
1008 uint32_t *mask)
1009{
1010 if (!intr || !mask)
1011 return -EINVAL;
1012
1013 *mask = IRQ_SOURCE_MDP | IRQ_SOURCE_DSI0 | IRQ_SOURCE_DSI1
1014 | IRQ_SOURCE_HDMI | IRQ_SOURCE_EDP;
1015
1016 return 0;
1017}
1018
1019static void dpu_hw_intr_get_interrupt_statuses(struct dpu_hw_intr *intr)991static void dpu_hw_intr_get_interrupt_statuses(struct dpu_hw_intr *intr)
1020{992{
1021 int i;993 int i;
@@ -1065,19 +1037,6 @@ static void dpu_hw_intr_clear_intr_status_nolock(struct dpu_hw_intr *intr, · 43 unmodified lines
1065 wmb();1037 wmb();
1066}1038}
1067 1039
1068static void dpu_hw_intr_clear_interrupt_status(struct dpu_hw_intr *intr,
1069 int irq_idx)
1070{
1071 unsigned long irq_flags;
1072
1073 if (!intr)
1074 return;
1075
1076 spin_lock_irqsave(&intr->irq_lock, irq_flags);
1077 dpu_hw_intr_clear_intr_status_nolock(intr, irq_idx);
1078 spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
1079}
1080
1081static u32 dpu_hw_intr_get_interrupt_status(struct dpu_hw_intr *intr,1040static u32 dpu_hw_intr_get_interrupt_status(struct dpu_hw_intr *intr,
1082 int irq_idx, bool clear)1041 int irq_idx, bool clear)
1083{1042{
@@ -1113,16 +1072,13 @@ static u32 dpu_hw_intr_get_interrupt_status(struct dpu_hw_intr *intr, · 29 unmodified lines
1113 1072
1114static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)1073static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)
1115{1074{
1116 ops->set_mask = dpu_hw_intr_set_mask;
1117 ops->irq_idx_lookup = dpu_hw_intr_irqidx_lookup;1075 ops->irq_idx_lookup = dpu_hw_intr_irqidx_lookup;
1118 ops->enable_irq = dpu_hw_intr_enable_irq;1076 ops->enable_irq = dpu_hw_intr_enable_irq;
1119 ops->disable_irq = dpu_hw_intr_disable_irq;1077 ops->disable_irq = dpu_hw_intr_disable_irq;
1120 ops->dispatch_irqs = dpu_hw_intr_dispatch_irq;1078 ops->dispatch_irqs = dpu_hw_intr_dispatch_irq;
1121 ops->clear_all_irqs = dpu_hw_intr_clear_irqs;1079 ops->clear_all_irqs = dpu_hw_intr_clear_irqs;
1122 ops->disable_all_irqs = dpu_hw_intr_disable_irqs;1080 ops->disable_all_irqs = dpu_hw_intr_disable_irqs;
1123 ops->get_valid_interrupts = dpu_hw_intr_get_valid_interrupts;
1124 ops->get_interrupt_statuses = dpu_hw_intr_get_interrupt_statuses;1081 ops->get_interrupt_statuses = dpu_hw_intr_get_interrupt_statuses;
1125 ops->clear_interrupt_status = dpu_hw_intr_clear_interrupt_status;
1126 ops->clear_intr_status_nolock = dpu_hw_intr_clear_intr_status_nolock;1082 ops->clear_intr_status_nolock = dpu_hw_intr_clear_intr_status_nolock;
1127 ops->get_interrupt_status = dpu_hw_intr_get_interrupt_status;1083 ops->get_interrupt_status = dpu_hw_intr_get_interrupt_status;
1128}1084}
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h+0−44
@@ -20,13 +20,6 @@ · 19 unmodified lines
20#include "dpu_hw_util.h"20#include "dpu_hw_util.h"
21#include "dpu_hw_mdss.h"21#include "dpu_hw_mdss.h"
22 22
23#define IRQ_SOURCE_MDP BIT(0)
24#define IRQ_SOURCE_DSI0 BIT(4)
25#define IRQ_SOURCE_DSI1 BIT(5)
26#define IRQ_SOURCE_HDMI BIT(8)
27#define IRQ_SOURCE_EDP BIT(12)
28#define IRQ_SOURCE_MHL BIT(16)
29
30/**23/**
31 * dpu_intr_type - HW Interrupt Type24 * dpu_intr_type - HW Interrupt Type
32 * @DPU_IRQ_TYPE_WB_ROT_COMP: WB rotator done25 * @DPU_IRQ_TYPE_WB_ROT_COMP: WB rotator done
@@ -95,18 +88,6 @@ struct dpu_hw_intr; · 62 unmodified lines
95 * Interrupt operations.88 * Interrupt operations.
96 */89 */
97struct dpu_hw_intr_ops {90struct dpu_hw_intr_ops {
98 /**
99 * set_mask - Programs the given interrupt register with the
100 * given interrupt mask. Register value will get overwritten.
101 * @intr: HW interrupt handle
102 * @reg_off: MDSS HW register offset
103 * @irqmask: IRQ mask value
104 */
105 void (*set_mask)(
106 struct dpu_hw_intr *intr,
107 uint32_t reg,
108 uint32_t irqmask);
109
110 /**91 /**
111 * irq_idx_lookup - Lookup IRQ index on the HW interrupt type92 * irq_idx_lookup - Lookup IRQ index on the HW interrupt type
112 * Used for all irq related ops93 * Used for all irq related ops
@@ -176,16 +157,6 @@ struct dpu_hw_intr_ops { · 63 unmodified lines
176 void (*get_interrupt_statuses)(157 void (*get_interrupt_statuses)(
177 struct dpu_hw_intr *intr);158 struct dpu_hw_intr *intr);
178 159
179 /**
180 * clear_interrupt_status - Clears HW interrupt status based on given
181 * lookup IRQ index.
182 * @intr: HW interrupt handle
183 * @irq_idx: Lookup irq index return from irq_idx_lookup
184 */
185 void (*clear_interrupt_status)(
186 struct dpu_hw_intr *intr,
187 int irq_idx);
188
189 /**160 /**
190 * clear_intr_status_nolock() - clears the HW interrupts without lock161 * clear_intr_status_nolock() - clears the HW interrupts without lock
191 * @intr: HW interrupt handle162 * @intr: HW interrupt handle
@@ -206,21 +177,6 @@ struct dpu_hw_intr_ops { · 14 unmodified lines
206 struct dpu_hw_intr *intr,177 struct dpu_hw_intr *intr,
207 int irq_idx,178 int irq_idx,
208 bool clear);179 bool clear);
209
210 /**
211 * get_valid_interrupts - Gets a mask of all valid interrupt sources
212 * within DPU. These are actually status bits
213 * within interrupt registers that specify the
214 * source of the interrupt in IRQs. For example,
215 * valid interrupt sources can be MDP, DSI,
216 * HDMI etc.
217 * @intr: HW interrupt handle
218 * @mask: Returning the interrupt source MASK
219 * @return: 0 for success, otherwise failure
220 */
221 int (*get_valid_interrupts)(
222 struct dpu_hw_intr *intr,
223 uint32_t *mask);
224};180};
225 181
226/**182/**
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h+0−7
@@ -258,12 +258,6 @@ enum dpu_vbif { · 257 unmodified lines
258 VBIF_NRT = VBIF_1258 VBIF_NRT = VBIF_1
259};259};
260 260
261enum dpu_iommu_domain {
262 DPU_IOMMU_DOMAIN_UNSECURE,
263 DPU_IOMMU_DOMAIN_SECURE,
264 DPU_IOMMU_DOMAIN_MAX
265};
266
267/**261/**
268 * DPU HW,Component order color map262 * DPU HW,Component order color map
269 */263 */
@@ -358,7 +352,6 @@ enum dpu_3d_blend_mode { · 88 unmodified lines
358 * @alpha_enable: whether the format has an alpha channel352 * @alpha_enable: whether the format has an alpha channel
359 * @num_planes: number of planes (including meta data planes)353 * @num_planes: number of planes (including meta data planes)
360 * @fetch_mode: linear, tiled, or ubwc hw fetch behavior354 * @fetch_mode: linear, tiled, or ubwc hw fetch behavior
361 * @is_yuv: is format a yuv variant
362 * @flag: usage bit flags355 * @flag: usage bit flags
363 * @tile_width: format tile width356 * @tile_width: format tile width
364 * @tile_height: format tile height357 * @tile_height: format tile height
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h+0−1
@@ -18,7 +18,6 @@ · 17 unmodified lines
18#include "dpu_hw_mdss.h"18#include "dpu_hw_mdss.h"
19 19
20#define REG_MASK(n) ((BIT(n)) - 1)20#define REG_MASK(n) ((BIT(n)) - 1)
21struct dpu_format_extended;
22 21
23/*22/*
24 * This is the common struct maintained by each sub block23 * This is the common struct maintained by each sub block
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c+36−29
@@ -405,35 +405,38 @@ static void dpu_kms_wait_for_commit_done(struct msm_kms *kms, · 404 unmodified lines
405 }405 }
406}406}
407 407
408static void _dpu_kms_initialize_dsi(struct drm_device *dev,408static int _dpu_kms_initialize_dsi(struct drm_device *dev,
409 struct msm_drm_private *priv,409 struct msm_drm_private *priv,
410 struct dpu_kms *dpu_kms)410 struct dpu_kms *dpu_kms)
411{411{
412 struct drm_encoder *encoder = NULL;412 struct drm_encoder *encoder = NULL;
413 int i, rc;413 int i, rc = 0;
414
415 if (!(priv->dsi[0] || priv->dsi[1]))
416 return rc;
414 417
415 /*TODO: Support two independent DSI connectors */418 /*TODO: Support two independent DSI connectors */
416 encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI);419 encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI);
417 if (IS_ERR_OR_NULL(encoder)) {420 if (IS_ERR(encoder)) {
418 DPU_ERROR("encoder init failed for dsi display\n");421 DPU_ERROR("encoder init failed for dsi display\n");
419 return;422 return PTR_ERR(encoder);
420 }423 }
421 424
422 priv->encoders[priv->num_encoders++] = encoder;425 priv->encoders[priv->num_encoders++] = encoder;
423 426
424 for (i = 0; i < ARRAY_SIZE(priv->dsi); i++) {427 for (i = 0; i < ARRAY_SIZE(priv->dsi); i++) {
425 if (!priv->dsi[i]) {428 if (!priv->dsi[i])
426 DPU_DEBUG("invalid msm_dsi for ctrl %d\n", i);429 continue;
427 return;
428 }
429 430
430 rc = msm_dsi_modeset_init(priv->dsi[i], dev, encoder);431 rc = msm_dsi_modeset_init(priv->dsi[i], dev, encoder);
431 if (rc) {432 if (rc) {
432 DPU_ERROR("modeset_init failed for dsi[%d], rc = %d\n",433 DPU_ERROR("modeset_init failed for dsi[%d], rc = %d\n",
433 i, rc);434 i, rc);
434 continue;435 break;
435 }436 }
436 }437 }
438
439 return rc;
437}440}
438 441
439/**442/**
@@ -444,16 +447,16 @@ static void _dpu_kms_initialize_dsi(struct drm_device *dev, · 4 unmodified lines
444 * @dpu_kms: Pointer to dpu kms structure447 * @dpu_kms: Pointer to dpu kms structure
445 * Returns: Zero on success448 * Returns: Zero on success
446 */449 */
447static void _dpu_kms_setup_displays(struct drm_device *dev,450static int _dpu_kms_setup_displays(struct drm_device *dev,
448 struct msm_drm_private *priv,451 struct msm_drm_private *priv,
449 struct dpu_kms *dpu_kms)452 struct dpu_kms *dpu_kms)
450{453{
451 _dpu_kms_initialize_dsi(dev, priv, dpu_kms);
452
453 /**454 /**
454 * Extend this function to initialize other455 * Extend this function to initialize other
455 * types of displays456 * types of displays
456 */457 */
458
459 return _dpu_kms_initialize_dsi(dev, priv, dpu_kms);
457}460}
458 461
459static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms)462static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms)
@@ -516,7 +519,9 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) · 56 unmodified lines
516 * Create encoder and query display drivers to create519 * Create encoder and query display drivers to create
517 * bridges and connectors520 * bridges and connectors
518 */521 */
519 _dpu_kms_setup_displays(dev, priv, dpu_kms);522 ret = _dpu_kms_setup_displays(dev, priv, dpu_kms);
523 if (ret)
524 goto fail;
520 525
521 max_crtc_count = min(catalog->mixer_count, priv->num_encoders);526 max_crtc_count = min(catalog->mixer_count, priv->num_encoders);
522 527
@@ -627,6 +632,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) · 104 unmodified lines
627 devm_iounmap(&dpu_kms->pdev->dev, dpu_kms->vbif[VBIF_RT]);632 devm_iounmap(&dpu_kms->pdev->dev, dpu_kms->vbif[VBIF_RT]);
628 dpu_kms->vbif[VBIF_RT] = NULL;633 dpu_kms->vbif[VBIF_RT] = NULL;
629 634
635 if (dpu_kms->hw_mdp)
636 dpu_hw_mdp_destroy(dpu_kms->hw_mdp);
637 dpu_kms->hw_mdp = NULL;
638
630 if (dpu_kms->mmio)639 if (dpu_kms->mmio)
631 devm_iounmap(&dpu_kms->pdev->dev, dpu_kms->mmio);640 devm_iounmap(&dpu_kms->pdev->dev, dpu_kms->mmio);
632 dpu_kms->mmio = NULL;641 dpu_kms->mmio = NULL;
@@ -877,8 +886,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 244 unmodified lines
877 goto power_error;886 goto power_error;
878 }887 }
879 888
880 rc = dpu_rm_init(&dpu_kms->rm, dpu_kms->catalog, dpu_kms->mmio,889 rc = dpu_rm_init(&dpu_kms->rm, dpu_kms->catalog, dpu_kms->mmio);
881 dpu_kms->dev);
882 if (rc) {890 if (rc) {
883 DPU_ERROR("rm init failed: %d\n", rc);891 DPU_ERROR("rm init failed: %d\n", rc);
884 goto power_error;892 goto power_error;
@@ -886,11 +894,10 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 1 unmodified line
886 894
887 dpu_kms->rm_init = true;895 dpu_kms->rm_init = true;
888 896
889 dpu_kms->hw_mdp = dpu_rm_get_mdp(&dpu_kms->rm);897 dpu_kms->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, dpu_kms->mmio,
890 if (IS_ERR_OR_NULL(dpu_kms->hw_mdp)) {898 dpu_kms->catalog);
899 if (IS_ERR(dpu_kms->hw_mdp)) {
891 rc = PTR_ERR(dpu_kms->hw_mdp);900 rc = PTR_ERR(dpu_kms->hw_mdp);
892 if (!dpu_kms->hw_mdp)
893 rc = -EINVAL;
894 DPU_ERROR("failed to get hw_mdp: %d\n", rc);901 DPU_ERROR("failed to get hw_mdp: %d\n", rc);
895 dpu_kms->hw_mdp = NULL;902 dpu_kms->hw_mdp = NULL;
896 goto power_error;903 goto power_error;
@@ -926,16 +933,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 29 unmodified lines
926 goto hw_intr_init_err;933 goto hw_intr_init_err;
927 }934 }
928 935
929 /*
930 * _dpu_kms_drm_obj_init should create the DRM related objects
931 * i.e. CRTCs, planes, encoders, connectors and so forth
932 */
933 rc = _dpu_kms_drm_obj_init(dpu_kms);
934 if (rc) {
935 DPU_ERROR("modeset init failed: %d\n", rc);
936 goto drm_obj_init_err;
937 }
938
939 dev->mode_config.min_width = 0;936 dev->mode_config.min_width = 0;
940 dev->mode_config.min_height = 0;937 dev->mode_config.min_height = 0;
941 938
@@ -952,6 +949,16 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 10 unmodified lines
952 */949 */
953 dev->mode_config.allow_fb_modifiers = true;950 dev->mode_config.allow_fb_modifiers = true;
954 951
952 /*
953 * _dpu_kms_drm_obj_init should create the DRM related objects
954 * i.e. CRTCs, planes, encoders, connectors and so forth
955 */
956 rc = _dpu_kms_drm_obj_init(dpu_kms);
957 if (rc) {
958 DPU_ERROR("modeset init failed: %d\n", rc);
959 goto drm_obj_init_err;
960 }
961
955 dpu_vbif_init_memtypes(dpu_kms);962 dpu_vbif_init_memtypes(dpu_kms);
956 963
957 pm_runtime_put_sync(&dpu_kms->pdev->dev);964 pm_runtime_put_sync(&dpu_kms->pdev->dev);
drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c+21−15
@@ -23,11 +23,14 @@ struct dpu_mdss { · 22 unmodified lines
23 struct dpu_irq_controller irq_controller;23 struct dpu_irq_controller irq_controller;
24};24};
25 25
26static irqreturn_t dpu_mdss_irq(int irq, void *arg)26static void dpu_mdss_irq(struct irq_desc *desc)
27{27{
28 struct dpu_mdss *dpu_mdss = arg;28 struct dpu_mdss *dpu_mdss = irq_desc_get_handler_data(desc);
29 struct irq_chip *chip = irq_desc_get_chip(desc);
29 u32 interrupts;30 u32 interrupts;
30 31
32 chained_irq_enter(chip, desc);
33
31 interrupts = readl_relaxed(dpu_mdss->mmio + HW_INTR_STATUS);34 interrupts = readl_relaxed(dpu_mdss->mmio + HW_INTR_STATUS);
32 35
33 while (interrupts) {36 while (interrupts) {
@@ -39,20 +42,20 @@ static irqreturn_t dpu_mdss_irq(int irq, void *arg) · 5 unmodified lines
39 hwirq);42 hwirq);
40 if (mapping == 0) {43 if (mapping == 0) {
41 DRM_ERROR("couldn't find irq mapping for %lu\n", hwirq);44 DRM_ERROR("couldn't find irq mapping for %lu\n", hwirq);
42 return IRQ_NONE;45 break;
43 }46 }
44 47
45 rc = generic_handle_irq(mapping);48 rc = generic_handle_irq(mapping);
46 if (rc < 0) {49 if (rc < 0) {
47 DRM_ERROR("handle irq fail: irq=%lu mapping=%u rc=%d\n",50 DRM_ERROR("handle irq fail: irq=%lu mapping=%u rc=%d\n",
48 hwirq, mapping, rc);51 hwirq, mapping, rc);
49 return IRQ_NONE;52 break;
50 }53 }
51 54
52 interrupts &= ~(1 << hwirq);55 interrupts &= ~(1 << hwirq);
53 }56 }
54 57
55 return IRQ_HANDLED;58 chained_irq_exit(chip, desc);
56}59}
57 60
58static void dpu_mdss_irq_mask(struct irq_data *irqd)61static void dpu_mdss_irq_mask(struct irq_data *irqd)
@@ -83,16 +86,16 @@ static struct irq_chip dpu_mdss_irq_chip = { · 24 unmodified lines
83 .irq_unmask = dpu_mdss_irq_unmask,86 .irq_unmask = dpu_mdss_irq_unmask,
84};87};
85 88
89static struct lock_class_key dpu_mdss_lock_key, dpu_mdss_request_key;
90
86static int dpu_mdss_irqdomain_map(struct irq_domain *domain,91static int dpu_mdss_irqdomain_map(struct irq_domain *domain,
87 unsigned int irq, irq_hw_number_t hwirq)92 unsigned int irq, irq_hw_number_t hwirq)
88{93{
89 struct dpu_mdss *dpu_mdss = domain->host_data;94 struct dpu_mdss *dpu_mdss = domain->host_data;
90 int ret;
91 95
96 irq_set_lockdep_class(irq, &dpu_mdss_lock_key, &dpu_mdss_request_key);
92 irq_set_chip_and_handler(irq, &dpu_mdss_irq_chip, handle_level_irq);97 irq_set_chip_and_handler(irq, &dpu_mdss_irq_chip, handle_level_irq);
93 ret = irq_set_chip_data(irq, dpu_mdss);98 return irq_set_chip_data(irq, dpu_mdss);
94
95 return ret;
96}99}
97 100
98static const struct irq_domain_ops dpu_mdss_irqdomain_ops = {101static const struct irq_domain_ops dpu_mdss_irqdomain_ops = {
@@ -159,11 +162,13 @@ static void dpu_mdss_destroy(struct drm_device *dev) · 60 unmodified lines
159 struct msm_drm_private *priv = dev->dev_private;162 struct msm_drm_private *priv = dev->dev_private;
160 struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss);163 struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss);
161 struct dss_module_power *mp = &dpu_mdss->mp;164 struct dss_module_power *mp = &dpu_mdss->mp;
165 int irq;
162 166
163 pm_runtime_suspend(dev->dev);167 pm_runtime_suspend(dev->dev);
164 pm_runtime_disable(dev->dev);168 pm_runtime_disable(dev->dev);
165 _dpu_mdss_irq_domain_fini(dpu_mdss);169 _dpu_mdss_irq_domain_fini(dpu_mdss);
166 free_irq(platform_get_irq(pdev, 0), dpu_mdss);170 irq = platform_get_irq(pdev, 0);
171 irq_set_chained_handler_and_data(irq, NULL, NULL);
167 msm_dss_put_clk(mp->clk_config, mp->num_clk);172 msm_dss_put_clk(mp->clk_config, mp->num_clk);
168 devm_kfree(&pdev->dev, mp->clk_config);173 devm_kfree(&pdev->dev, mp->clk_config);
169 174
@@ -187,6 +192,7 @@ int dpu_mdss_init(struct drm_device *dev) · 17 unmodified lines
187 struct dpu_mdss *dpu_mdss;192 struct dpu_mdss *dpu_mdss;
188 struct dss_module_power *mp;193 struct dss_module_power *mp;
189 int ret = 0;194 int ret = 0;
195 int irq;
190 196
191 dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL);197 dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL);
192 if (!dpu_mdss)198 if (!dpu_mdss)
@@ -219,12 +225,12 @@ int dpu_mdss_init(struct drm_device *dev) · 26 unmodified lines
219 if (ret)225 if (ret)
220 goto irq_domain_error;226 goto irq_domain_error;
221 227
222 ret = request_irq(platform_get_irq(pdev, 0),228 irq = platform_get_irq(pdev, 0);
223 dpu_mdss_irq, 0, "dpu_mdss_isr", dpu_mdss);229 if (irq < 0)
224 if (ret) {
225 DPU_ERROR("failed to init irq: %d\n", ret);
226 goto irq_error;230 goto irq_error;
227 }231
232 irq_set_chained_handler_and_data(irq, dpu_mdss_irq,
233 dpu_mdss);
228 234
229 pm_runtime_enable(dev->dev);235 pm_runtime_enable(dev->dev);
230 236
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c+34−17
@@ -95,8 +95,6 @@ struct dpu_plane { · 94 unmodified lines
95 95
96 enum dpu_sspp pipe;96 enum dpu_sspp pipe;
97 uint32_t features; /* capabilities from catalog */97 uint32_t features; /* capabilities from catalog */
98 uint32_t nformats;
99 uint32_t formats[64];
100 98
101 struct dpu_hw_pipe *pipe_hw;99 struct dpu_hw_pipe *pipe_hw;
102 struct dpu_hw_pipe_cfg pipe_cfg;100 struct dpu_hw_pipe_cfg pipe_cfg;
@@ -121,6 +119,12 @@ struct dpu_plane { · 18 unmodified lines
121 bool debugfs_default_scale;119 bool debugfs_default_scale;
122};120};
123 121
122static const uint64_t supported_format_modifiers[] = {
123 DRM_FORMAT_MOD_QCOM_COMPRESSED,
124 DRM_FORMAT_MOD_LINEAR,
125 DRM_FORMAT_MOD_INVALID
126};
127
124#define to_dpu_plane(x) container_of(x, struct dpu_plane, base)128#define to_dpu_plane(x) container_of(x, struct dpu_plane, base)
125 129
126static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane)130static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane)
@@ -1410,6 +1414,23 @@ static void dpu_plane_early_unregister(struct drm_plane *plane) · 1283 unmodified lines
1410 debugfs_remove_recursive(pdpu->debugfs_root);1414 debugfs_remove_recursive(pdpu->debugfs_root);
1411}1415}
1412 1416
1417static bool dpu_plane_format_mod_supported(struct drm_plane *plane,
1418 uint32_t format, uint64_t modifier)
1419{
1420 if (modifier == DRM_FORMAT_MOD_LINEAR)
1421 return true;
1422
1423 if (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED) {
1424 int i;
1425 for (i = 0; i < ARRAY_SIZE(qcom_compressed_supported_formats); i++) {
1426 if (format == qcom_compressed_supported_formats[i])
1427 return true;
1428 }
1429 }
1430
1431 return false;
1432}
1433
1413static const struct drm_plane_funcs dpu_plane_funcs = {1434static const struct drm_plane_funcs dpu_plane_funcs = {
1414 .update_plane = drm_atomic_helper_update_plane,1435 .update_plane = drm_atomic_helper_update_plane,
1415 .disable_plane = drm_atomic_helper_disable_plane,1436 .disable_plane = drm_atomic_helper_disable_plane,
@@ -1419,6 +1440,7 @@ static const struct drm_plane_funcs dpu_plane_funcs = { · 3 unmodified lines
1419 .atomic_destroy_state = dpu_plane_destroy_state,1440 .atomic_destroy_state = dpu_plane_destroy_state,
1420 .late_register = dpu_plane_late_register,1441 .late_register = dpu_plane_late_register,
1421 .early_unregister = dpu_plane_early_unregister,1442 .early_unregister = dpu_plane_early_unregister,
1443 .format_mod_supported = dpu_plane_format_mod_supported,
1422};1444};
1423 1445
1424static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = {1446static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = {
@@ -1444,11 +1466,12 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, · 19 unmodified lines
1444 unsigned long possible_crtcs, u32 master_plane_id)1466 unsigned long possible_crtcs, u32 master_plane_id)
1445{1467{
1446 struct drm_plane *plane = NULL, *master_plane = NULL;1468 struct drm_plane *plane = NULL, *master_plane = NULL;
1447 const struct dpu_format_extended *format_list;1469 const uint32_t *format_list;
1448 struct dpu_plane *pdpu;1470 struct dpu_plane *pdpu;
1449 struct msm_drm_private *priv = dev->dev_private;1471 struct msm_drm_private *priv = dev->dev_private;
1450 struct dpu_kms *kms = to_dpu_kms(priv->kms);1472 struct dpu_kms *kms = to_dpu_kms(priv->kms);
1451 int zpos_max = DPU_ZPOS_MAX;1473 int zpos_max = DPU_ZPOS_MAX;
1474 uint32_t num_formats;
1452 int ret = -EINVAL;1475 int ret = -EINVAL;
1453 1476
1454 /* create and zero local structure */1477 /* create and zero local structure */
@@ -1491,24 +1514,18 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, · 36 unmodified lines
1491 goto clean_sspp;1514 goto clean_sspp;
1492 }1515 }
1493 1516
1494 if (!master_plane_id)1517 if (pdpu->is_virtual) {
1495 format_list = pdpu->pipe_sblk->format_list;
1496 else
1497 format_list = pdpu->pipe_sblk->virt_format_list;1518 format_list = pdpu->pipe_sblk->virt_format_list;
1498 1519 num_formats = pdpu->pipe_sblk->virt_num_formats;
1499 pdpu->nformats = dpu_populate_formats(format_list,1520 }
1500 pdpu->formats,1521 else {
1501 0,1522 format_list = pdpu->pipe_sblk->format_list;
1502 ARRAY_SIZE(pdpu->formats));1523 num_formats = pdpu->pipe_sblk->num_formats;
1503
1504 if (!pdpu->nformats) {
1505 DPU_ERROR("[%u]no valid formats for plane\n", pipe);
1506 goto clean_sspp;
1507 }1524 }
1508 1525
1509 ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,1526 ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
1510 pdpu->formats, pdpu->nformats,1527 format_list, num_formats,
1511 NULL, type, NULL);1528 supported_format_modifiers, type, NULL);
1512 if (ret)1529 if (ret)
1513 goto clean_sspp;1530 goto clean_sspp;
1514 1531
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h+0−27
@@ -28,23 +28,18 @@ · 27 unmodified lines
28/**28/**
29 * struct dpu_plane_state: Define dpu extension of drm plane state object29 * struct dpu_plane_state: Define dpu extension of drm plane state object
30 * @base: base drm plane state object30 * @base: base drm plane state object
31 * @property_state: Local storage for msm_prop properties
32 * @property_values: cached plane property values
33 * @aspace: pointer to address space for input/output buffers31 * @aspace: pointer to address space for input/output buffers
34 * @input_fence: dereferenced input fence pointer
35 * @stage: assigned by crtc blender32 * @stage: assigned by crtc blender
36 * @multirect_index: index of the rectangle of SSPP33 * @multirect_index: index of the rectangle of SSPP
37 * @multirect_mode: parallel or time multiplex multirect mode34 * @multirect_mode: parallel or time multiplex multirect mode
38 * @pending: whether the current update is still pending35 * @pending: whether the current update is still pending
39 * @scaler3_cfg: configuration data for scaler336 * @scaler3_cfg: configuration data for scaler3
40 * @pixel_ext: configuration data for pixel extensions37 * @pixel_ext: configuration data for pixel extensions
41 * @scaler_check_state: indicates status of user provided pixel extension data
42 * @cdp_cfg: CDP configuration38 * @cdp_cfg: CDP configuration
43 */39 */
44struct dpu_plane_state {40struct dpu_plane_state {
45 struct drm_plane_state base;41 struct drm_plane_state base;
46 struct msm_gem_address_space *aspace;42 struct msm_gem_address_space *aspace;
47 void *input_fence;
48 enum dpu_stage stage;43 enum dpu_stage stage;
49 uint32_t multirect_index;44 uint32_t multirect_index;
50 uint32_t multirect_mode;45 uint32_t multirect_mode;
@@ -106,12 +101,6 @@ void dpu_plane_restore(struct drm_plane *plane); · 55 unmodified lines
106 */101 */
107void dpu_plane_flush(struct drm_plane *plane);102void dpu_plane_flush(struct drm_plane *plane);
108 103
109/**
110 * dpu_plane_kickoff - final plane operations before commit kickoff
111 * @plane: Pointer to drm plane structure
112 */
113void dpu_plane_kickoff(struct drm_plane *plane);
114
115/**104/**
116 * dpu_plane_set_error: enable/disable error condition105 * dpu_plane_set_error: enable/disable error condition
117 * @plane: pointer to drm_plane structure106 * @plane: pointer to drm_plane structure
@@ -146,14 +135,6 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane); · 28 unmodified lines
146 */135 */
147void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);136void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);
148 137
149/**
150 * dpu_plane_wait_input_fence - wait for input fence object
151 * @plane: Pointer to DRM plane object
152 * @wait_ms: Wait timeout value
153 * Returns: Zero on success
154 */
155int dpu_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms);
156
157/**138/**
158 * dpu_plane_color_fill - enables color fill on plane139 * dpu_plane_color_fill - enables color fill on plane
159 * @plane: Pointer to DRM plane object140 * @plane: Pointer to DRM plane object
@@ -164,12 +145,4 @@ int dpu_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms); · 4 unmodified lines
164int dpu_plane_color_fill(struct drm_plane *plane,145int dpu_plane_color_fill(struct drm_plane *plane,
165 uint32_t color, uint32_t alpha);146 uint32_t color, uint32_t alpha);
166 147
167/**
168 * dpu_plane_set_revalidate - sets revalidate flag which forces a full
169 * validation of the plane properties in the next atomic check
170 * @plane: Pointer to DRM plane object
171 * @enable: Boolean to set/unset the flag
172 */
173void dpu_plane_set_revalidate(struct drm_plane *plane, bool enable);
174
175#endif /* _DPU_PLANE_H_ */148#endif /* _DPU_PLANE_H_ */
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c+46−279
@@ -21,8 +21,8 @@ · 20 unmodified lines
21#include "dpu_encoder.h"21#include "dpu_encoder.h"
22#include "dpu_trace.h"22#include "dpu_trace.h"
23 23
24#define RESERVED_BY_OTHER(h, r) \24#define RESERVED_BY_OTHER(h, r) \
25 ((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id))25 ((h)->enc_id && (h)->enc_id != r)
26 26
27/**27/**
28 * struct dpu_rm_requirements - Reservation requirements parameter bundle28 * struct dpu_rm_requirements - Reservation requirements parameter bundle
@@ -34,90 +34,21 @@ struct dpu_rm_requirements { · 5 unmodified lines
34 struct dpu_encoder_hw_resources hw_res;34 struct dpu_encoder_hw_resources hw_res;
35};35};
36 36
37/**
38 * struct dpu_rm_rsvp - Use Case Reservation tagging structure
39 * Used to tag HW blocks as reserved by a CRTC->Encoder->Connector chain
40 * By using as a tag, rather than lists of pointers to HW blocks used
41 * we can avoid some list management since we don't know how many blocks
42 * of each type a given use case may require.
43 * @list: List head for list of all reservations
44 * @seq: Global RSVP sequence number for debugging, especially for
45 * differentiating differenct allocations for same encoder.
46 * @enc_id: Reservations are tracked by Encoder DRM object ID.
47 * CRTCs may be connected to multiple Encoders.
48 * An encoder or connector id identifies the display path.
49 */
50struct dpu_rm_rsvp {
51 struct list_head list;
52 uint32_t seq;
53 uint32_t enc_id;
54};
55 37
56/**38/**
57 * struct dpu_rm_hw_blk - hardware block tracking list member39 * struct dpu_rm_hw_blk - hardware block tracking list member
58 * @list: List head for list of all hardware blocks tracking items40 * @list: List head for list of all hardware blocks tracking items
59 * @rsvp: Pointer to use case reservation if reserved by a client
60 * @rsvp_nxt: Temporary pointer used during reservation to the incoming
61 * request. Will be swapped into rsvp if proposal is accepted
62 * @type: Type of hardware block this structure tracks
63 * @id: Hardware ID number, within it's own space, ie. LM_X41 * @id: Hardware ID number, within it's own space, ie. LM_X
64 * @catalog: Pointer to the hardware catalog entry for this block42 * @enc_id: Encoder id to which this blk is binded
65 * @hw: Pointer to the hardware register access object for this block43 * @hw: Pointer to the hardware register access object for this block
66 */44 */
67struct dpu_rm_hw_blk {45struct dpu_rm_hw_blk {
68 struct list_head list;46 struct list_head list;
69 struct dpu_rm_rsvp *rsvp;
70 struct dpu_rm_rsvp *rsvp_nxt;
71 enum dpu_hw_blk_type type;
72 uint32_t id;47 uint32_t id;
48 uint32_t enc_id;
73 struct dpu_hw_blk *hw;49 struct dpu_hw_blk *hw;
74};50};
75 51
76/**
77 * dpu_rm_dbg_rsvp_stage - enum of steps in making reservation for event logging
78 */
79enum dpu_rm_dbg_rsvp_stage {
80 DPU_RM_STAGE_BEGIN,
81 DPU_RM_STAGE_AFTER_CLEAR,
82 DPU_RM_STAGE_AFTER_RSVPNEXT,
83 DPU_RM_STAGE_FINAL
84};
85
86static void _dpu_rm_print_rsvps(
87 struct dpu_rm *rm,
88 enum dpu_rm_dbg_rsvp_stage stage)
89{
90 struct dpu_rm_rsvp *rsvp;
91 struct dpu_rm_hw_blk *blk;
92 enum dpu_hw_blk_type type;
93
94 DPU_DEBUG("%d\n", stage);
95
96 list_for_each_entry(rsvp, &rm->rsvps, list) {
97 DRM_DEBUG_KMS("%d rsvp[s%ue%u]\n", stage, rsvp->seq,
98 rsvp->enc_id);
99 }
100
101 for (type = 0; type < DPU_HW_BLK_MAX; type++) {
102 list_for_each_entry(blk, &rm->hw_blks[type], list) {
103 if (!blk->rsvp && !blk->rsvp_nxt)
104 continue;
105
106 DRM_DEBUG_KMS("%d rsvp[s%ue%u->s%ue%u] %d %d\n", stage,
107 (blk->rsvp) ? blk->rsvp->seq : 0,
108 (blk->rsvp) ? blk->rsvp->enc_id : 0,
109 (blk->rsvp_nxt) ? blk->rsvp_nxt->seq : 0,
110 (blk->rsvp_nxt) ? blk->rsvp_nxt->enc_id : 0,
111 blk->type, blk->id);
112 }
113 }
114}
115
116struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm)
117{
118 return rm->hw_mdp;
119}
120
121void dpu_rm_init_hw_iter(52void dpu_rm_init_hw_iter(
122 struct dpu_rm_hw_iter *iter,53 struct dpu_rm_hw_iter *iter,
123 uint32_t enc_id,54 uint32_t enc_id,
@@ -148,15 +79,7 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct dpu_rm_hw_iter *i) · 24 unmodified lines
148 i->blk = list_prepare_entry(i->blk, blk_list, list);79 i->blk = list_prepare_entry(i->blk, blk_list, list);
149 80
150 list_for_each_entry_continue(i->blk, blk_list, list) {81 list_for_each_entry_continue(i->blk, blk_list, list) {
151 struct dpu_rm_rsvp *rsvp = i->blk->rsvp;82 if (i->enc_id == i->blk->enc_id) {
152
153 if (i->blk->type != i->type) {
154 DPU_ERROR("found incorrect block type %d on %d list\n",
155 i->blk->type, i->type);
156 return false;
157 }
158
159 if ((i->enc_id == 0) || (rsvp && rsvp->enc_id == i->enc_id)) {
160 i->hw = i->blk->hw;83 i->hw = i->blk->hw;
161 DPU_DEBUG("found type %d id %d for enc %d\n",84 DPU_DEBUG("found type %d id %d for enc %d\n",
162 i->type, i->blk->id, i->enc_id);85 i->type, i->blk->id, i->enc_id);
@@ -208,34 +131,18 @@ static void _dpu_rm_hw_destroy(enum dpu_hw_blk_type type, void *hw) · 45 unmodified lines
208 131
209int dpu_rm_destroy(struct dpu_rm *rm)132int dpu_rm_destroy(struct dpu_rm *rm)
210{133{
211
212 struct dpu_rm_rsvp *rsvp_cur, *rsvp_nxt;
213 struct dpu_rm_hw_blk *hw_cur, *hw_nxt;134 struct dpu_rm_hw_blk *hw_cur, *hw_nxt;
214 enum dpu_hw_blk_type type;135 enum dpu_hw_blk_type type;
215 136
216 if (!rm) {
217 DPU_ERROR("invalid rm\n");
218 return -EINVAL;
219 }
220
221 list_for_each_entry_safe(rsvp_cur, rsvp_nxt, &rm->rsvps, list) {
222 list_del(&rsvp_cur->list);
223 kfree(rsvp_cur);
224 }
225
226
227 for (type = 0; type < DPU_HW_BLK_MAX; type++) {137 for (type = 0; type < DPU_HW_BLK_MAX; type++) {
228 list_for_each_entry_safe(hw_cur, hw_nxt, &rm->hw_blks[type],138 list_for_each_entry_safe(hw_cur, hw_nxt, &rm->hw_blks[type],
229 list) {139 list) {
230 list_del(&hw_cur->list);140 list_del(&hw_cur->list);
231 _dpu_rm_hw_destroy(hw_cur->type, hw_cur->hw);141 _dpu_rm_hw_destroy(type, hw_cur->hw);
232 kfree(hw_cur);142 kfree(hw_cur);
233 }143 }
234 }144 }
235 145
236 dpu_hw_mdp_destroy(rm->hw_mdp);
237 rm->hw_mdp = NULL;
238
239 mutex_destroy(&rm->rm_lock);146 mutex_destroy(&rm->rm_lock);
240 147
241 return 0;148 return 0;
@@ -250,11 +157,8 @@ static int _dpu_rm_hw_blk_create( · 8 unmodified lines
250 void *hw_catalog_info)157 void *hw_catalog_info)
251{158{
252 struct dpu_rm_hw_blk *blk;159 struct dpu_rm_hw_blk *blk;
253 struct dpu_hw_mdp *hw_mdp;
254 void *hw;160 void *hw;
255 161
256 hw_mdp = rm->hw_mdp;
257
258 switch (type) {162 switch (type) {
259 case DPU_HW_BLK_LM:163 case DPU_HW_BLK_LM:
260 hw = dpu_hw_lm_init(id, mmio, cat);164 hw = dpu_hw_lm_init(id, mmio, cat);
@@ -290,9 +194,9 @@ static int _dpu_rm_hw_blk_create( · 29 unmodified lines
290 return -ENOMEM;194 return -ENOMEM;
291 }195 }
292 196
293 blk->type = type;
294 blk->id = id;197 blk->id = id;
295 blk->hw = hw;198 blk->hw = hw;
199 blk->enc_id = 0;
296 list_add_tail(&blk->list, &rm->hw_blks[type]);200 list_add_tail(&blk->list, &rm->hw_blks[type]);
297 201
298 return 0;202 return 0;
@@ -300,13 +204,12 @@ static int _dpu_rm_hw_blk_create( · 1 unmodified line
300 204
301int dpu_rm_init(struct dpu_rm *rm,205int dpu_rm_init(struct dpu_rm *rm,
302 struct dpu_mdss_cfg *cat,206 struct dpu_mdss_cfg *cat,
303 void __iomem *mmio,207 void __iomem *mmio)
304 struct drm_device *dev)
305{208{
306 int rc, i;209 int rc, i;
307 enum dpu_hw_blk_type type;210 enum dpu_hw_blk_type type;
308 211
309 if (!rm || !cat || !mmio || !dev) {212 if (!rm || !cat || !mmio) {
310 DPU_ERROR("invalid kms\n");213 DPU_ERROR("invalid kms\n");
311 return -EINVAL;214 return -EINVAL;
312 }215 }
@@ -316,21 +219,9 @@ int dpu_rm_init(struct dpu_rm *rm, · 3 unmodified lines
316 219
317 mutex_init(&rm->rm_lock);220 mutex_init(&rm->rm_lock);
318 221
319 INIT_LIST_HEAD(&rm->rsvps);
320 for (type = 0; type < DPU_HW_BLK_MAX; type++)222 for (type = 0; type < DPU_HW_BLK_MAX; type++)
321 INIT_LIST_HEAD(&rm->hw_blks[type]);223 INIT_LIST_HEAD(&rm->hw_blks[type]);
322 224
323 rm->dev = dev;
324
325 /* Some of the sub-blocks require an mdptop to be created */
326 rm->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, mmio, cat);
327 if (IS_ERR_OR_NULL(rm->hw_mdp)) {
328 rc = PTR_ERR(rm->hw_mdp);
329 rm->hw_mdp = NULL;
330 DPU_ERROR("failed: mdp hw not available\n");
331 goto fail;
332 }
333
334 /* Interrogate HW catalog and create tracking items for hw blocks */225 /* Interrogate HW catalog and create tracking items for hw blocks */
335 for (i = 0; i < cat->mixer_count; i++) {226 for (i = 0; i < cat->mixer_count; i++) {
336 struct dpu_lm_cfg *lm = &cat->mixer[i];227 struct dpu_lm_cfg *lm = &cat->mixer[i];
@@ -410,7 +301,7 @@ static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top) · 73 unmodified lines
410 * proposed use case requirements, incl. hardwired dependent blocks like301 * proposed use case requirements, incl. hardwired dependent blocks like
411 * pingpong302 * pingpong
412 * @rm: dpu resource manager handle303 * @rm: dpu resource manager handle
413 * @rsvp: reservation currently being created304 * @enc_id: encoder id requesting for allocation
414 * @reqs: proposed use case requirements305 * @reqs: proposed use case requirements
415 * @lm: proposed layer mixer, function checks if lm, and all other hardwired306 * @lm: proposed layer mixer, function checks if lm, and all other hardwired
416 * blocks connected to the lm (pp) is available and appropriate307 * blocks connected to the lm (pp) is available and appropriate
@@ -422,7 +313,7 @@ static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top) · 5 unmodified lines
422 */313 */
423static bool _dpu_rm_check_lm_and_get_connected_blks(314static bool _dpu_rm_check_lm_and_get_connected_blks(
424 struct dpu_rm *rm,315 struct dpu_rm *rm,
425 struct dpu_rm_rsvp *rsvp,316 uint32_t enc_id,
426 struct dpu_rm_requirements *reqs,317 struct dpu_rm_requirements *reqs,
427 struct dpu_rm_hw_blk *lm,318 struct dpu_rm_hw_blk *lm,
428 struct dpu_rm_hw_blk **pp,319 struct dpu_rm_hw_blk **pp,
@@ -449,7 +340,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks( · 20 unmodified lines
449 }340 }
450 341
451 /* Already reserved? */342 /* Already reserved? */
452 if (RESERVED_BY_OTHER(lm, rsvp)) {343 if (RESERVED_BY_OTHER(lm, enc_id)) {
453 DPU_DEBUG("lm %d already reserved\n", lm_cfg->id);344 DPU_DEBUG("lm %d already reserved\n", lm_cfg->id);
454 return false;345 return false;
455 }346 }
@@ -467,7 +358,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks( · 11 unmodified lines
467 return false;358 return false;
468 }359 }
469 360
470 if (RESERVED_BY_OTHER(*pp, rsvp)) {361 if (RESERVED_BY_OTHER(*pp, enc_id)) {
471 DPU_DEBUG("lm %d pp %d already reserved\n", lm->id,362 DPU_DEBUG("lm %d pp %d already reserved\n", lm->id,
472 (*pp)->id);363 (*pp)->id);
473 return false;364 return false;
@@ -476,10 +367,8 @@ static bool _dpu_rm_check_lm_and_get_connected_blks( · 2 unmodified lines
476 return true;367 return true;
477}368}
478 369
479static int _dpu_rm_reserve_lms(370static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id,
480 struct dpu_rm *rm,371 struct dpu_rm_requirements *reqs)
481 struct dpu_rm_rsvp *rsvp,
482 struct dpu_rm_requirements *reqs)
483 372
484{373{
485 struct dpu_rm_hw_blk *lm[MAX_BLOCKS];374 struct dpu_rm_hw_blk *lm[MAX_BLOCKS];
@@ -504,7 +393,7 @@ static int _dpu_rm_reserve_lms( · 18 unmodified lines
504 lm[lm_count] = iter_i.blk;393 lm[lm_count] = iter_i.blk;
505 394
506 if (!_dpu_rm_check_lm_and_get_connected_blks(395 if (!_dpu_rm_check_lm_and_get_connected_blks(
507 rm, rsvp, reqs, lm[lm_count],396 rm, enc_id, reqs, lm[lm_count],
508 &pp[lm_count], NULL))397 &pp[lm_count], NULL))
509 continue;398 continue;
510 399
@@ -519,7 +408,7 @@ static int _dpu_rm_reserve_lms( · 8 unmodified lines
519 continue;408 continue;
520 409
521 if (!_dpu_rm_check_lm_and_get_connected_blks(410 if (!_dpu_rm_check_lm_and_get_connected_blks(
522 rm, rsvp, reqs, iter_j.blk,411 rm, enc_id, reqs, iter_j.blk,
523 &pp[lm_count], iter_i.blk))412 &pp[lm_count], iter_i.blk))
524 continue;413 continue;
525 414
@@ -537,11 +426,10 @@ static int _dpu_rm_reserve_lms( · 11 unmodified lines
537 if (!lm[i])426 if (!lm[i])
538 break;427 break;
539 428
540 lm[i]->rsvp_nxt = rsvp;429 lm[i]->enc_id = enc_id;
541 pp[i]->rsvp_nxt = rsvp;430 pp[i]->enc_id = enc_id;
542 431
543 trace_dpu_rm_reserve_lms(lm[i]->id, lm[i]->type, rsvp->enc_id,432 trace_dpu_rm_reserve_lms(lm[i]->id, enc_id, pp[i]->id);
544 pp[i]->id);
545 }433 }
546 434
547 return rc;435 return rc;
@@ -549,7 +437,7 @@ static int _dpu_rm_reserve_lms( · 1 unmodified line
549 437
550static int _dpu_rm_reserve_ctls(438static int _dpu_rm_reserve_ctls(
551 struct dpu_rm *rm,439 struct dpu_rm *rm,
552 struct dpu_rm_rsvp *rsvp,440 uint32_t enc_id,
553 const struct msm_display_topology *top)441 const struct msm_display_topology *top)
554{442{
555 struct dpu_rm_hw_blk *ctls[MAX_BLOCKS];443 struct dpu_rm_hw_blk *ctls[MAX_BLOCKS];
@@ -570,7 +458,7 @@ static int _dpu_rm_reserve_ctls( · 14 unmodified lines
570 unsigned long features = ctl->caps->features;458 unsigned long features = ctl->caps->features;
571 bool has_split_display;459 bool has_split_display;
572 460
573 if (RESERVED_BY_OTHER(iter.blk, rsvp))461 if (RESERVED_BY_OTHER(iter.blk, enc_id))
574 continue;462 continue;
575 463
576 has_split_display = BIT(DPU_CTL_SPLIT_DISPLAY) & features;464 has_split_display = BIT(DPU_CTL_SPLIT_DISPLAY) & features;
@@ -591,9 +479,8 @@ static int _dpu_rm_reserve_ctls( · 14 unmodified lines
591 return -ENAVAIL;479 return -ENAVAIL;
592 480
593 for (i = 0; i < ARRAY_SIZE(ctls) && i < num_ctls; i++) {481 for (i = 0; i < ARRAY_SIZE(ctls) && i < num_ctls; i++) {
594 ctls[i]->rsvp_nxt = rsvp;482 ctls[i]->enc_id = enc_id;
595 trace_dpu_rm_reserve_ctls(ctls[i]->id, ctls[i]->type,483 trace_dpu_rm_reserve_ctls(ctls[i]->id, enc_id);
596 rsvp->enc_id);
597 }484 }
598 485
599 return 0;486 return 0;
@@ -601,7 +488,7 @@ static int _dpu_rm_reserve_ctls( · 1 unmodified line
601 488
602static int _dpu_rm_reserve_intf(489static int _dpu_rm_reserve_intf(
603 struct dpu_rm *rm,490 struct dpu_rm *rm,
604 struct dpu_rm_rsvp *rsvp,491 uint32_t enc_id,
605 uint32_t id,492 uint32_t id,
606 enum dpu_hw_blk_type type)493 enum dpu_hw_blk_type type)
607{494{
@@ -614,14 +501,13 @@ static int _dpu_rm_reserve_intf( · 6 unmodified lines
614 if (iter.blk->id != id)501 if (iter.blk->id != id)
615 continue;502 continue;
616 503
617 if (RESERVED_BY_OTHER(iter.blk, rsvp)) {504 if (RESERVED_BY_OTHER(iter.blk, enc_id)) {
618 DPU_ERROR("type %d id %d already reserved\n", type, id);505 DPU_ERROR("type %d id %d already reserved\n", type, id);
619 return -ENAVAIL;506 return -ENAVAIL;
620 }507 }
621 508
622 iter.blk->rsvp_nxt = rsvp;509 iter.blk->enc_id = enc_id;
623 trace_dpu_rm_reserve_intf(iter.blk->id, iter.blk->type,510 trace_dpu_rm_reserve_intf(iter.blk->id, enc_id);
624 rsvp->enc_id);
625 break;511 break;
626 }512 }
627 513
@@ -636,7 +522,7 @@ static int _dpu_rm_reserve_intf( · 8 unmodified lines
636 522
637static int _dpu_rm_reserve_intf_related_hw(523static int _dpu_rm_reserve_intf_related_hw(
638 struct dpu_rm *rm,524 struct dpu_rm *rm,
639 struct dpu_rm_rsvp *rsvp,525 uint32_t enc_id,
640 struct dpu_encoder_hw_resources *hw_res)526 struct dpu_encoder_hw_resources *hw_res)
641{527{
642 int i, ret = 0;528 int i, ret = 0;
@@ -646,7 +532,7 @@ static int _dpu_rm_reserve_intf_related_hw( · 3 unmodified lines
646 if (hw_res->intfs[i] == INTF_MODE_NONE)532 if (hw_res->intfs[i] == INTF_MODE_NONE)
647 continue;533 continue;
648 id = i + INTF_0;534 id = i + INTF_0;
649 ret = _dpu_rm_reserve_intf(rm, rsvp, id,535 ret = _dpu_rm_reserve_intf(rm, enc_id, id,
650 DPU_HW_BLK_INTF);536 DPU_HW_BLK_INTF);
651 if (ret)537 if (ret)
652 return ret;538 return ret;
@@ -655,33 +541,27 @@ static int _dpu_rm_reserve_intf_related_hw( · 2 unmodified lines
655 return ret;541 return ret;
656}542}
657 543
658static int _dpu_rm_make_next_rsvp(544static int _dpu_rm_make_reservation(
659 struct dpu_rm *rm,545 struct dpu_rm *rm,
660 struct drm_encoder *enc,546 struct drm_encoder *enc,
661 struct drm_crtc_state *crtc_state,547 struct drm_crtc_state *crtc_state,
662 struct dpu_rm_rsvp *rsvp,
663 struct dpu_rm_requirements *reqs)548 struct dpu_rm_requirements *reqs)
664{549{
665 int ret;550 int ret;
666 551
667 /* Create reservation info, tag reserved blocks with it as we go */552 ret = _dpu_rm_reserve_lms(rm, enc->base.id, reqs);
668 rsvp->seq = ++rm->rsvp_next_seq;
669 rsvp->enc_id = enc->base.id;
670 list_add_tail(&rsvp->list, &rm->rsvps);
671
672 ret = _dpu_rm_reserve_lms(rm, rsvp, reqs);
673 if (ret) {553 if (ret) {
674 DPU_ERROR("unable to find appropriate mixers\n");554 DPU_ERROR("unable to find appropriate mixers\n");
675 return ret;555 return ret;
676 }556 }
677 557
678 ret = _dpu_rm_reserve_ctls(rm, rsvp, &reqs->topology);558 ret = _dpu_rm_reserve_ctls(rm, enc->base.id, &reqs->topology);
679 if (ret) {559 if (ret) {
680 DPU_ERROR("unable to find appropriate CTL\n");560 DPU_ERROR("unable to find appropriate CTL\n");
681 return ret;561 return ret;
682 }562 }
683 563
684 ret = _dpu_rm_reserve_intf_related_hw(rm, rsvp, &reqs->hw_res);564 ret = _dpu_rm_reserve_intf_related_hw(rm, enc->base.id, &reqs->hw_res);
685 if (ret)565 if (ret)
686 return ret;566 return ret;
687 567
@@ -706,108 +586,31 @@ static int _dpu_rm_populate_requirements( · 18 unmodified lines
706 return 0;586 return 0;
707}587}
708 588
709static struct dpu_rm_rsvp *_dpu_rm_get_rsvp(589static void _dpu_rm_release_reservation(struct dpu_rm *rm, uint32_t enc_id)
710 struct dpu_rm *rm,
711 struct drm_encoder *enc)
712{590{
713 struct dpu_rm_rsvp *i;
714
715 if (!rm || !enc) {
716 DPU_ERROR("invalid params\n");
717 return NULL;
718 }
719
720 if (list_empty(&rm->rsvps))
721 return NULL;
722
723 list_for_each_entry(i, &rm->rsvps, list)
724 if (i->enc_id == enc->base.id)
725 return i;
726
727 return NULL;
728}
729
730/**
731 * _dpu_rm_release_rsvp - release resources and release a reservation
732 * @rm: KMS handle
733 * @rsvp: RSVP pointer to release and release resources for
734 */
735static void _dpu_rm_release_rsvp(struct dpu_rm *rm, struct dpu_rm_rsvp *rsvp)
736{
737 struct dpu_rm_rsvp *rsvp_c, *rsvp_n;
738 struct dpu_rm_hw_blk *blk;591 struct dpu_rm_hw_blk *blk;
739 enum dpu_hw_blk_type type;592 enum dpu_hw_blk_type type;
740 593
741 if (!rsvp)
742 return;
743
744 DPU_DEBUG("rel rsvp %d enc %d\n", rsvp->seq, rsvp->enc_id);
745
746 list_for_each_entry_safe(rsvp_c, rsvp_n, &rm->rsvps, list) {
747 if (rsvp == rsvp_c) {
748 list_del(&rsvp_c->list);
749 break;
750 }
751 }
752
753 for (type = 0; type < DPU_HW_BLK_MAX; type++) {594 for (type = 0; type < DPU_HW_BLK_MAX; type++) {
754 list_for_each_entry(blk, &rm->hw_blks[type], list) {595 list_for_each_entry(blk, &rm->hw_blks[type], list) {
755 if (blk->rsvp == rsvp) {596 if (blk->enc_id == enc_id) {
756 blk->rsvp = NULL;597 blk->enc_id = 0;
757 DPU_DEBUG("rel rsvp %d enc %d %d %d\n",598 DPU_DEBUG("rel enc %d %d %d\n", enc_id,
758 rsvp->seq, rsvp->enc_id,599 type, blk->id);
759 blk->type, blk->id);
760 }
761 if (blk->rsvp_nxt == rsvp) {
762 blk->rsvp_nxt = NULL;
763 DPU_DEBUG("rel rsvp_nxt %d enc %d %d %d\n",
764 rsvp->seq, rsvp->enc_id,
765 blk->type, blk->id);
766 }600 }
767 }601 }
768 }602 }
769
770 kfree(rsvp);
771}603}
772 604
773void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc)605void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc)
774{606{
775 struct dpu_rm_rsvp *rsvp;
776
777 if (!rm || !enc) {
778 DPU_ERROR("invalid params\n");
779 return;
780 }
781
782 mutex_lock(&rm->rm_lock);607 mutex_lock(&rm->rm_lock);
783 608
784 rsvp = _dpu_rm_get_rsvp(rm, enc);609 _dpu_rm_release_reservation(rm, enc->base.id);
785 if (!rsvp) {
786 DPU_ERROR("failed to find rsvp for enc %d\n", enc->base.id);
787 goto end;
788 }
789 610
790 _dpu_rm_release_rsvp(rm, rsvp);
791end:
792 mutex_unlock(&rm->rm_lock);611 mutex_unlock(&rm->rm_lock);
793}612}
794 613
795static void _dpu_rm_commit_rsvp(struct dpu_rm *rm, struct dpu_rm_rsvp *rsvp)
796{
797 struct dpu_rm_hw_blk *blk;
798 enum dpu_hw_blk_type type;
799
800 /* Swap next rsvp to be the active */
801 for (type = 0; type < DPU_HW_BLK_MAX; type++) {
802 list_for_each_entry(blk, &rm->hw_blks[type], list) {
803 if (blk->rsvp_nxt) {
804 blk->rsvp = blk->rsvp_nxt;
805 blk->rsvp_nxt = NULL;
806 }
807 }
808 }
809}
810
811int dpu_rm_reserve(614int dpu_rm_reserve(
812 struct dpu_rm *rm,615 struct dpu_rm *rm,
813 struct drm_encoder *enc,616 struct drm_encoder *enc,
@@ -815,7 +618,6 @@ int dpu_rm_reserve( · 1 unmodified line
815 struct msm_display_topology topology,618 struct msm_display_topology topology,
816 bool test_only)619 bool test_only)
817{620{
818 struct dpu_rm_rsvp *rsvp_cur, *rsvp_nxt;
819 struct dpu_rm_requirements reqs;621 struct dpu_rm_requirements reqs;
820 int ret;622 int ret;
821 623
@@ -828,8 +630,6 @@ int dpu_rm_reserve( · 6 unmodified lines
828 630
829 mutex_lock(&rm->rm_lock);631 mutex_lock(&rm->rm_lock);
830 632
831 _dpu_rm_print_rsvps(rm, DPU_RM_STAGE_BEGIN);
832
833 ret = _dpu_rm_populate_requirements(rm, enc, crtc_state, &reqs,633 ret = _dpu_rm_populate_requirements(rm, enc, crtc_state, &reqs,
834 topology);634 topology);
835 if (ret) {635 if (ret) {
@@ -837,50 +637,17 @@ int dpu_rm_reserve( · 1 unmodified line
837 goto end;637 goto end;
838 }638 }
839 639
840 /*640 ret = _dpu_rm_make_reservation(rm, enc, crtc_state, &reqs);
841 * We only support one active reservation per-hw-block. But to implement
842 * transactional semantics for test-only, and for allowing failure while
843 * modifying your existing reservation, over the course of this
844 * function we can have two reservations:
845 * Current: Existing reservation
846 * Next: Proposed reservation. The proposed reservation may fail, or may
847 * be discarded if in test-only mode.
848 * If reservation is successful, and we're not in test-only, then we
849 * replace the current with the next.
850 */
851 rsvp_nxt = kzalloc(sizeof(*rsvp_nxt), GFP_KERNEL);
852 if (!rsvp_nxt) {
853 ret = -ENOMEM;
854 goto end;
855 }
856
857 rsvp_cur = _dpu_rm_get_rsvp(rm, enc);
858
859 /* Check the proposed reservation, store it in hw's "next" field */
860 ret = _dpu_rm_make_next_rsvp(rm, enc, crtc_state, rsvp_nxt, &reqs);
861
862 _dpu_rm_print_rsvps(rm, DPU_RM_STAGE_AFTER_RSVPNEXT);
863
864 if (ret) {641 if (ret) {
865 DPU_ERROR("failed to reserve hw resources: %d\n", ret);642 DPU_ERROR("failed to reserve hw resources: %d\n", ret);
866 _dpu_rm_release_rsvp(rm, rsvp_nxt);643 _dpu_rm_release_reservation(rm, enc->base.id);
867 } else if (test_only) {644 } else if (test_only) {
868 /*645 /* test_only: test the reservation and then undo */
869 * Normally, if test_only, test the reservation and then undo646 DPU_DEBUG("test_only: discard test [enc: %d]\n",
870 * However, if the user requests LOCK, then keep the reservation647 enc->base.id);
871 * made during the atomic_check phase.648 _dpu_rm_release_reservation(rm, enc->base.id);
872 */
873 DPU_DEBUG("test_only: discard test rsvp[s%de%d]\n",
874 rsvp_nxt->seq, rsvp_nxt->enc_id);
875 _dpu_rm_release_rsvp(rm, rsvp_nxt);
876 } else {
877 _dpu_rm_release_rsvp(rm, rsvp_cur);
878
879 _dpu_rm_commit_rsvp(rm, rsvp_nxt);
880 }649 }
881 650
882 _dpu_rm_print_rsvps(rm, DPU_RM_STAGE_FINAL);
883
884end:651end:
885 mutex_unlock(&rm->rm_lock);652 mutex_unlock(&rm->rm_lock);
886 653
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h+1−27
@@ -22,22 +22,14 @@ · 21 unmodified lines
22 22
23/**23/**
24 * struct dpu_rm - DPU dynamic hardware resource manager24 * struct dpu_rm - DPU dynamic hardware resource manager
25 * @dev: device handle for event logging purposes
26 * @rsvps: list of hardware reservations by each crtc->encoder->connector
27 * @hw_blks: array of lists of hardware resources present in the system, one25 * @hw_blks: array of lists of hardware resources present in the system, one
28 * list per type of hardware block26 * list per type of hardware block
29 * @hw_mdp: hardware object for mdp_top
30 * @lm_max_width: cached layer mixer maximum width27 * @lm_max_width: cached layer mixer maximum width
31 * @rsvp_next_seq: sequence number for next reservation for debugging purposes
32 * @rm_lock: resource manager mutex28 * @rm_lock: resource manager mutex
33 */29 */
34struct dpu_rm {30struct dpu_rm {
35 struct drm_device *dev;
36 struct list_head rsvps;
37 struct list_head hw_blks[DPU_HW_BLK_MAX];31 struct list_head hw_blks[DPU_HW_BLK_MAX];
38 struct dpu_hw_mdp *hw_mdp;
39 uint32_t lm_max_width;32 uint32_t lm_max_width;
40 uint32_t rsvp_next_seq;
41 struct mutex rm_lock;33 struct mutex rm_lock;
42};34};
43 35
@@ -67,13 +59,11 @@ struct dpu_rm_hw_iter { · 23 unmodified lines
67 * @rm: DPU Resource Manager handle59 * @rm: DPU Resource Manager handle
68 * @cat: Pointer to hardware catalog60 * @cat: Pointer to hardware catalog
69 * @mmio: mapped register io address of MDP61 * @mmio: mapped register io address of MDP
70 * @dev: device handle for event logging purposes
71 * @Return: 0 on Success otherwise -ERROR62 * @Return: 0 on Success otherwise -ERROR
72 */63 */
73int dpu_rm_init(struct dpu_rm *rm,64int dpu_rm_init(struct dpu_rm *rm,
74 struct dpu_mdss_cfg *cat,65 struct dpu_mdss_cfg *cat,
75 void __iomem *mmio,66 void __iomem *mmio);
76 struct drm_device *dev);
77 67
78/**68/**
79 * dpu_rm_destroy - Free all memory allocated by dpu_rm_init69 * dpu_rm_destroy - Free all memory allocated by dpu_rm_init
@@ -111,14 +101,6 @@ int dpu_rm_reserve(struct dpu_rm *rm, · 31 unmodified lines
111 */101 */
112void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc);102void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc);
113 103
114/**
115 * dpu_rm_get_mdp - Retrieve HW block for MDP TOP.
116 * This is never reserved, and is usable by any display.
117 * @rm: DPU Resource Manager handle
118 * @Return: Pointer to hw block or NULL
119 */
120struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm);
121
122/**104/**
123 * dpu_rm_init_hw_iter - setup given iterator for new iteration over hw list105 * dpu_rm_init_hw_iter - setup given iterator for new iteration over hw list
124 * using dpu_rm_get_hw106 * using dpu_rm_get_hw
@@ -144,12 +126,4 @@ void dpu_rm_init_hw_iter( · 19 unmodified lines
144 * @Return: true on match found, false on no match found126 * @Return: true on match found, false on no match found
145 */127 */
146bool dpu_rm_get_hw(struct dpu_rm *rm, struct dpu_rm_hw_iter *iter);128bool dpu_rm_get_hw(struct dpu_rm *rm, struct dpu_rm_hw_iter *iter);
147
148/**
149 * dpu_rm_check_property_topctl - validate property bitmask before it is set
150 * @val: user's proposed topology control bitmask
151 * @Return: 0 on success or error
152 */
153int dpu_rm_check_property_topctl(uint64_t val);
154
155#endif /* __DPU_RM_H__ */129#endif /* __DPU_RM_H__ */
drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h+11−17
@@ -831,48 +831,42 @@ TRACE_EVENT(dpu_plane_disable, · 830 unmodified lines
831);831);
832 832
833DECLARE_EVENT_CLASS(dpu_rm_iter_template,833DECLARE_EVENT_CLASS(dpu_rm_iter_template,
834 TP_PROTO(uint32_t id, enum dpu_hw_blk_type type, uint32_t enc_id),834 TP_PROTO(uint32_t id, uint32_t enc_id),
835 TP_ARGS(id, type, enc_id),835 TP_ARGS(id, enc_id),
836 TP_STRUCT__entry(836 TP_STRUCT__entry(
837 __field( uint32_t, id )837 __field( uint32_t, id )
838 __field( enum dpu_hw_blk_type, type )
839 __field( uint32_t, enc_id )838 __field( uint32_t, enc_id )
840 ),839 ),
841 TP_fast_assign(840 TP_fast_assign(
842 __entry->id = id;841 __entry->id = id;
843 __entry->type = type;
844 __entry->enc_id = enc_id;842 __entry->enc_id = enc_id;
845 ),843 ),
846 TP_printk("id:%d type:%d enc_id:%u", __entry->id, __entry->type,844 TP_printk("id:%d enc_id:%u", __entry->id, __entry->enc_id)
847 __entry->enc_id)
848);845);
849DEFINE_EVENT(dpu_rm_iter_template, dpu_rm_reserve_intf,846DEFINE_EVENT(dpu_rm_iter_template, dpu_rm_reserve_intf,
850 TP_PROTO(uint32_t id, enum dpu_hw_blk_type type, uint32_t enc_id),847 TP_PROTO(uint32_t id, uint32_t enc_id),
851 TP_ARGS(id, type, enc_id)848 TP_ARGS(id, enc_id)
852);849);
853DEFINE_EVENT(dpu_rm_iter_template, dpu_rm_reserve_ctls,850DEFINE_EVENT(dpu_rm_iter_template, dpu_rm_reserve_ctls,
854 TP_PROTO(uint32_t id, enum dpu_hw_blk_type type, uint32_t enc_id),851 TP_PROTO(uint32_t id, uint32_t enc_id),
855 TP_ARGS(id, type, enc_id)852 TP_ARGS(id, enc_id)
856);853);
857 854
858TRACE_EVENT(dpu_rm_reserve_lms,855TRACE_EVENT(dpu_rm_reserve_lms,
859 TP_PROTO(uint32_t id, enum dpu_hw_blk_type type, uint32_t enc_id,856 TP_PROTO(uint32_t id, uint32_t enc_id, uint32_t pp_id),
860 uint32_t pp_id),857 TP_ARGS(id, enc_id, pp_id),
861 TP_ARGS(id, type, enc_id, pp_id),
862 TP_STRUCT__entry(858 TP_STRUCT__entry(
863 __field( uint32_t, id )859 __field( uint32_t, id )
864 __field( enum dpu_hw_blk_type, type )
865 __field( uint32_t, enc_id )860 __field( uint32_t, enc_id )
866 __field( uint32_t, pp_id )861 __field( uint32_t, pp_id )
867 ),862 ),
868 TP_fast_assign(863 TP_fast_assign(
869 __entry->id = id;864 __entry->id = id;
870 __entry->type = type;
871 __entry->enc_id = enc_id;865 __entry->enc_id = enc_id;
872 __entry->pp_id = pp_id;866 __entry->pp_id = pp_id;
873 ),867 ),
874 TP_printk("id:%d type:%d enc_id:%u pp_id:%u", __entry->id,868 TP_printk("id:%d enc_id:%u pp_id:%u", __entry->id,
875 __entry->type, __entry->enc_id, __entry->pp_id)869 __entry->enc_id, __entry->pp_id)
876);870);
877 871
878TRACE_EVENT(dpu_vbif_wait_xin_halt_fail,872TRACE_EVENT(dpu_vbif_wait_xin_halt_fail,
drivers/gpu/drm/msm/msm_drv.c+34−92
@@ -207,62 +207,44 @@ u32 msm_readl(const void __iomem *addr) · 206 unmodified lines
207 return val;207 return val;
208}208}
209 209
210struct vblank_event {210struct msm_vblank_work {
211 struct list_head node;211 struct work_struct work;
212 int crtc_id;212 int crtc_id;
213 bool enable;213 bool enable;
214 struct msm_drm_private *priv;
214};215};
215 216
216static void vblank_ctrl_worker(struct kthread_work *work)217static void vblank_ctrl_worker(struct work_struct *work)
217{218{
218 struct msm_vblank_ctrl *vbl_ctrl = container_of(work,219 struct msm_vblank_work *vbl_work = container_of(work,
219 struct msm_vblank_ctrl, work);220 struct msm_vblank_work, work);
220 struct msm_drm_private *priv = container_of(vbl_ctrl,221 struct msm_drm_private *priv = vbl_work->priv;
221 struct msm_drm_private, vblank_ctrl);
222 struct msm_kms *kms = priv->kms;222 struct msm_kms *kms = priv->kms;
223 struct vblank_event *vbl_ev, *tmp;
224 unsigned long flags;
225
226 spin_lock_irqsave(&vbl_ctrl->lock, flags);
227 list_for_each_entry_safe(vbl_ev, tmp, &vbl_ctrl->event_list, node) {
228 list_del(&vbl_ev->node);
229 spin_unlock_irqrestore(&vbl_ctrl->lock, flags);
230
231 if (vbl_ev->enable)
232 kms->funcs->enable_vblank(kms,
233 priv->crtcs[vbl_ev->crtc_id]);
234 else
235 kms->funcs->disable_vblank(kms,
236 priv->crtcs[vbl_ev->crtc_id]);
237
238 kfree(vbl_ev);
239 223
240 spin_lock_irqsave(&vbl_ctrl->lock, flags);224 if (vbl_work->enable)
241 }225 kms->funcs->enable_vblank(kms, priv->crtcs[vbl_work->crtc_id]);
226 else
227 kms->funcs->disable_vblank(kms, priv->crtcs[vbl_work->crtc_id]);
242 228
243 spin_unlock_irqrestore(&vbl_ctrl->lock, flags);229 kfree(vbl_work);
244}230}
245 231
246static int vblank_ctrl_queue_work(struct msm_drm_private *priv,232static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
247 int crtc_id, bool enable)233 int crtc_id, bool enable)
248{234{
249 struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl;235 struct msm_vblank_work *vbl_work;
250 struct vblank_event *vbl_ev;
251 unsigned long flags;
252 236
253 vbl_ev = kzalloc(sizeof(*vbl_ev), GFP_ATOMIC);237 vbl_work = kzalloc(sizeof(*vbl_work), GFP_ATOMIC);
254 if (!vbl_ev)238 if (!vbl_work)
255 return -ENOMEM;239 return -ENOMEM;
256 240
257 vbl_ev->crtc_id = crtc_id;241 INIT_WORK(&vbl_work->work, vblank_ctrl_worker);
258 vbl_ev->enable = enable;
259 242
260 spin_lock_irqsave(&vbl_ctrl->lock, flags);243 vbl_work->crtc_id = crtc_id;
261 list_add_tail(&vbl_ev->node, &vbl_ctrl->event_list);244 vbl_work->enable = enable;
262 spin_unlock_irqrestore(&vbl_ctrl->lock, flags);245 vbl_work->priv = priv;
263 246
264 kthread_queue_work(&priv->disp_thread[crtc_id].worker,247 queue_work(priv->wq, &vbl_work->work);
265 &vbl_ctrl->work);
266 248
267 return 0;249 return 0;
268}250}
@@ -274,31 +256,20 @@ static int msm_drm_uninit(struct device *dev) · 5 unmodified lines
274 struct msm_drm_private *priv = ddev->dev_private;256 struct msm_drm_private *priv = ddev->dev_private;
275 struct msm_kms *kms = priv->kms;257 struct msm_kms *kms = priv->kms;
276 struct msm_mdss *mdss = priv->mdss;258 struct msm_mdss *mdss = priv->mdss;
277 struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl;
278 struct vblank_event *vbl_ev, *tmp;
279 int i;259 int i;
280 260
281 /* We must cancel and cleanup any pending vblank enable/disable261 /* We must cancel and cleanup any pending vblank enable/disable
282 * work before drm_irq_uninstall() to avoid work re-enabling an262 * work before drm_irq_uninstall() to avoid work re-enabling an
283 * irq after uninstall has disabled it.263 * irq after uninstall has disabled it.
284 */264 */
285 kthread_flush_work(&vbl_ctrl->work);
286 list_for_each_entry_safe(vbl_ev, tmp, &vbl_ctrl->event_list, node) {
287 list_del(&vbl_ev->node);
288 kfree(vbl_ev);
289 }
290 265
291 /* clean up display commit/event worker threads */266 flush_workqueue(priv->wq);
292 for (i = 0; i < priv->num_crtcs; i++) {267 destroy_workqueue(priv->wq);
293 if (priv->disp_thread[i].thread) {
294 kthread_flush_worker(&priv->disp_thread[i].worker);
295 kthread_stop(priv->disp_thread[i].thread);
296 priv->disp_thread[i].thread = NULL;
297 }
298 268
269 /* clean up event worker threads */
270 for (i = 0; i < priv->num_crtcs; i++) {
299 if (priv->event_thread[i].thread) {271 if (priv->event_thread[i].thread) {
300 kthread_flush_worker(&priv->event_thread[i].worker);272 kthread_destroy_worker(&priv->event_thread[i].worker);
301 kthread_stop(priv->event_thread[i].thread);
302 priv->event_thread[i].thread = NULL;273 priv->event_thread[i].thread = NULL;
303 }274 }
304 }275 }
@@ -323,9 +294,6 @@ static int msm_drm_uninit(struct device *dev) · 18 unmodified lines
323 drm_irq_uninstall(ddev);294 drm_irq_uninstall(ddev);
324 pm_runtime_put_sync(dev);295 pm_runtime_put_sync(dev);
325 296
326 flush_workqueue(priv->wq);
327 destroy_workqueue(priv->wq);
328
329 if (kms && kms->funcs)297 if (kms && kms->funcs)
330 kms->funcs->destroy(kms);298 kms->funcs->destroy(kms);
331 299
@@ -490,9 +458,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) · 158 unmodified lines
490 priv->wq = alloc_ordered_workqueue("msm", 0);458 priv->wq = alloc_ordered_workqueue("msm", 0);
491 459
492 INIT_LIST_HEAD(&priv->inactive_list);460 INIT_LIST_HEAD(&priv->inactive_list);
493 INIT_LIST_HEAD(&priv->vblank_ctrl.event_list);
494 kthread_init_work(&priv->vblank_ctrl.work, vblank_ctrl_worker);
495 spin_lock_init(&priv->vblank_ctrl.lock);
496 461
497 drm_mode_config_init(ddev);462 drm_mode_config_init(ddev);
498 463
@@ -554,27 +519,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) · 55 unmodified lines
554 */519 */
555 param.sched_priority = 16;520 param.sched_priority = 16;
556 for (i = 0; i < priv->num_crtcs; i++) {521 for (i = 0; i < priv->num_crtcs; i++) {
557
558 /* initialize display thread */
559 priv->disp_thread[i].crtc_id = priv->crtcs[i]->base.id;
560 kthread_init_worker(&priv->disp_thread[i].worker);
561 priv->disp_thread[i].dev = ddev;
562 priv->disp_thread[i].thread =
563 kthread_run(kthread_worker_fn,
564 &priv->disp_thread[i].worker,
565 "crtc_commit:%d", priv->disp_thread[i].crtc_id);
566 if (IS_ERR(priv->disp_thread[i].thread)) {
567 DRM_DEV_ERROR(dev, "failed to create crtc_commit kthread\n");
568 priv->disp_thread[i].thread = NULL;
569 goto err_msm_uninit;
570 }
571
572 ret = sched_setscheduler(priv->disp_thread[i].thread,
573 SCHED_FIFO, &param);
574 if (ret)
575 dev_warn(dev, "disp_thread set priority failed: %d\n",
576 ret);
577
578 /* initialize event thread */522 /* initialize event thread */
579 priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id;523 priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id;
580 kthread_init_worker(&priv->event_thread[i].worker);524 kthread_init_worker(&priv->event_thread[i].worker);
@@ -589,13 +533,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) · 8 unmodified lines
589 goto err_msm_uninit;533 goto err_msm_uninit;
590 }534 }
591 535
592 /**
593 * event thread should also run at same priority as disp_thread
594 * because it is handling frame_done events. A lower priority
595 * event thread and higher priority disp_thread can causes
596 * frame_pending counters beyond 2. This can lead to commit
597 * failure at crtc commit level.
598 */
599 ret = sched_setscheduler(priv->event_thread[i].thread,536 ret = sched_setscheduler(priv->event_thread[i].thread,
600 SCHED_FIFO, &param);537 SCHED_FIFO, &param);
601 if (ret)538 if (ret)
@@ -914,8 +851,12 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, · 312 unmodified lines
914 ret = -EINVAL;851 ret = -EINVAL;
915 break;852 break;
916 }853 }
917 ret = copy_from_user(msm_obj->name,854 if (copy_from_user(msm_obj->name, u64_to_user_ptr(args->value),
918 u64_to_user_ptr(args->value), args->len);855 args->len)) {
856 msm_obj->name[0] = '\0';
857 ret = -EFAULT;
858 break;
859 }
919 msm_obj->name[args->len] = '\0';860 msm_obj->name[args->len] = '\0';
920 for (i = 0; i < args->len; i++) {861 for (i = 0; i < args->len; i++) {
921 if (!isprint(msm_obj->name[i])) {862 if (!isprint(msm_obj->name[i])) {
@@ -931,8 +872,9 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, · 9 unmodified lines
931 }872 }
932 args->len = strlen(msm_obj->name);873 args->len = strlen(msm_obj->name);
933 if (args->value) {874 if (args->value) {
934 ret = copy_to_user(u64_to_user_ptr(args->value),875 if (copy_to_user(u64_to_user_ptr(args->value),
935 msm_obj->name, args->len);876 msm_obj->name, args->len))
877 ret = -EFAULT;
936 }878 }
937 break;879 break;
938 }880 }
drivers/gpu/drm/msm/msm_drv.h+1−9
@@ -77,12 +77,6 @@ enum msm_mdp_plane_property { · 76 unmodified lines
77 PLANE_PROP_MAX_NUM77 PLANE_PROP_MAX_NUM
78};78};
79 79
80struct msm_vblank_ctrl {
81 struct kthread_work work;
82 struct list_head event_list;
83 spinlock_t lock;
84};
85
86#define MSM_GPU_MAX_RINGS 480#define MSM_GPU_MAX_RINGS 4
87#define MAX_H_TILES_PER_DISPLAY 281#define MAX_H_TILES_PER_DISPLAY 2
88 82
@@ -126,7 +120,7 @@ struct msm_display_topology { · 37 unmodified lines
126 120
127/**121/**
128 * struct msm_display_info - defines display properties122 * struct msm_display_info - defines display properties
129 * @intf_type: DRM_MODE_CONNECTOR_ display type123 * @intf_type: DRM_MODE_ENCODER_ type
130 * @capabilities: Bitmask of display flags124 * @capabilities: Bitmask of display flags
131 * @num_of_h_tiles: Number of horizontal tiles in case of split interface125 * @num_of_h_tiles: Number of horizontal tiles in case of split interface
132 * @h_tile_instance: Controller instance used per tile. Number of elements is126 * @h_tile_instance: Controller instance used per tile. Number of elements is
@@ -199,7 +193,6 @@ struct msm_drm_private { · 66 unmodified lines
199 unsigned int num_crtcs;193 unsigned int num_crtcs;
200 struct drm_crtc *crtcs[MAX_CRTCS];194 struct drm_crtc *crtcs[MAX_CRTCS];
201 195
202 struct msm_drm_thread disp_thread[MAX_CRTCS];
203 struct msm_drm_thread event_thread[MAX_CRTCS];196 struct msm_drm_thread event_thread[MAX_CRTCS];
204 197
205 unsigned int num_encoders;198 unsigned int num_encoders;
@@ -228,7 +221,6 @@ struct msm_drm_private { · 22 unmodified lines
228 struct notifier_block vmap_notifier;221 struct notifier_block vmap_notifier;
229 struct shrinker shrinker;222 struct shrinker shrinker;
230 223
231 struct msm_vblank_ctrl vblank_ctrl;
232 struct drm_atomic_state *pm_state;224 struct drm_atomic_state *pm_state;
233};225};
234 226
include/drm/drm_dp_helper.h+13−0
@@ -560,6 +560,8 @@ · 559 unmodified lines
560# define DP_TEST_LINK_EDID_READ (1 << 2)560# define DP_TEST_LINK_EDID_READ (1 << 2)
561# define DP_TEST_LINK_PHY_TEST_PATTERN (1 << 3) /* DPCD >= 1.1 */561# define DP_TEST_LINK_PHY_TEST_PATTERN (1 << 3) /* DPCD >= 1.1 */
562# define DP_TEST_LINK_FAUX_PATTERN (1 << 4) /* DPCD >= 1.2 */562# define DP_TEST_LINK_FAUX_PATTERN (1 << 4) /* DPCD >= 1.2 */
563# define DP_TEST_LINK_AUDIO_PATTERN (1 << 5) /* DPCD >= 1.2 */
564# define DP_TEST_LINK_AUDIO_DISABLED_VIDEO (1 << 6) /* DPCD >= 1.2 */
563 565
564#define DP_TEST_LINK_RATE 0x219566#define DP_TEST_LINK_RATE 0x219
565# define DP_LINK_RATE_162 (0x6)567# define DP_LINK_RATE_162 (0x6)
@@ -608,6 +610,7 @@ · 42 unmodified lines
608# define DP_COLOR_FORMAT_RGB (0 << 1)610# define DP_COLOR_FORMAT_RGB (0 << 1)
609# define DP_COLOR_FORMAT_YCbCr422 (1 << 1)611# define DP_COLOR_FORMAT_YCbCr422 (1 << 1)
610# define DP_COLOR_FORMAT_YCbCr444 (2 << 1)612# define DP_COLOR_FORMAT_YCbCr444 (2 << 1)
613# define DP_TEST_DYNAMIC_RANGE_VESA (0 << 3)
611# define DP_TEST_DYNAMIC_RANGE_CEA (1 << 3)614# define DP_TEST_DYNAMIC_RANGE_CEA (1 << 3)
612# define DP_TEST_YCBCR_COEFFICIENTS (1 << 4)615# define DP_TEST_YCBCR_COEFFICIENTS (1 << 4)
613# define DP_YCBCR_COEFFICIENTS_ITU601 (0 << 4)616# define DP_YCBCR_COEFFICIENTS_ITU601 (0 << 4)
@@ -657,6 +660,16 @@ · 43 unmodified lines
657 660
658#define DP_TEST_SINK 0x270661#define DP_TEST_SINK 0x270
659# define DP_TEST_SINK_START (1 << 0)662# define DP_TEST_SINK_START (1 << 0)
663#define DP_TEST_AUDIO_MODE 0x271
664#define DP_TEST_AUDIO_PATTERN_TYPE 0x272
665#define DP_TEST_AUDIO_PERIOD_CH1 0x273
666#define DP_TEST_AUDIO_PERIOD_CH2 0x274
667#define DP_TEST_AUDIO_PERIOD_CH3 0x275
668#define DP_TEST_AUDIO_PERIOD_CH4 0x276
669#define DP_TEST_AUDIO_PERIOD_CH5 0x277
670#define DP_TEST_AUDIO_PERIOD_CH6 0x278
671#define DP_TEST_AUDIO_PERIOD_CH7 0x279
672#define DP_TEST_AUDIO_PERIOD_CH8 0x27A
660 673
661#define DP_FEC_STATUS 0x280 /* 1.4 */674#define DP_FEC_STATUS 0x280 /* 1.4 */
662# define DP_FEC_DECODE_EN_DETECTED (1 << 0)675# define DP_FEC_DECODE_EN_DETECTED (1 << 0)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t