Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Revert "drm/msm/dpu: support plane splitting in quad-pipe case"

This reverts commit 5978864e34b66bdae4d7613834c03dd5d0a0c891.

At least on Hamoa based devices, there are IOMMU faults:

arm-smmu 15000000.iommu: Unhandled context fault: fsr=0x402, iova=0x00000000, fsynr=0x3d0023, cbfrsynra=0x1c00, cb=13
arm-smmu 15000000.iommu: FSR = 00000402 [Format=2 TF], SID=0x1c00
arm-smmu 15000000.iommu: FSYNR0 = 003d0023 [S1CBNDX=61 PNU PLVL=3]

While on some of these devices, there are also all sorts of artifacts on eDP.

Reverting this fixes these issues.

Closes: https://lore.kernel.org/r/z75wnahrp7lrl5yhfdysr3np3qrs6xti2i4otkng4ex3blfgrx@xyiucge3xykb/
Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
Fixes: 5978864e34b6 ("drm/msm/dpu: support plane splitting in quad-pipe case")
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/695549/
Link: https://lore.kernel.org/r/20251219-drm-msm-dpu-revert-quad-pipe-broken-v1-1-654b46505f84@oss.qualcomm.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

authored by

Abel Vesa and committed by
Dmitry Baryshkov
35ab5123 7c85da6f

