From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C2323DAABE for ; Mon, 31 Aug 2026 08:18:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788164331; cv=none; b=n3HH3C7aobkq39PmEJYCkod3ocNDZ85iybB7fDmsCGoYiB0zR8qMHLbFIE9uoEMT3MlHU0P/vnEKyJJLteM7uNe/wyvfTWRmcATtBkLc6qCB3DFGeVhhJUW2g/+Tlll87265l9C9LDnBhG3KboIUCp+MVpTmt3J9yqUzFrPzXAs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788164331; c=relaxed/simple; bh=OGhauJd3OzLxD4MHbH499N+Wbne6Z3WirdM/odSM+RI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tplvOcjQgFYtTqXUJpixYc+o2pykNWfZxaH/G/U/PDwhkLMxGIgsOtOl9pM9FpUn/7db80MUYPWgo8ERGEY0BndGmPPnlaxzpW539Oh7AwmZw2jZm9Ex5rL81kX+eCKR/EYw9QRlaI9duexRW2QrEZFLjbJYwUZW2KEpv2/l3A4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=pYMwTrEf; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=QGctRtwZ; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="pYMwTrEf"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="QGctRtwZ" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67V7xH5q4081389 for ; Mon, 31 Aug 2026 08:18:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= XPOHxmn22GGB+hL14ouCUx7W10U1V29hXn+CFqhPpAI=; b=pYMwTrEfkWSpVbdq SaxpLlbzt5bouI8rykgorIiEbX0LkjjOZhRugsJTK9Qp5CuPx7mqxArt0XKBpIhs dni1PMLlSfrvk51PdUsojUgrrZLgM3vs7U2rQupXjc8jjkZxtgVm8ycwyiMkvO7A qjbpTG/wHJXQZTOObvbNUYhD/KfI8GCaPEkYxMm3AU5ldVlAG819p19NgM4e+v9n iIu9sdELe0h7sEMT9KBSlVFcovnKMMg0J/zVlba8DuWTycmcR7ar8xBR22EYryhX nnQvCUGb8ElVl+fkuyoegyNQOkoCdO9coLLP/xlJxQrsZs5XN1WyAwCm3srLscf4 78Dtrw== Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gcv8h1nav-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 31 Aug 2026 08:18:49 +0000 (GMT) Received: by mail-qk1-f197.google.com with SMTP id af79cd13be357-92e538afe65so768302485a.3 for ; Mon, 31 Aug 2026 01:18:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1788164328; x=1788769128; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=XPOHxmn22GGB+hL14ouCUx7W10U1V29hXn+CFqhPpAI=; b=QGctRtwZY/B5Q0uAky1Nv45X59B+zGzZXBv1S3/s4qlXqC/oHGvKtZkRwW1pCjm/ep jYUU5ciABU0pSzD0tH8k0IQ+RTRXwpXFH3UCEJ6M6hrjJRdKzIaSzA9Q9nlTO91pEnmB doJ91Lp+9wObIhjvsosswiv99xArmHfTdhqtLyarEHmTaM9GAjnlTAPPmgTdLKMQX+us PDf6ZN3MvY3wUcZT/TQTPIg1ljEvsSlbkOqcChffPir36GyrVTH6gSFKzPZx7mj45tpl kDncp5HDCe96bKXWeFc+4JCI8cSuC33WsnljL2mQll3s0mHlXfcYQOhVSLEs4KnUmKhS wTQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788164328; x=1788769128; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=XPOHxmn22GGB+hL14ouCUx7W10U1V29hXn+CFqhPpAI=; b=dIXH83Fjd0K2LnulSHB80QoRV65uNKqmeZ8liVb9lgXmOBHDkij1sewIJ+nWD/xPyd gjM3ruqI5OWem8kkQspWq+j04txVwr0cWzFWz4O+O9K2A87+7mv5UX7WP5sB3YAoX8vY Q7C8yxsJahwYGti0buXtkmr50iQlgUUGiHpVhSbypt0B3LKeS5bS4EeChj5HFyn5DbKt N4XsdmCz37imJcNKT/mIOSO4+33ZEelT3cCTPdHxEA4JPnN2ECT4mA3sh4AZL3aNjxOs kLGjEc7h1vlIfijTSCret6dP0/DdAuwyYvnHPFZ/rOZ10Gn2BTpFy5MSixymrRDNPxjA 6duA== X-Forwarded-Encrypted: i=1; AHgh+RpPfUzQgHNpAV56QX6knStuyPCDks/tFGUS+ZdENFNd/Nf2rufaJgfVdRVKRCCGAXAIsIuk/6NH7UF+NSI=@vger.kernel.org X-Gm-Message-State: AFuF++k+7nGs36mfgty9d2Fwf+zLXbbdA2PGrY/PyE4dsGCYnfJXL4Rk YweTV9XTSZ35dNldmgvrzQeD4WYAJ3Frdwyj0Vc2V/W629CXu8Cakwbsh/g9mkrTLCy1TwEzEzT HaDloh1k8rtTSpFpV1PG4I1p+wyM2K0Q78qCQ9FziySduhEIIAQLrmWcHPQ/k4jrsVTs= X-Gm-Gg: AR+sD12TGUb61ghdPvk9y8BgdEzR66n7vJ+l4CtnIuYdCPtVlodJvEoXbzN9V1TgaDX Vn6G9bBxi1SO6USmqNWD32i8JE5mL+yLpozS8CUoWSy2A59e7NUstv4mrgaJJ/F98z22e/BtiHj mxjZjh7pDcG3hN4oQj6XmXbxSpioon+e5LMXGM7pqakGZTsNxJxunr5vRrREinhnl/q7br5qwQ7 MbdwqBe3yv6Rm4Ynm0wAVmQRcA1jIxR1oM78rO1bHRGrfiAGRer/H6z6cVRrhMoL3aCEYMkIPTn XLkuNK1J8spIiN6h6wHA965jb+vBd75HNdoPs01cX8y1i6UW1nsFi0XETtF6g+4EVpWb7+U5Pwu OJ5AC0HNl3UANAlwwy+okbLHmpbww+CKhOmDkgcxl1UXwcnVGg63A98sCDO5Mi/c= X-Received: by 2002:a05:620a:438a:b0:938:fd9b:c615 with SMTP id af79cd13be357-93942c00205mr139535685a.40.1788164325084; Mon, 31 Aug 2026 01:18:45 -0700 (PDT) X-Received: by 2002:a05:620a:438a:b0:938:fd9b:c615 with SMTP id af79cd13be357-93942c00205mr139533085a.40.1788164324604; Mon, 31 Aug 2026 01:18:44 -0700 (PDT) Received: from yongmou2.ap.qualcomm.com (Global_NAT1_IAD_FW.qualcomm.com. [129.46.232.65]) by smtp.gmail.com with ESMTPSA id af79cd13be357-93917236b86sm735974285a.13.2026.08.31.01.18.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 01:18:44 -0700 (PDT) From: Yongxing Mou Date: Mon, 31 Aug 2026 16:17:30 +0800 Subject: [PATCH v6 13/29] drm/msm/dp: add support for MST channel slot allocation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260831-msm-dp-mst-v6-13-c91d35d6fb9e@oss.qualcomm.com> References: <20260831-msm-dp-mst-v6-0-c91d35d6fb9e@oss.qualcomm.com> In-Reply-To: <20260831-msm-dp-mst-v6-0-c91d35d6fb9e@oss.qualcomm.com> To: Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Sean Paul , Marijn Suijten , David Airlie , Simona Vetter , Jessica Zhang , Jessica Zhang Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org, Yongxing Mou , Abhinav Kumar X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788164246; l=11267; i=yongxing.mou@oss.qualcomm.com; s=20250910; h=from:subject:message-id; bh=+W3yOOVPimxIkzfy2QCIg8lz3eQgKKACbs3gAn/D970=; b=r5sJm5XI51pD8MoKykvhzqDw/PEcaqZXQSuvnn6pp4PrGPjwLYAkFBMSD8shSENrrv6NQTgWj qKe389Ca5U+CF7cN+Z/rOwXA1k57b2+nDN5uGPHPz15XR4tPIkfXBgp X-Developer-Key: i=yongxing.mou@oss.qualcomm.com; a=ed25519; pk=rAy5J1eP+V7OXqH5FJ7ngMCtUrnHhut30ZTldOj52UM= X-Authority-Analysis: v=2.4 cv=DY0nbPtW c=1 sm=1 tr=0 ts=6a9538e9 cx=c_pps a=50t2pK5VMbmlHzFWWp8p/g==:117 a=C3Dk8TwHQYyIj7nOf9RCJw==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=COk6AnOGAAAA:8 a=EUspDBNiAAAA:8 a=MDyj_ca9PKY2YTlzjZYA:9 a=QEXdDO2ut3YA:10 a=IoWCM6iH3mJn3m4BftBB:22 a=TjNXssC_j7lpFel5tvFf:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODMxMDA3MCBTYWx0ZWRfX0gkXXrVkzpEw AzmkdR4Cc2Zqn6HYWWfdDqTk7TJhhZOFZsTiizsoyL2yAncKN3LpIM06Ejkzf7QKqrCi0ySy/0n I6tEYdh+Og7/cD046yGpcFwvDCyLUhz4WaMjFYcut0asdRx0fc5GcXlFT4PGKHkiQ3GW4DwPFlJ L27DPId2lOv3aG5oTMF6Bo6/2ziCgWnLJ08wbZE+rConXXGqgH/zTm7AO9M5c4Y07mNhJ2ycFke Pw4f0ZRs6XdW7+M0FKPtVJTopFpwvYrlm9rW+oT7LPDz9YyrNtOFyYFv6f27slUvouTHmmobHFX wJGHFRaC93HVG72kOvC8nSRK/EfKP29ZprjN4b++7m5WEW29vMa0MN82D367NGwrdIjQjMDMYHi ptME928uOLN2KU6Z8JTIankxivPDX0Ujwg4PMUkFAwamF1FI4U+X3DOv+y7LMEC8I6mjnw4KyVl F4bcDbSkKvdOpZGly5Q== X-Proofpoint-ORIG-GUID: se-ekCGLKjHyeoXcmqRylfhkvj-z9TJB X-Proofpoint-Spam-Info: AW1haW4tMjYwODMxMDA3MCBTYWx0ZWRfX7IWHexUyuTeg riOqzqUV6og7mwQkV9G8rDAGEvb3db/ioH7/PSllNsyauvSONdhrZTfaP0gqTq6eWVlVa+7xXhr IpudAednrJBvOcQuNtbI1rttiMwWVws= X-Proofpoint-GUID: se-ekCGLKjHyeoXcmqRylfhkvj-z9TJB X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-31_03,2026-08-27_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 adultscore=0 clxscore=1015 priorityscore=1501 spamscore=0 suspectscore=0 malwarescore=0 bulkscore=0 lowpriorityscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608310070 From: Abhinav Kumar DP MST streams share 64 MTP slots in a time-multiplexed manner. Add support for calculating the rate governor, slot allocation, and slot reservation in the DP controller. Each MST stream can reserve its slots by calling msm_dp_display_set_stream_info() from its bridge callbacks. Signed-off-by: Abhinav Kumar Signed-off-by: Yongxing Mou --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 187 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/dp/dp_ctrl.h | 4 + drivers/gpu/drm/msm/dp/dp_display.c | 13 +++ drivers/gpu/drm/msm/dp/dp_display.h | 2 + 4 files changed, 206 insertions(+) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 109a84167599..73aabd219125 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -78,6 +78,7 @@ #define MR_LINK_PRBS7 0x100 #define MR_LINK_CUSTOM80 0x200 #define MR_LINK_TRAINING4 0x40 +#define DP_MAX_TIME_SLOTS 64 enum { DP_TRAINING_NONE, @@ -114,6 +115,12 @@ struct msm_dp_vc_tu_mapping_table { u8 tu_size_minus1; }; +struct msm_dp_mst_ch_slot_info { + u32 start_slot; + u32 tot_slots; + u32 pbn; +}; + struct msm_dp_ctrl_private { struct msm_dp_ctrl msm_dp_ctrl; struct drm_device *drm_dev; @@ -148,6 +155,8 @@ struct msm_dp_ctrl_private { bool link_clks_on; bool stream_clks_on[DP_STREAM_MAX]; bool mst_active; + + struct msm_dp_mst_ch_slot_info mst_ch_info[DP_STREAM_MAX]; }; static inline u32 msm_dp_read_ahb(const struct msm_dp_ctrl_private *ctrl, u32 offset) @@ -294,6 +303,37 @@ static void msm_dp_ctrl_mst_config(struct msm_dp_ctrl_private *ctrl, bool enable msm_dp_write_link(ctrl, REG_DP_MAINLINK_CTRL, mainlink_ctrl); } +static void msm_dp_ctrl_mst_update_timeslot(struct msm_dp_ctrl_private *ctrl, + enum msm_dp_stream_id stream_id, u32 ch_start_slot, + u32 tot_slot_cnt) +{ + u32 slot_reg_1 = 0, slot_reg_2 = 0; + + drm_dbg_dp(ctrl->drm_dev, "stream_id %d, start_slot %d, tot_slot %d\n", + stream_id, ch_start_slot, tot_slot_cnt); + + if (ch_start_slot && tot_slot_cnt) { + u64 mask = GENMASK_ULL(ch_start_slot + tot_slot_cnt - 2, ch_start_slot - 1); + + slot_reg_1 = mask & 0xFFFFFFFF; + slot_reg_2 = (mask >> 32) & 0xFFFFFFFF; + } + + msm_dp_write_stream_link(ctrl, stream_id, REG_DP_DP0_TIMESLOT_1_32, slot_reg_1); + msm_dp_write_stream_link(ctrl, stream_id, REG_DP_DP0_TIMESLOT_33_63, slot_reg_2); +} + +static void msm_dp_ctrl_update_rg(struct msm_dp_ctrl_private *ctrl, + enum msm_dp_stream_id stream_id, u32 x_int, u32 y_frac_enum) +{ + u32 rg = y_frac_enum | (x_int << 16); + + drm_dbg_dp(ctrl->drm_dev, "stream_id: %d x_int:%d y_frac_enum:%d rg:%d\n", + stream_id, x_int, y_frac_enum, rg); + + msm_dp_write_stream_link(ctrl, stream_id, REG_DP_DP0_RG, rg); +} + /* * NOTE: resetting DP controller will also clear any pending HPD related interrupts */ @@ -2675,6 +2715,117 @@ static void msm_dp_ctrl_config_msa(struct msm_dp_ctrl_private *ctrl, msm_dp_write_stream_link(ctrl, panel->stream_id, REG_DP_SOFTWARE_NVID, nvid); } +/* + * Calculate MST Rate Governor parameters x_int and y_frac_enum. + * + * The RG paces symbol delivery per MTP via: M = x_int + y_frac_enum/256 + * where M is the target symbol count per MTP across all lanes. + * + * min_slot_cnt = (pclk * bpp/8) / (lclk * lanes) * 64 -- slots at 1.0x BW + * max_slot_cnt = pbn * 54 / (lclk * lanes) -- slots at PBN limit + * raw_target_sc = (min + max) / 2 -- midpoint (~1.003x) + * + * Quantize raw_target_sc to 1/(256*lanes) steps, then: + * M = Chosen_TARGET_Slot_Count * lanes + * x_int = INT(M) + * y_frac_enum = CEIL(256 * MOD(M, 1)) + */ +static void msm_dp_ctrl_mst_calculate_rg(struct msm_dp_ctrl_private *ctrl, + struct msm_dp_panel *panel, + u32 *p_x_int, u32 *p_y_frac_enum) +{ + u64 min_slot_cnt, max_slot_cnt; + u64 raw_target_sc, target_sc_fixp; + u64 ts_denom, ts_enum, ts_int; + u64 pclk = panel->msm_dp_mode.drm_mode.clock; + u64 lclk = 0; + u64 lanes = ctrl->link->link_params.num_lanes; + u64 bpp = panel->msm_dp_mode.bpp; + u64 pbn = ctrl->mst_ch_info[panel->stream_id].pbn; + u64 numerator, denominator, temp, temp1, temp2; + u32 x_int = 0, y_frac_enum = 0; + u64 target_strm_sym, ts_int_fixp, ts_frac_fixp, y_frac_enum_fixp; + + lclk = ctrl->link->link_params.rate; + + /* min_slot_cnt */ + numerator = pclk * bpp * 64 * 1000; + denominator = lclk * lanes * 8 * 1000; + min_slot_cnt = drm_fixp_from_fraction(numerator, denominator); + + /* max_slot_cnt */ + numerator = pbn * 54 * 1000; + denominator = lclk * lanes; + max_slot_cnt = drm_fixp_from_fraction(numerator, denominator); + + /* raw_target_sc */ + numerator = max_slot_cnt + min_slot_cnt; + denominator = drm_fixp_from_fraction(2, 1); + raw_target_sc = drm_fixp_div(numerator, denominator); + + /* target_sc */ + temp = drm_fixp_from_fraction(256 * lanes, 1); + numerator = drm_fixp_mul(raw_target_sc, temp); + denominator = drm_fixp_from_fraction(256 * lanes, 1); + target_sc_fixp = drm_fixp_div(numerator, denominator); + + ts_enum = 256 * lanes; + ts_denom = drm_fixp_from_fraction(256 * lanes, 1); + ts_int = drm_fixp2int(target_sc_fixp); + + temp = drm_fixp2int_ceil(raw_target_sc); + if (temp != ts_int) { + temp = drm_fixp_from_fraction(ts_int, 1); + temp1 = raw_target_sc - temp; + temp2 = drm_fixp_mul(temp1, ts_denom); + ts_enum = drm_fixp2int(temp2); + } + + /* target_strm_sym */ + ts_int_fixp = drm_fixp_from_fraction(ts_int, 1); + ts_frac_fixp = drm_fixp_from_fraction(ts_enum, drm_fixp2int(ts_denom)); + temp = ts_int_fixp + ts_frac_fixp; + temp1 = drm_fixp_from_fraction(lanes, 1); + target_strm_sym = drm_fixp_mul(temp, temp1); + + /* x_int */ + x_int = drm_fixp2int(target_strm_sym); + + /* y_enum_frac */ + temp = drm_fixp_from_fraction(x_int, 1); + temp1 = target_strm_sym - temp; + temp2 = drm_fixp_from_fraction(256, 1); + y_frac_enum_fixp = drm_fixp_mul(temp1, temp2); + + temp1 = drm_fixp2int(y_frac_enum_fixp); + temp2 = drm_fixp2int_ceil(y_frac_enum_fixp); + + y_frac_enum = (u32)((temp1 == temp2) ? temp1 : temp1 + 1); + + *p_x_int = x_int; + *p_y_frac_enum = y_frac_enum; + + drm_dbg_dp(ctrl->drm_dev, "MST lane_cnt:%llu, rate:%llu x_int:%d, y_frac:%d\n", + lanes, lclk, x_int, y_frac_enum); +} + +static void msm_dp_ctrl_mst_stream_setup(struct msm_dp_ctrl_private *ctrl, + struct msm_dp_panel *panel) +{ + u32 x_int, y_frac_enum; + + if (!ctrl->mst_active) + return; + + drm_dbg_dp(ctrl->drm_dev, "MST stream channel allocation\n"); + + msm_dp_ctrl_mst_timeslot_setup(&ctrl->msm_dp_ctrl); + + msm_dp_ctrl_mst_calculate_rg(ctrl, panel, &x_int, &y_frac_enum); + + msm_dp_ctrl_update_rg(ctrl, panel->stream_id, x_int, y_frac_enum); +} + int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel, bool force_link_train) @@ -2758,6 +2909,8 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel * if (!ctrl->mst_active) msm_dp_ctrl_setup_tr_unit(ctrl, panel); + msm_dp_ctrl_mst_stream_setup(ctrl, panel); + msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO); ret = msm_dp_ctrl_mst_send_act(msm_dp_ctrl, panel); @@ -2809,6 +2962,40 @@ void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl, phy_power_off(phy); } +void msm_dp_ctrl_set_mst_channel_info(struct msm_dp_ctrl *msm_dp_ctrl, + enum msm_dp_stream_id stream_id, + u32 start_slot, u32 tot_slots, u32 pbn) +{ + struct msm_dp_ctrl_private *ctrl; + + if (!msm_dp_ctrl || stream_id >= DP_STREAM_MAX) { + DRM_ERROR("invalid input\n"); + return; + } + + ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl); + + ctrl->mst_ch_info[stream_id].start_slot = start_slot; + ctrl->mst_ch_info[stream_id].tot_slots = tot_slots; + ctrl->mst_ch_info[stream_id].pbn = pbn; +} + +void msm_dp_ctrl_mst_timeslot_setup(struct msm_dp_ctrl *msm_dp_ctrl) +{ + struct msm_dp_ctrl_private *ctrl; + int i; + + ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl); + + if (!ctrl->mst_active) + return; + + for (i = DP_STREAM_0; i < ctrl->num_pixel_clks; i++) { + msm_dp_ctrl_mst_update_timeslot(ctrl, i, ctrl->mst_ch_info[i].start_slot, + ctrl->mst_ch_info[i].tot_slots); + } +} + irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel) { diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h index 84ea37d8db2e..e8b445c552f7 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.h +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h @@ -63,4 +63,8 @@ bool msm_dp_ctrl_stream_clks_on(struct msm_dp_ctrl *dp_ctrl, enum msm_dp_stream_id stream_id); int msm_dp_ctrl_mst_send_act(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel); +void msm_dp_ctrl_mst_timeslot_setup(struct msm_dp_ctrl *msm_dp_ctrl); +void msm_dp_ctrl_set_mst_channel_info(struct msm_dp_ctrl *msm_dp_ctrl, + enum msm_dp_stream_id stream_id, + u32 start_slot, u32 tot_slots, u32 pbn); #endif /* _DP_CTRL_H_ */ diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 00c9b55925f9..6f79328c8b79 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -734,6 +734,18 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp, return 0; } +int msm_dp_display_set_stream_info(struct msm_dp *msm_dp_display, struct msm_dp_panel *panel, + u32 start_slot, u32 num_slots, u32 pbn) +{ + struct msm_dp_display_private *dp; + + dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display); + + msm_dp_ctrl_set_mst_channel_info(dp->ctrl, panel->stream_id, start_slot, num_slots, pbn); + + return 0; +} + /** * msm_dp_display_mode_valid - callback to determine if specified mode is valid * @dp: Pointer to dp display structure @@ -1497,6 +1509,7 @@ void msm_dp_display_atomic_disable(struct msm_dp *dp) msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display); msm_dp_ctrl_push_vcpf(msm_dp_display->ctrl, msm_dp_display->panel); + msm_dp_ctrl_mst_timeslot_setup(msm_dp_display->ctrl); msm_dp_ctrl_mst_send_act(msm_dp_display->ctrl, msm_dp_display->panel); } diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h index 472429d09200..317c19b809ec 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.h +++ b/drivers/gpu/drm/msm/dp/dp_display.h @@ -43,5 +43,7 @@ void msm_dp_display_atomic_enable(struct msm_dp *dp_display, enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp, const struct drm_display_info *info, const struct drm_display_mode *mode); +int msm_dp_display_set_stream_info(struct msm_dp *msm_dp_display, struct msm_dp_panel *panel, + u32 start_slot, u32 num_slots, u32 pbn); #endif /* _DP_DISPLAY_H_ */ -- 2.43.0