+41 -111
-11
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
··· 1620 1620 return 0; 1621 1621 } 1622 1622 1623 - /** 1624 - * dpu_crtc_get_num_lm - Get mixer number in this CRTC pipeline 1625 - * @state: Pointer to drm crtc state object 1626 - */ 1627 - unsigned int dpu_crtc_get_num_lm(const struct drm_crtc_state *state) 1628 - { 1629 - struct dpu_crtc_state *cstate = to_dpu_crtc_state(state); 1630 - 1631 - return cstate->num_mixers; 1632 - } 1633 - 1634 1623 #ifdef CONFIG_DEBUG_FS 1635 1624 static int _dpu_debugfs_status_show(struct seq_file *s, void *data) 1636 1625 {
-2
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
··· 267 267 268 268 void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event); 269 269 270 - unsigned int dpu_crtc_get_num_lm(const struct drm_crtc_state *state); 271 - 272 270 #endif /* _DPU_CRTC_H_ */
+41 -98
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
··· 826 826 struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); 827 827 struct dpu_sw_pipe_cfg *pipe_cfg; 828 828 struct dpu_sw_pipe_cfg *r_pipe_cfg; 829 - struct dpu_sw_pipe_cfg init_pipe_cfg; 830 829 struct drm_rect fb_rect = { 0 }; 831 - const struct drm_display_mode *mode = &crtc_state->adjusted_mode; 832 830 uint32_t max_linewidth; 833 - u32 num_lm; 834 - int stage_id, num_stages; 835 831 836 832 min_scale = FRAC_16_16(1, MAX_UPSCALE_RATIO); 837 833 max_scale = MAX_DOWNSCALE_RATIO << 16; ··· 850 854 return -EINVAL; 851 855 } 852 856 853 - num_lm = dpu_crtc_get_num_lm(crtc_state); 854 - 857 + /* move the assignment here, to ease handling to another pairs later */ 858 + pipe_cfg = &pstate->pipe_cfg[0]; 859 + r_pipe_cfg = &pstate->pipe_cfg[1]; 855 860 /* state->src is 16.16, src_rect is not */ 856 - drm_rect_fp_to_int(&init_pipe_cfg.src_rect, &new_plane_state->src); 861 + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src); 862 + 863 + pipe_cfg->dst_rect = new_plane_state->dst; 857 864 858 865 fb_rect.x2 = new_plane_state->fb->width; 859 866 fb_rect.y2 = new_plane_state->fb->height; ··· 881 882 882 883 max_linewidth = pdpu->catalog->caps->max_linewidth; 883 884 884 - drm_rect_rotate(&init_pipe_cfg.src_rect, 885 + drm_rect_rotate(&pipe_cfg->src_rect, 885 886 new_plane_state->fb->width, new_plane_state->fb->height, 886 887 new_plane_state->rotation); 887 888 888 - /* 889 - * We have 1 mixer pair cfg for 1:1:1 and 2:2:1 topology, 2 mixer pair 890 - * configs for left and right half screen in case of 4:4:2 topology. 891 - * But we may have 2 rect to split wide plane that exceeds limit with 1 892 - * config for 2:2:1. So need to handle both wide plane splitting, and 893 - * two halves of screen splitting for quad-pipe case. Check dest 894 - * rectangle left/right clipping first, then check wide rectangle 895 - * splitting in every half next. 896 - */ 897 - num_stages = (num_lm + 1) / 2; 898 - /* iterate mixer configs for this plane, to separate left/right with the id */ 899 - for (stage_id = 0; stage_id < num_stages; stage_id++) { 900 - struct drm_rect mixer_rect = { 901 - .x1 = stage_id * mode->hdisplay / num_stages, 902 - .y1 = 0, 903 - .x2 = (stage_id + 1) * mode->hdisplay / num_stages, 904 - .y2 = mode->vdisplay 905 - }; 906 - int cfg_idx = stage_id * PIPES_PER_STAGE; 907 - 908 - pipe_cfg = &pstate->pipe_cfg[cfg_idx]; 909 - r_pipe_cfg = &pstate->pipe_cfg[cfg_idx + 1]; 910 - 911 - drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src); 912 - pipe_cfg->dst_rect = new_plane_state->dst; 913 - 914 - DPU_DEBUG_PLANE(pdpu, "checking src " DRM_RECT_FMT 915 - " vs clip window " DRM_RECT_FMT "\n", 916 - DRM_RECT_ARG(&pipe_cfg->src_rect), 917 - DRM_RECT_ARG(&mixer_rect)); 918 - 919 - /* 920 - * If this plane does not fall into mixer rect, check next 921 - * mixer rect. 922 - */ 923 - if (!drm_rect_clip_scaled(&pipe_cfg->src_rect, 924 - &pipe_cfg->dst_rect, 925 - &mixer_rect)) { 926 - memset(pipe_cfg, 0, 2 * sizeof(struct dpu_sw_pipe_cfg)); 927 - 928 - continue; 889 + if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) || 890 + _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) { 891 + if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) { 892 + DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n", 893 + DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); 894 + return -E2BIG; 929 895 } 930 896 931 - pipe_cfg->dst_rect.x1 -= mixer_rect.x1; 932 - pipe_cfg->dst_rect.x2 -= mixer_rect.x1; 933 - 934 - DPU_DEBUG_PLANE(pdpu, "Got clip src:" DRM_RECT_FMT " dst: " DRM_RECT_FMT "\n", 935 - DRM_RECT_ARG(&pipe_cfg->src_rect), DRM_RECT_ARG(&pipe_cfg->dst_rect)); 936 - 937 - /* Split wide rect into 2 rect */ 938 - if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) || 939 - _dpu_plane_calc_clk(mode, pipe_cfg) > max_mdp_clk_rate) { 940 - 941 - if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) { 942 - DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n", 943 - DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); 944 - return -E2BIG; 945 - } 946 - 947 - memcpy(r_pipe_cfg, pipe_cfg, sizeof(struct dpu_sw_pipe_cfg)); 948 - pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1; 949 - pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1; 950 - r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2; 951 - r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; 952 - DPU_DEBUG_PLANE(pdpu, "Split wide plane into:" 953 - DRM_RECT_FMT " and " DRM_RECT_FMT "\n", 954 - DRM_RECT_ARG(&pipe_cfg->src_rect), 955 - DRM_RECT_ARG(&r_pipe_cfg->src_rect)); 956 - } else { 957 - memset(r_pipe_cfg, 0, sizeof(struct dpu_sw_pipe_cfg)); 958 - } 959 - 960 - drm_rect_rotate_inv(&pipe_cfg->src_rect, 961 - new_plane_state->fb->width, 962 - new_plane_state->fb->height, 963 - new_plane_state->rotation); 964 - 965 - if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) 966 - drm_rect_rotate_inv(&r_pipe_cfg->src_rect, 967 - new_plane_state->fb->width, 968 - new_plane_state->fb->height, 969 - new_plane_state->rotation); 897 + *r_pipe_cfg = *pipe_cfg; 898 + pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1; 899 + pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1; 900 + r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2; 901 + r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; 902 + } else { 903 + memset(r_pipe_cfg, 0, sizeof(*r_pipe_cfg)); 970 904 } 905 + 906 + drm_rect_rotate_inv(&pipe_cfg->src_rect, 907 + new_plane_state->fb->width, new_plane_state->fb->height, 908 + new_plane_state->rotation); 909 + if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) 910 + drm_rect_rotate_inv(&r_pipe_cfg->src_rect, 911 + new_plane_state->fb->width, new_plane_state->fb->height, 912 + new_plane_state->rotation); 971 913 972 914 pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state); 973 915 ··· 985 1045 drm_atomic_get_new_plane_state(state, plane); 986 1046 struct dpu_plane *pdpu = to_dpu_plane(plane); 987 1047 struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); 988 - struct dpu_sw_pipe *pipe; 989 - struct dpu_sw_pipe_cfg *pipe_cfg; 990 - int ret = 0, i; 1048 + struct dpu_sw_pipe *pipe = &pstate->pipe[0]; 1049 + struct dpu_sw_pipe *r_pipe = &pstate->pipe[1]; 1050 + struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[0]; 1051 + struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[1]; 1052 + int ret = 0; 991 1053 992 - for (i = 0; i < PIPES_PER_PLANE; i++) { 993 - pipe = &pstate->pipe[i]; 994 - pipe_cfg = &pstate->pipe_cfg[i]; 995 - if (!drm_rect_width(&pipe_cfg->src_rect)) 996 - continue; 997 - DPU_DEBUG_PLANE(pdpu, "pipe %d is in use, validate it\n", i); 998 - ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, 1054 + ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, 1055 + &crtc_state->adjusted_mode, 1056 + new_plane_state); 1057 + if (ret) 1058 + return ret; 1059 + 1060 + if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) { 1061 + ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, 999 1062 &crtc_state->adjusted_mode, 1000 1063 new_plane_state); 1001 1064 if (ret)