From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from fllvem-ot03.ext.ti.com (fllvem-ot03.ext.ti.com [198.47.19.245]) (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 C3D31146A66; Tue, 30 Sep 2025 12:42:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.245 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759236162; cv=none; b=YJYJ6XaKWUkBE42QKIsFI8Bvgl8cHOGfZ72cJvA0DJ/WB0i2yKBZHiltXu6yfuQ5hVGLGlJHyn/bizf8DSDtqLpF1m62vL072XraKLZ84jvK7tHfCqHcGxbAWJrMlzNBw9swNV5qGezT645ViEFjdLY0xvTtXVL4ZBCDJ1e6i2I= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759236162; c=relaxed/simple; bh=Vr1C26lMY28YmMjLf3GBcj1LcfwlwQNTSBRFafN7o/U=; h=Message-ID:Date:MIME-Version:Subject:To:CC:References:From: In-Reply-To:Content-Type; b=WQOGihbo7Kvzmrx6ITMhfdIYLru6eOz+f+EkUExz1sMnI5mkHjXV44fQhD5mcGY0e3ODgTNv/IpMZdnWv+N5TTe27tUvjzvkKrcp6xKCmX4yf/EPpxEXCwi8NzfBhkXrleKRjODl/u/vSzjIsWhwRB9serdCjRu17mNA0UFrjf4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=PfT0UFmD; arc=none smtp.client-ip=198.47.19.245 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="PfT0UFmD" Received: from fllvem-sh04.itg.ti.com ([10.64.41.54]) by fllvem-ot03.ext.ti.com (8.15.2/8.15.2) with ESMTP id 58UCfpC42418483; Tue, 30 Sep 2025 07:41:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1759236111; bh=rkjrgikif2H0LwyswjA9rvggsWYfLJh5uV4br+mvjYw=; h=Date:Subject:To:CC:References:From:In-Reply-To; b=PfT0UFmDxEJ1y000wL6/z2XkHJSAcq/585tKSca+7BjxaijXd9dQM4rS0dq1RQmI0 FR4PCvzHsnxTIfGS8xZfWEqVuQE8qV3fotIogrOGk54pV37GycMskTXL7vCyMKncha Higlc9hroh+t+gFhVdHlw9oKQbTX4Q0dAD7Qb7vI= Received: from DFLE106.ent.ti.com (dfle106.ent.ti.com [10.64.6.27]) by fllvem-sh04.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 58UCfoVR3918021 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Tue, 30 Sep 2025 07:41:50 -0500 Received: from DFLE203.ent.ti.com (10.64.6.61) by DFLE106.ent.ti.com (10.64.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.55; Tue, 30 Sep 2025 07:41:50 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) by DFLE203.ent.ti.com (10.64.6.61) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20 via Frontend Transport; Tue, 30 Sep 2025 07:41:50 -0500 Received: from [172.24.235.208] (hkshenoy.dhcp.ti.com [172.24.235.208] (may be forged)) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 58UCffG13176386; Tue, 30 Sep 2025 07:41:42 -0500 Message-ID: <50be4e62-efe4-4b2a-bf60-27a8c444cfbe@ti.com> Date: Tue, 30 Sep 2025 18:11:41 +0530 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v5 2/2] drm: bridge: cdns-mhdp8546: Add support for DSC and FEC To: Dmitry Baryshkov CC: , , , , , , , , , , , , , , , , , , , , , , , , , , , References: <20250915103041.3891448-1-h-shenoy@ti.com> <20250915103041.3891448-3-h-shenoy@ti.com> Content-Language: en-US From: Harikrishna Shenoy In-Reply-To: Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 8bit X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea On 9/15/25 16:36, Dmitry Baryshkov wrote: > On Mon, Sep 15, 2025 at 04:00:41PM +0530, Harikrishna Shenoy wrote: >> From: Swapnil Jakhade >> >> Enable support for Display Stream Compression (DSC) in independent >> mode with a single stream, along with Forward Error Correction (FEC) >> in the Cadence MHDP8546 DisplayPort controller driver. >> >> FEC is required when DSC is enabled to ensure reliable transmission >> of the compressed stream. >> >> Signed-off-by: Swapnil Jakhade >> Signed-off-by: Harikrishna Shenoy >> --- >> drivers/gpu/drm/bridge/cadence/Makefile | 2 +- >> .../drm/bridge/cadence/cdns-mhdp8546-core.c | 367 ++++++++- >> .../drm/bridge/cadence/cdns-mhdp8546-core.h | 68 ++ >> .../drm/bridge/cadence/cdns-mhdp8546-dsc.c | 695 ++++++++++++++++++ >> .../drm/bridge/cadence/cdns-mhdp8546-dsc.h | 285 +++++++ >> 5 files changed, 1392 insertions(+), 25 deletions(-) >> create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-dsc.c >> create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-dsc.h >> >> diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile >> index c95fd5b81d13..7957fbdc1b78 100644 >> --- a/drivers/gpu/drm/bridge/cadence/Makefile >> +++ b/drivers/gpu/drm/bridge/cadence/Makefile >> @@ -3,5 +3,5 @@ obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o >> cdns-dsi-y := cdns-dsi-core.o >> cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o >> obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o >> -cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o >> +cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o cdns-mhdp8546-dsc.o >> cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o >> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >> index a614d1384f71..df8bbf8919b2 100644 >> --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >> @@ -50,6 +50,7 @@ >> #include >> >> #include "cdns-mhdp8546-core.h" >> +#include "cdns-mhdp8546-dsc.h" >> #include "cdns-mhdp8546-hdcp.h" >> #include "cdns-mhdp8546-j721e.h" >> >> @@ -545,6 +546,116 @@ int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, unsigned int nlanes, >> return ret; >> } >> >> +static int cdns_mhdp_wait_for_fec(struct cdns_mhdp_device *mhdp, >> + bool expected_status) >> +{ >> + u32 fec_status; >> + unsigned long timeout = jiffies + msecs_to_jiffies(1000); >> + >> + cdns_mhdp_reg_read(mhdp, CDNS_DP_FEC_STATUS, &fec_status); >> + while (((fec_status & CDNS_DP_FEC_BUSY) != expected_status) && >> + time_before(jiffies, timeout)) { >> + cdns_mhdp_reg_read(mhdp, CDNS_DP_FEC_STATUS, &fec_status); >> + cpu_relax(); >> + } >> + >> + if (time_after_eq(jiffies, timeout)) { >> + DRM_DEV_ERROR(mhdp->dev, "Timeout while waiting for FEC\n"); >> + return -ETIMEDOUT; >> + } >> + >> + return 0; >> +} >> + >> +static int cdns_mhdp_fec_sink_support(struct cdns_mhdp_device *mhdp) >> +{ >> + int ret; >> + u16 dpcd_buffer; >> + >> + ret = drm_dp_dpcd_read(&mhdp->aux, DP_FEC_CAPABILITY, &dpcd_buffer, 1); >> + if (ret < 0) >> + goto err; > Only since DP 1.4 if I'm not mistaken. will add the check for DP version>= 1.4. >> + >> + if (!(dpcd_buffer & DP_FEC_CAPABLE)) { >> + ret = -EOPNOTSUPP; >> + DRM_DEV_ERROR(mhdp->dev, "sink does not support FEC: %d\n", ret); > This is too loud. will reduce the level. > >> + goto err; >> + } >> + >> + if (ret > 0) >> + return 0; >> +err: >> + return ret; >> +} > Consider extracting a common helper and using it here and in the Intel > DP driver. Also please use new DPCD helpers which return 0 instead of > size. > will use dpcd_helpers which return 0 instead of number of bytes read and check if anything can be extracted to drm dsc helpers I assume? >> + >> +static int cdns_mhdp_fec_sink_set_ready(struct cdns_mhdp_device *mhdp, >> + bool enable) >> +{ >> + int ret; >> + u8 dpcd_buffer; >> + >> + ret = drm_dp_dpcd_read(&mhdp->aux, DP_FEC_CONFIGURATION, &dpcd_buffer, 1); >> + if (ret < 0) >> + goto err; > No need to read it back, it's controlled by DPTX and you don't set > anything else. ok, will do the changes here. >> + >> + if (enable) >> + dpcd_buffer |= DP_FEC_READY; >> + else >> + dpcd_buffer &= ~DP_FEC_READY; >> + >> + ret = drm_dp_dpcd_write(&mhdp->aux, DP_FEC_CONFIGURATION, &dpcd_buffer, 1); >> + >> + if (ret > 0) >> + return 0; >> +err: >> + DRM_DEV_ERROR(mhdp->dev, "cannot set sink FEC ready: %d\n", ret); >> + return ret; >> +} >> + >> +static int cdns_mhdp_fec_set_ready(struct cdns_mhdp_device *mhdp, bool enable) >> +{ >> + int ret; >> + >> + ret = cdns_mhdp_fec_sink_support(mhdp); >> + if (ret) >> + goto err; >> + >> + ret = cdns_mhdp_fec_sink_set_ready(mhdp, enable); >> + if (ret) >> + goto err; >> + >> + ret = cdns_mhdp_reg_write_bit(mhdp, CDNS_DP_FEC_CTRL, 1, 1, enable); >> + if (ret) >> + goto err; >> + >> +err: >> + return ret; >> +} >> + >> +static int cdns_mhdp_fec_enable(struct cdns_mhdp_device *mhdp, bool enable) >> +{ >> + int ret; >> + u32 resp; >> + >> + ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp); >> + if (ret < 0) >> + goto err; >> + >> + if (!(resp & CDNS_DP_NO_VIDEO_MODE)) { >> + ret = -EIO; >> + goto err; >> + } >> + >> + ret = cdns_mhdp_reg_write_bit(mhdp, CDNS_DP_FEC_CTRL, 0, 1, enable); >> + if (ret) >> + goto err; >> + >> + return cdns_mhdp_wait_for_fec(mhdp, enable); >> +err: >> + DRM_DEV_ERROR(mhdp->dev, "set fec enable failed: %d\n", ret); >> + return ret; >> +} >> + >> /** >> * cdns_mhdp_link_configure() - configure a DisplayPort link >> * @aux: DisplayPort AUX channel >> @@ -1407,6 +1518,13 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp) >> amp[1] = DP_SET_ANSI_8B10B; >> drm_dp_dpcd_write(&mhdp->aux, DP_DOWNSPREAD_CTRL, amp, 2); >> >> + if (cdns_mhdp_fec_set_ready(mhdp, true)) { >> + mhdp->fec_enabled = false; >> + dev_info(mhdp->dev, "Cannot set FEC ready.\n"); > If DPRX doesn't support FEC, we've just got several messages for no > particular reason. It's an optional feature. will reduce the logging level. >> + } else { >> + mhdp->fec_enabled = true; >> + } >> + >> if (mhdp->host.fast_link & mhdp->sink.fast_link) { >> dev_err(mhdp->dev, "fastlink not supported\n"); >> return -EOPNOTSUPP; >> @@ -1494,10 +1612,14 @@ static int cdns_mhdp_connector_detect(struct drm_connector *conn, >> return cdns_mhdp_detect(mhdp); >> } >> >> -static u32 cdns_mhdp_get_bpp(struct cdns_mhdp_display_fmt *fmt) >> +static u32 cdns_mhdp_get_bpp(struct cdns_mhdp_device *mhdp) >> { >> + struct cdns_mhdp_display_fmt *fmt = &mhdp->display_fmt; >> u32 bpp; >> >> + if (mhdp->dsc_params.compression_enable) >> + return mhdp->dsc_params.compressed_bpp; >> + >> if (fmt->y_only) >> return fmt->bpc; >> >> @@ -1533,7 +1655,7 @@ bool cdns_mhdp_bandwidth_ok(struct cdns_mhdp_device *mhdp, >> * units of the rate parameter. >> */ >> >> - bpp = cdns_mhdp_get_bpp(&mhdp->display_fmt); >> + bpp = cdns_mhdp_get_bpp(mhdp); >> req_bw = mode->clock * bpp / 8; >> max_bw = lanes * rate; >> if (req_bw > max_bw) { >> @@ -1693,6 +1815,74 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge, >> return ret; >> } >> >> +static int cdns_mhdp_dsc_set_stream_compressed(struct cdns_mhdp_device *mhdp, >> + int stream_id, bool compressed) >> +{ >> + u32 reg_val; >> + int ret; >> + >> + ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_VB_ID(stream_id), ®_val); >> + if (ret < 0) >> + return ret; >> + >> + if (compressed) >> + reg_val |= CDNS_DP_VB_ID_COMPRESSED; >> + else >> + reg_val &= ~CDNS_DP_VB_ID_COMPRESSED; >> + >> + return cdns_mhdp_reg_write(mhdp, CDNS_DP_VB_ID(stream_id), reg_val); >> +} >> + >> +static int cdns_mhdp_dsc_wait_for_completion(struct cdns_mhdp_device *mhdp, >> + u8 event_bit, int stream_id) >> +{ >> + u32 dsc_ctrl; >> + int ret; >> + unsigned long timeout; >> + >> + ret = cdns_mhdp_reg_write_bit(mhdp, CDNS_DP_DSC_CTRL(stream_id), >> + event_bit, 1, true); >> + if (ret) >> + return ret; >> + >> + timeout = jiffies + msecs_to_jiffies(1000); >> + >> + do { >> + cdns_mhdp_reg_read(mhdp, CDNS_DP_DSC_CTRL(stream_id), &dsc_ctrl); >> + cpu_relax(); >> + } while (((dsc_ctrl & (1 << event_bit)) != 0) && time_before(jiffies, timeout)); >> + >> + if (time_after_eq(jiffies, timeout)) { >> + DRM_DEV_ERROR(mhdp->dev, "Timeout while waiting for event %d\n", event_bit); >> + return -ETIMEDOUT; >> + } >> + >> + return 0; >> +} >> + >> +static int cdns_mhdp_dsc_reset(struct cdns_mhdp_device *mhdp) >> +{ >> + /* Setting reset bit in any stream resets entire DSC. Stream 0 may always be used for it. */ >> + return cdns_mhdp_dsc_wait_for_completion(mhdp, CDNS_DP_DSC_CTRL_SW_RST_BIT, 0); >> +} >> + >> +static int cdns_mhdp_dsc_update(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + return cdns_mhdp_dsc_wait_for_completion(mhdp, CDNS_DP_DSC_CTRL_REG_UPDATE_BIT, >> + stream_id); >> +} >> + >> +static int cdns_mhdp_dsc_enable(struct cdns_mhdp_device *mhdp, int stream_id, bool enable) >> +{ >> + return cdns_mhdp_reg_write_bit(mhdp, CDNS_DP_DSC_CTRL(stream_id), >> + CDNS_DP_DSC_CTRL_EN_BIT, 1, enable ? 1 : 0); >> +} >> + >> +static int cdns_mhdp_dsc_sink_enable(struct cdns_mhdp_device *mhdp, bool enable) >> +{ >> + return drm_dp_dpcd_writeb(&mhdp->aux, DP_DSC_ENABLE, enable) != 1; >> +} >> + >> static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, >> const struct drm_display_mode *mode) >> { >> @@ -1702,7 +1892,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, >> front_porch, back_porch, msa_h0, msa_v0, hsync, vsync, >> dp_vertical_1; >> u8 stream_id = mhdp->stream_id; >> - u32 bpp, bpc, pxlfmt, framer; >> + u32 bpp, bpc, pxlfmt, framer, dp_byte_count; >> int ret; >> >> pxlfmt = mhdp->display_fmt.color_format; >> @@ -1716,7 +1906,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, >> pxlfmt == DRM_COLOR_FORMAT_YCBCR422) && mode->crtc_vdisplay >= 720) >> misc0 = DP_YCBCR_COEFFICIENTS_ITU709; >> >> - bpp = cdns_mhdp_get_bpp(&mhdp->display_fmt); >> + bpp = cdns_mhdp_get_bpp(mhdp); >> >> switch (pxlfmt) { >> case DRM_COLOR_FORMAT_RGB444: >> @@ -1765,6 +1955,9 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, >> if (mode->flags & DRM_MODE_FLAG_INTERLACE) >> bnd_hsync2vsync |= CDNS_IP_DET_INTERLACE_FORMAT; >> >> + if (mhdp->dsc_params.compression_enable) >> + bnd_hsync2vsync |= CDNS_IP_VIF_ALIGNMENT_LSB; >> + >> cdns_mhdp_reg_write(mhdp, CDNS_BND_HSYNC2VSYNC(stream_id), >> bnd_hsync2vsync); >> >> @@ -1792,8 +1985,14 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, >> CDNS_DP_FRONT_PORCH(front_porch) | >> CDNS_DP_BACK_PORCH(back_porch)); >> >> - cdns_mhdp_reg_write(mhdp, CDNS_DP_BYTE_COUNT(stream_id), >> - mode->crtc_hdisplay * bpp / 8); >> + if (mhdp->dsc_params.compression_enable) { >> + dp_byte_count = (((mhdp->dsc_config.slice_chunk_size / mhdp->link.num_lanes) + 1) << >> + CDNS_DP_BYTE_COUNT_BYTES_IN_CHUNK_SHIFT) | >> + ((mhdp->dsc_config.slice_chunk_size / mhdp->link.num_lanes) + 1); >> + } else { >> + dp_byte_count = (mode->crtc_hdisplay * bpp / 8); >> + } >> + cdns_mhdp_reg_write(mhdp, CDNS_DP_BYTE_COUNT(stream_id), dp_byte_count); >> >> msa_h0 = mode->crtc_htotal - mode->crtc_hsync_start; >> cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_0(stream_id), >> @@ -1852,6 +2051,9 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, >> (mode->flags & DRM_MODE_FLAG_INTERLACE) ? >> CDNS_DP_VB_ID_INTERLACED : 0); >> >> + if (mhdp->dsc_params.compression_enable) >> + cdns_mhdp_dsc_set_stream_compressed(mhdp, stream_id, true); >> + >> ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer); >> if (ret < 0) { >> dev_err(mhdp->dev, >> @@ -1860,7 +2062,6 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, >> return; >> } >> framer |= CDNS_DP_FRAMER_EN; >> - framer &= ~CDNS_DP_NO_VIDEO_MODE; >> cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer); >> } >> >> @@ -1869,20 +2070,67 @@ static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp, >> { >> u32 rate, vs, required_bandwidth, available_bandwidth; >> s32 line_thresh1, line_thresh2, line_thresh = 0; >> - int pxlclock = mode->crtc_clock; >> + int ret, pxlclock = mode->crtc_clock; >> + u32 vs_f, framer, pxl_repr; >> u32 tu_size = 64; >> u32 bpp; >> >> /* Get rate in MSymbols per second per lane */ >> rate = mhdp->link.rate / 1000; >> >> - bpp = cdns_mhdp_get_bpp(&mhdp->display_fmt); >> + if (mhdp->fec_enabled) { >> + if (cdns_mhdp_fec_enable(mhdp, true)) >> + mhdp->fec_enabled = false; >> + } else { >> + cdns_mhdp_fec_enable(mhdp, false); >> + } >> + >> + if (mhdp->dsc_supported && !cdns_mhdp_dsc_sink_support(mhdp)) { > Should be happening only if FEC is supported and enabled. yes, will change to enable DSCĀ  only when FEC is supported and enabled. > >> + ret = cdns_mhdp_dsc_reset(mhdp); >> + if (ret) >> + dev_err(mhdp->dev, "DSC reset failed. ret = %d\n", ret); >> + >> + mhdp->dsc_params.compressed_bpp = 8; >> + mhdp->dsc_params.slice_count = 10; > Why is it 10? for DSC independent mode, there is a requirement to use 1 slice per line. Basically, any value greater than or equal to 1 for slice_count should be supported. will check with some values and make changes if required, but not any specific reason for 10. > >> + >> + ret = cdns_mhdp_compute_dsc_params(mhdp); >> + if (ret < 0) { >> + mhdp->dsc_params.compression_enable = false; >> + dev_err(mhdp->dev, "DSC params computation failed. ret = %d\n", ret); >> + } else { >> + mhdp->dsc_params.compression_enable = true; >> + /* Write config for stream 0 */ >> + cdns_mhdp_dsc_write_enc_config(mhdp, 0, mode); >> + cdns_mhdp_dsc_update(mhdp, 0); >> + cdns_mhdp_dsc_write_config(mhdp); >> + } >> + } else { >> + if (mhdp->dsc_params.compression_enable) { >> + cdns_mhdp_dsc_sink_enable(mhdp, false); >> + cdns_mhdp_dsc_set_stream_compressed(mhdp, 0, false); >> + } >> + mhdp->dsc_params.compression_enable = false; >> + } >> + >> + /* Enable DSC for stream 0 */ >> + if (mhdp->dsc_params.compression_enable) { >> + cdns_mhdp_dsc_enable(mhdp, 0, true); >> + >> + if (cdns_mhdp_dsc_sink_enable(mhdp, true)) >> + dev_err(mhdp->dev, "Cannot enable DSC in sink.\n"); >> + cdns_mhdp_dsc_send_pps_sdp(mhdp, 0); >> + } >> + >> + bpp = cdns_mhdp_get_bpp(mhdp); >> >> required_bandwidth = pxlclock * bpp / 8; >> available_bandwidth = mhdp->link.num_lanes * rate; >> >> - vs = tu_size * required_bandwidth / available_bandwidth; >> - vs /= 1000; >> + vs_f = tu_size * required_bandwidth / available_bandwidth; >> + if (mhdp->fec_enabled) >> + vs_f = (vs_f * 1024) / 1000; //2.4% >> + vs = vs_f / 1000; >> + vs_f = vs_f % 1000; >> >> if (vs == tu_size) >> vs = tu_size - 1; >> @@ -1907,6 +2155,70 @@ static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp, >> 0 : tu_size - vs)); >> >> cdns_mhdp_configure_video(mhdp, mode); >> + >> + if (mhdp->dsc_params.compression_enable) { >> + cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_PXL_REPR(0), &pxl_repr); >> + pxl_repr &= ~CDNS_DP_FRAMER_PXL_REPR_M; >> + pxl_repr &= ~CDNS_DP_FRAMER_PXL_REPR_DIFF; >> + pxl_repr |= (((vs_f / 10) << CDNS_DP_FRAMER_PXL_REPR_M_SHIFT) >> + & CDNS_DP_FRAMER_PXL_REPR_M) | >> + (((100 - (vs_f / 10)) << CDNS_DP_FRAMER_PXL_REPR_DIFF_SHIFT) >> + & CDNS_DP_FRAMER_PXL_REPR_DIFF); >> + cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_PXL_REPR(0), pxl_repr); >> + } >> + >> + /* Enable video mode */ >> + cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer); >> + framer &= ~CDNS_DP_NO_VIDEO_MODE; >> + cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer); >> +} >> + >> +static int cdns_mhdp_configure_car(struct cdns_mhdp_device *mhdp, bool enable) >> +{ >> + u32 dptx_car, source_pkt_car; >> + int ret; >> + >> + ret = cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &dptx_car); >> + if (ret < 0) { >> + dev_err(mhdp->dev, "Failed to read CDNS_DPTX_CAR %d\n", ret); >> + goto out; >> + } >> + >> + ret = cdns_mhdp_reg_read(mhdp, CDNS_SOURCE_PKT_CAR, &source_pkt_car); >> + if (ret < 0) { >> + dev_err(mhdp->dev, "Failed to read CDNS_SOURCE_PKT_CAR %d\n", ret); >> + goto out; >> + } >> + >> + if (enable) { >> + dev_dbg(mhdp->dev, "%s: Enable clocks for VIF and PIF\n", __func__); >> + >> + /* Enable VIF clock for stream 0 */ >> + cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR, >> + dptx_car | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN); >> + >> + /* Enable PKT clock */ >> + cdns_mhdp_reg_write(mhdp, CDNS_SOURCE_PKT_CAR, >> + source_pkt_car | CDNS_PKT_DATA_CLK_EN >> + | CDNS_PKT_DATA_RSTN >> + | CDNS_PKT_SYS_CLK_EN >> + | CDNS_PKT_SYS_RSTN); >> + } else { >> + dev_dbg(mhdp->dev, "%s: Disable clocks for VIF and PIF\n", __func__); >> + >> + /* Disable VIF clock for stream 0 */ >> + cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR, >> + dptx_car & ~(CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN)); >> + >> + /* Disable PKT clock */ >> + cdns_mhdp_reg_write(mhdp, CDNS_SOURCE_PKT_CAR, >> + source_pkt_car & ~(CDNS_PKT_DATA_CLK_EN >> + | CDNS_PKT_DATA_RSTN >> + | CDNS_PKT_SYS_CLK_EN >> + | CDNS_PKT_SYS_RSTN)); >> + } >> +out: >> + return ret; >> } >> >> static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge, >> @@ -1919,8 +2231,7 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge, >> struct drm_connector_state *conn_state; >> struct drm_bridge_state *new_state; >> const struct drm_display_mode *mode; >> - u32 resp; >> - int ret; >> + int ret = 0; >> >> dev_dbg(mhdp->dev, "bridge enable\n"); >> >> @@ -1935,16 +2246,13 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge, >> if (mhdp->info && mhdp->info->ops && mhdp->info->ops->enable) >> mhdp->info->ops->enable(mhdp); >> >> - /* Enable VIF clock for stream 0 */ >> - ret = cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp); >> + /* Enable clocks for video and packet interfaces */ >> + ret = cdns_mhdp_configure_car(mhdp, true); >> if (ret < 0) { >> - dev_err(mhdp->dev, "Failed to read CDNS_DPTX_CAR %d\n", ret); >> + dev_err(mhdp->dev, "Failed to enable clocks %d\n", ret); >> goto out; >> } >> >> - cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR, >> - resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN); >> - >> connector = drm_atomic_get_new_connector_for_encoder(state, >> bridge->encoder); >> if (WARN_ON(!connector)) >> @@ -2020,10 +2328,8 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge, >> >> cdns_mhdp_link_down(mhdp); >> >> - /* Disable VIF clock for stream 0 */ >> - cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp); >> - cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR, >> - resp & ~(CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN)); >> + /* Disable clocks for video and packet interfaces */ >> + cdns_mhdp_configure_car(mhdp, false); >> >> if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable) >> mhdp->info->ops->disable(mhdp); >> @@ -2119,7 +2425,7 @@ static int cdns_mhdp_atomic_check(struct drm_bridge *bridge, >> struct drm_connector_state *conn_state) >> { >> struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge); >> - const struct drm_display_mode *mode = &crtc_state->adjusted_mode; >> + struct drm_display_mode *mode = &crtc_state->adjusted_mode; >> >> mutex_lock(&mhdp->link_mutex); >> >> @@ -2139,6 +2445,10 @@ static int cdns_mhdp_atomic_check(struct drm_bridge *bridge, >> if (mhdp->info) >> bridge_state->input_bus_cfg.flags = *mhdp->info->input_bus_flags; >> >> + //TODO For DSC. Might need proper handling. 1920x1080 mode doesn't work without this. >> + mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); >> + mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC); >> + >> mutex_unlock(&mhdp->link_mutex); >> return 0; >> } >> @@ -2426,6 +2736,15 @@ static int cdns_mhdp_probe(struct platform_device *pdev) >> mhdp->hdcp_supported = true; >> } >> >> + mhdp->dsc_regs = devm_platform_ioremap_resource_byname(pdev, "dsc"); >> + if (IS_ERR(mhdp->dsc_regs)) { >> + mhdp->dsc_supported = false; >> + dev_info(dev, >> + "Failed to get DSC memory resource, DSC not supported\n"); >> + } else { >> + mhdp->dsc_supported = true; >> + } >> + >> mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node, 0); >> if (IS_ERR(mhdp->phy)) { >> dev_err(dev, "no PHY configured\n"); >> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h >> index bad2fc0c7306..c8f8071776d7 100644 >> --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h >> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h >> @@ -16,6 +16,7 @@ >> #include >> >> #include >> +#include >> #include >> #include >> >> @@ -66,18 +67,30 @@ struct phy; >> #define CDNS_VIF_CLK_EN BIT(0) >> #define CDNS_VIF_CLK_RSTN BIT(1) >> >> +#define CDNS_SOURCE_PKT_CAR 0x00918 >> +#define CDNS_PKT_DATA_CLK_EN BIT(0) >> +#define CDNS_PKT_DATA_RSTN BIT(1) >> +#define CDNS_PKT_SYS_CLK_EN BIT(2) >> +#define CDNS_PKT_SYS_RSTN BIT(3) >> + >> #define CDNS_SOURCE_VIDEO_IF(s) (0x00b00 + ((s) * 0x20)) >> #define CDNS_BND_HSYNC2VSYNC(s) (CDNS_SOURCE_VIDEO_IF(s) + \ >> 0x00) >> #define CDNS_IP_DTCT_WIN GENMASK(11, 0) >> #define CDNS_IP_DET_INTERLACE_FORMAT BIT(12) >> #define CDNS_IP_BYPASS_V_INTERFACE BIT(13) >> +#define CDNS_IP_VIF_ALIGNMENT_LSB BIT(14) >> >> #define CDNS_HSYNC2VSYNC_POL_CTRL(s) (CDNS_SOURCE_VIDEO_IF(s) + \ >> 0x10) >> #define CDNS_H2V_HSYNC_POL_ACTIVE_LOW BIT(1) >> #define CDNS_H2V_VSYNC_POL_ACTIVE_LOW BIT(2) >> >> +#define CDNS_DP_DSC_CTRL(s) (CDNS_SOURCE_VIDEO_IF(s) + 0x14) >> +#define CDNS_DP_DSC_CTRL_EN_BIT 0 >> +#define CDNS_DP_DSC_CTRL_SW_RST_BIT 1 >> +#define CDNS_DP_DSC_CTRL_REG_UPDATE_BIT 2 >> + >> #define CDNS_DPTX_PHY_CONFIG 0x02000 >> #define CDNS_PHY_TRAINING_EN BIT(0) >> #define CDNS_PHY_TRAINING_TYPE(x) (((x) & GENMASK(3, 0)) << 1) >> @@ -121,6 +134,10 @@ struct phy; >> >> #define CDNS_DP_ENHNCD 0x02304 >> >> +#define CDNS_DP_FEC_CTRL 0x02310 >> +#define CDNS_DP_FEC_STATUS 0x02314 >> +#define CDNS_DP_FEC_BUSY BIT(0) >> + >> #define CDNS_DPTX_STREAM(s) (0x03000 + (s) * 0x80) >> #define CDNS_DP_MSA_HORIZONTAL_0(s) (CDNS_DPTX_STREAM(s) + 0x00) >> #define CDNS_DP_MSAH0_H_TOTAL(x) (x) >> @@ -178,6 +195,10 @@ struct phy; >> #define CDNS_DP_FRAMER_YCBCR422 BIT(2) >> #define CDNS_DP_FRAMER_YCBCR420 BIT(3) >> #define CDNS_DP_FRAMER_Y_ONLY BIT(4) >> +#define CDNS_DP_FRAMER_PXL_REPR_M GENMASK(22, 16) >> +#define CDNS_DP_FRAMER_PXL_REPR_DIFF GENMASK(30, 24) >> +#define CDNS_DP_FRAMER_PXL_REPR_M_SHIFT 16 >> +#define CDNS_DP_FRAMER_PXL_REPR_DIFF_SHIFT 24 >> >> #define CDNS_DP_FRAMER_SP(s) (CDNS_DPTX_STREAM(s) + 0x50) >> #define CDNS_DP_FRAMER_VSYNC_POL_LOW BIT(0) >> @@ -198,6 +219,38 @@ struct phy; >> #define CDNS_DP_BYTE_COUNT(s) (CDNS_DPTX_STREAM(s) + 0x7c) >> #define CDNS_DP_BYTE_COUNT_BYTES_IN_CHUNK_SHIFT 16 >> >> +#define CDNS_SOURCE_PACKET_IF(s) (0x30800 + ((s) * 0x40)) >> +#define CDNS_SOURCE_PIF_WR_ADDR(s) (CDNS_SOURCE_PACKET_IF(s) + 0x00) >> + >> +#define CDNS_SOURCE_PIF_WR_REQ(s) (CDNS_SOURCE_PACKET_IF(s) + 0x04) >> +#define SOURCE_PIF_WR_REQ_HOST_WR BIT(0) >> + >> +#define CDNS_SOURCE_PIF_RD_ADDR(s) (CDNS_SOURCE_PACKET_IF(s) + 0x08) >> +#define CDNS_SOURCE_PIF_RD_REQ(s) (CDNS_SOURCE_PACKET_IF(s) + 0x0c) >> +#define CDNS_SOURCE_PIF_DATA_WR(s) (CDNS_SOURCE_PACKET_IF(s) + 0x10) >> +#define CDNS_SOURCE_PIF_DATA_RD(s) (CDNS_SOURCE_PACKET_IF(s) + 0x14) >> +#define CDNS_SOURCE_PIF_FIFO1_FLUSH(s) (CDNS_SOURCE_PACKET_IF(s) + 0x18) >> +#define CDNS_SOURCE_PIF_FIFO2_FLUSH(s) (CDNS_SOURCE_PACKET_IF(s) + 0x1c) >> +#define CDNS_SOURCE_PIF_STATUS(s) (CDNS_SOURCE_PACKET_IF(s) + 0x20) >> +#define CDNS_SOURCE_PIF_INT_SOURCE(s) (CDNS_SOURCE_PACKET_IF(s) + 0x24) >> +#define CDNS_SOURCE_PIF_INT_MASK(s) (CDNS_SOURCE_PACKET_IF(s) + 0x28) >> + >> +#define CDNS_SOURCE_PIF_PKT_ALLOC_REG(s) (CDNS_SOURCE_PACKET_IF(s) + 0x2c) >> +#define SOURCE_PIF_PKT_ALLOC_REG_ACTIVE_IDLE_TYPE BIT(17) >> +#define SOURCE_PIF_PKT_ALLOC_REG_TYPE_VALID BIT(16) >> +#define SOURCE_PIF_PKT_ALLOC_REG_PACKET_TYPE GENMASK(15, 8) >> +#define SOURCE_PIF_PKT_ALLOC_REG_PACKET_TYPE_SHIFT 8 >> +#define SOURCE_PIF_PKT_ALLOC_REG_PKT_ALLOC_ADDR GENMASK(3, 0) >> + >> +#define CDNS_SOURCE_PIF_PKT_ALLOC_WR_EN(s) (CDNS_SOURCE_PACKET_IF(s) + 0x30) >> +#define SOURCE_PIF_PKT_ALLOC_WR_EN_EN BIT(0) >> + >> +#define CDNS_SOURCE_PIF_SW_RST(s) (CDNS_SOURCE_PACKET_IF(s) + 0x34) >> +#define CDNS_SOURCE_PIF_PPS_HEADER(s) (CDNS_SOURCE_PACKET_IF(s) + 0x38) >> + >> +#define CDNS_SOURCE_PIF_PPS(s) (CDNS_SOURCE_PACKET_IF(s) + 0x3c) >> +#define SOURCE_PIF_PPS_PPS BIT(0) >> + >> /* mailbox */ >> #define MAILBOX_RETRY_US 1000 >> #define MAILBOX_TIMEOUT_US 2000000 >> @@ -354,6 +407,7 @@ struct cdns_mhdp_hdcp { >> struct cdns_mhdp_device { >> void __iomem *regs; >> void __iomem *sapb_regs; >> + void __iomem *dsc_regs; >> void __iomem *j721e_regs; >> >> struct device *dev; >> @@ -412,6 +466,20 @@ struct cdns_mhdp_device { >> >> struct cdns_mhdp_hdcp hdcp; >> bool hdcp_supported; >> + >> + struct drm_dsc_config dsc_config; >> + >> + /* Display Stream Compression state */ >> + bool dsc_supported; >> + struct { >> + bool compression_enable; >> + bool dsc_split; >> + u16 compressed_bpp; >> + u8 slice_count; >> + u8 dsc_cap[DP_DSC_RECEIVER_CAP_SIZE]; >> + } dsc_params; >> + >> + bool fec_enabled; >> }; >> >> #define connector_to_mhdp(x) container_of(x, struct cdns_mhdp_device, connector) >> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-dsc.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-dsc.c >> new file mode 100644 >> index 000000000000..e540e8f2dd4a >> --- /dev/null >> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-dsc.c >> @@ -0,0 +1,695 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Copyright (C) Cadence Design Systems, Inc. >> + * >> + * Author: Swapnil Jakhade >> + */ >> + >> +#include "cdns-mhdp8546-core.h" >> +#include "cdns-mhdp8546-dsc.h" >> + >> +void cdns_mhdp_dsc_write_config(struct cdns_mhdp_device *mhdp) >> +{ >> + u32 main_conf = 0; >> + >> + main_conf = CDNS_DP_COM_MAIN_CONF_INPUT_MODE | >> + CDNS_DP_COM_MAIN_CONF_AUTO_DB_UPDATE; >> + >> + if (mhdp->dsc_params.dsc_split) { >> + main_conf |= CDNS_DP_COM_MAIN_CONF_MUX_MODE | >> + CDNS_DP_COM_MAIN_CONF_SPLIT_PANEL; >> + } >> + >> + writel(main_conf, mhdp->dsc_regs + CDNS_DP_COM_MAIN_CONF); >> +} >> + >> +static u8 cdns_mhdp_dsc_compute_initial_lines(struct cdns_mhdp_device *mhdp) >> +{ >> + struct drm_dsc_config *dsc_cfg = &mhdp->dsc_config; >> + unsigned long k1, real_bpp; >> + u8 initial_lines; >> + >> + real_bpp = (unsigned long)dsc_cfg->bits_per_pixel / 16; >> + >> + if (dsc_cfg->bits_per_component == 8) >> + k1 = 296; >> + else >> + k1 = 320; >> + >> + if (mhdp->dsc_params.dsc_split) { >> + initial_lines = (u8)DIV_ROUND_UP >> + ((k1 + (unsigned long)dsc_cfg->initial_xmit_delay + >> + ((((unsigned long)dsc_cfg->slice_chunk_size * 8) + 144) / >> + real_bpp)), (unsigned long)dsc_cfg->slice_width); >> + } else { >> + initial_lines = (u8)DIV_ROUND_UP >> + ((k1 + (unsigned long)dsc_cfg->initial_xmit_delay + >> + ((DIV_ROUND_UP(((1 - (real_bpp / 48)) * >> + ((unsigned long)dsc_cfg->slice_chunk_size * 8)), 1) + 144) / >> + real_bpp)), (unsigned long)dsc_cfg->slice_width); >> + } > Is there a way to make it possible to comprehend? will break it down and make it better. > >> + >> + return initial_lines; >> +} >> + >> +static void write_enc_main_conf(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val = 0; >> + >> + if (mhdp->dsc_config.convert_rgb) >> + reg_val |= CDNS_DP_ENC_MAIN_CONF_CONVERT_RGB; >> + >> + reg_val |= (mhdp->dsc_config.line_buf_depth << >> + CDNS_DP_ENC_MAIN_CONF_LINEBUF_DEPTH_SHIFT) & >> + CDNS_DP_ENC_MAIN_CONF_LINEBUF_DEPTH; >> + >> + reg_val |= (mhdp->dsc_config.bits_per_pixel << >> + CDNS_DP_ENC_MAIN_CONF_BITS_PER_PIXEL_SHIFT) & >> + CDNS_DP_ENC_MAIN_CONF_BITS_PER_PIXEL; >> + >> + if (mhdp->dsc_config.block_pred_enable) >> + reg_val |= CDNS_DP_ENC_MAIN_CONF_BLOCK_PRED_EN; >> + >> + reg_val |= CDNS_DP_ENC_MAIN_CONF_VIDEO_MODE; >> + >> + reg_val |= (cdns_mhdp_dsc_compute_initial_lines(mhdp) << >> + CDNS_DP_ENC_MAIN_CONF_INITIAL_LINES_SHIFT) & >> + CDNS_DP_ENC_MAIN_CONF_INITIAL_LINES; >> + >> + if (mhdp->dsc_config.bits_per_component == 10) >> + reg_val |= 0x1; >> + else if (mhdp->dsc_config.bits_per_component != 8) >> + dev_err(mhdp->dev, "Unsupported bits_per_component = %d\n", >> + mhdp->dsc_config.bits_per_component); >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_MAIN_CONF(stream_id)); >> +} >> + >> +static void write_enc_picture_size(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val = 0; >> + >> + reg_val = (mhdp->dsc_config.pic_width & >> + CDNS_DP_ENC_PICTURE_SIZE_WIDTH); >> + >> + reg_val |= (mhdp->dsc_config.pic_height << >> + CDNS_DP_ENC_PICTURE_SIZE_HEIGHT_SHIFT) & >> + CDNS_DP_ENC_PICTURE_SIZE_HEIGHT; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_PICTURE_SIZE(stream_id)); >> +} >> + >> +static void write_enc_slice_size(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val = 0; >> + >> + reg_val = (mhdp->dsc_config.slice_width & >> + CDNS_DP_ENC_SLICE_SIZE_WIDTH); >> + >> + reg_val |= (mhdp->dsc_config.slice_height << >> + CDNS_DP_ENC_SLICE_SIZE_HEIGHT_SHIFT) & >> + CDNS_DP_ENC_SLICE_SIZE_HEIGHT; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_SLICE_SIZE(stream_id)); >> +} >> + >> +static void write_enc_misc_size(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val = 0; >> + >> + reg_val = ((mhdp->dsc_config.slice_width + 2) % 3) & >> + CDNS_DP_ENC_MISC_SIZE_LAST_GRP_SIZE; >> + >> + reg_val |= (DSC_OUTPUT_BUFFER_MAX_ADDRESS << >> + CDNS_DP_ENC_MISC_SIZE_OB_MAX_ADDR_SHIFT) & >> + CDNS_DP_ENC_MISC_SIZE_OB_MAX_ADDR; >> + >> + reg_val |= (mhdp->dsc_config.slice_chunk_size << >> + CDNS_DP_ENC_MISC_SIZE_CHUNK_SIZE_SHIFT) & >> + CDNS_DP_ENC_MISC_SIZE_CHUNK_SIZE; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_MISC_SIZE(stream_id)); >> +} >> + >> +static void write_enc_hrd_delays(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val = 0; >> + >> + reg_val = (mhdp->dsc_config.initial_xmit_delay & >> + CDNS_DP_ENC_HRD_DELAYS_INIT_XMIT_DELAY); >> + >> + reg_val |= (mhdp->dsc_config.initial_dec_delay << >> + CDNS_DP_ENC_HRD_DELAYS_INIT_DEC_DELAY_SHIFT) & >> + CDNS_DP_ENC_HRD_DELAYS_INIT_DEC_DELAY; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_HRD_DELAYS(stream_id)); >> +} >> + >> +static void write_enc_rc_scale(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val = 0; >> + >> + reg_val = (mhdp->dsc_config.initial_scale_value & >> + CDNS_DP_ENC_RC_SCALE_INIT_SCALE_VALUE); >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_SCALE(stream_id)); >> +} >> + >> +static void write_enc_rc_scale_inc_dec(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val = 0; >> + >> + reg_val = (mhdp->dsc_config.scale_increment_interval & >> + CDNS_DP_ENC_RC_SCALE_INC_INTERVAL); >> + >> + reg_val |= (mhdp->dsc_config.scale_decrement_interval << >> + CDNS_DP_ENC_RC_SCALE_DEC_INTERVAL_SHIFT) & >> + CDNS_DP_ENC_RC_SCALE_DEC_INTERVAL; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_SCALE_INC_DEC(stream_id)); >> +} >> + >> +static void write_enc_rc_offsets(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val; >> + >> + reg_val = (mhdp->dsc_config.first_line_bpg_offset & >> + CDNS_DP_ENC_RC_OFFSETS_1_FL_BPG_OFFSET); >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_OFFSETS_1(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.nfl_bpg_offset & >> + CDNS_DP_ENC_RC_OFFSETS_2_NFL_BPG_OFFSET); >> + >> + reg_val |= (mhdp->dsc_config.slice_bpg_offset << >> + CDNS_DP_ENC_RC_OFFSETS_2_SL_BPG_OFFSET_SHIFT) & >> + CDNS_DP_ENC_RC_OFFSETS_2_SL_BPG_OFFSET; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_OFFSETS_2(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.initial_offset & >> + CDNS_DP_ENC_RC_OFFSETS_3_INIT_OFFSET); >> + >> + reg_val |= (mhdp->dsc_config.final_offset << >> + CDNS_DP_ENC_RC_OFFSETS_3_FINAL_OFFSET_SHIFT) & >> + CDNS_DP_ENC_RC_OFFSETS_3_FINAL_OFFSET; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_OFFSETS_3(stream_id)); >> +} >> + >> +static void write_enc_flatness_detection(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val; >> + >> + reg_val = (mhdp->dsc_config.flatness_min_qp & >> + CDNS_DP_ENC_FLATNESS_DETECTION_MIN_QP); >> + >> + reg_val |= (mhdp->dsc_config.flatness_max_qp << >> + CDNS_DP_ENC_FLATNESS_DETECTION_MAX_QP_SHIFT) & >> + CDNS_DP_ENC_FLATNESS_DETECTION_MAX_QP; >> + >> + reg_val |= (drm_dsc_flatness_det_thresh(&mhdp->dsc_config) << >> + CDNS_DP_ENC_FLATNESS_DETECTION_THRESH_SHIFT) & >> + CDNS_DP_ENC_FLATNESS_DETECTION_THRESH; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_FLATNESS_DETECTION(stream_id)); >> +} >> + >> +static void write_enc_rc_model_size(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val; >> + >> + reg_val = (mhdp->dsc_config.rc_model_size & >> + CDNS_DP_ENC_RC_MODEL_SIZE_RC_MODEL_SIZE); >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_MODEL_SIZE(stream_id)); >> +} >> + >> +static void write_enc_rc_config(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val; >> + >> + reg_val = (mhdp->dsc_config.rc_edge_factor & >> + CDNS_DP_ENC_RC_CONFIG_EDGE_FACTOR); >> + >> + reg_val |= (mhdp->dsc_config.rc_quant_incr_limit0 << >> + CDNS_DP_ENC_RC_CONFIG_QUANT_INC_LIM_0_SHIFT) & >> + CDNS_DP_ENC_RC_CONFIG_QUANT_INC_LIM_0; >> + >> + reg_val |= (mhdp->dsc_config.rc_quant_incr_limit1 << >> + CDNS_DP_ENC_RC_CONFIG_QUANT_INC_LIM_1_SHIFT) & >> + CDNS_DP_ENC_RC_CONFIG_QUANT_INC_LIM_1; >> + >> + reg_val |= (mhdp->dsc_config.rc_tgt_offset_high << >> + CDNS_DP_ENC_RC_CONFIG_TGT_OFFSET_HI_SHIFT) & >> + CDNS_DP_ENC_RC_CONFIG_TGT_OFFSET_HI; >> + >> + reg_val |= (mhdp->dsc_config.rc_tgt_offset_low << >> + CDNS_DP_ENC_RC_CONFIG_TGT_OFFSET_LO_SHIFT) & >> + CDNS_DP_ENC_RC_CONFIG_TGT_OFFSET_LO; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_CONFIG(stream_id)); >> +} >> + >> +static void write_enc_rc_buf_thresh(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val; >> + int index = 0; >> + >> + reg_val = (mhdp->dsc_config.rc_buf_thresh[index++] & >> + CDNS_DP_ENC_RC_BUF_THRESH_0_THRESH_0); >> + >> + reg_val |= (mhdp->dsc_config.rc_buf_thresh[index++] << >> + CDNS_DP_ENC_RC_BUF_THRESH_THRESH_1_SHIFT) & >> + CDNS_DP_ENC_RC_BUF_THRESH_0_THRESH_1; >> + >> + reg_val |= (mhdp->dsc_config.rc_buf_thresh[index++] << >> + CDNS_DP_ENC_RC_BUF_THRESH_THRESH_2_SHIFT) & >> + CDNS_DP_ENC_RC_BUF_THRESH_0_THRESH_2; >> + >> + reg_val |= (mhdp->dsc_config.rc_buf_thresh[index++] << >> + CDNS_DP_ENC_RC_BUF_THRESH_THRESH_3_SHIFT) & >> + CDNS_DP_ENC_RC_BUF_THRESH_0_THRESH_3; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_BUF_THRESH_0(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.rc_buf_thresh[index++] & >> + CDNS_DP_ENC_RC_BUF_THRESH_1_THRESH_4); >> + >> + reg_val |= (mhdp->dsc_config.rc_buf_thresh[index++] << >> + CDNS_DP_ENC_RC_BUF_THRESH_THRESH_1_SHIFT) & >> + CDNS_DP_ENC_RC_BUF_THRESH_1_THRESH_5; >> + >> + reg_val |= (mhdp->dsc_config.rc_buf_thresh[index++] << >> + CDNS_DP_ENC_RC_BUF_THRESH_THRESH_2_SHIFT) & >> + CDNS_DP_ENC_RC_BUF_THRESH_1_THRESH_6; >> + >> + reg_val |= (mhdp->dsc_config.rc_buf_thresh[index++] << >> + CDNS_DP_ENC_RC_BUF_THRESH_THRESH_3_SHIFT) & >> + CDNS_DP_ENC_RC_BUF_THRESH_1_THRESH_7; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_BUF_THRESH_1(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.rc_buf_thresh[index++] & >> + CDNS_DP_ENC_RC_BUF_THRESH_2_THRESH_8); >> + >> + reg_val |= (mhdp->dsc_config.rc_buf_thresh[index++] << >> + CDNS_DP_ENC_RC_BUF_THRESH_THRESH_1_SHIFT) & >> + CDNS_DP_ENC_RC_BUF_THRESH_2_THRESH_9; >> + >> + reg_val |= (mhdp->dsc_config.rc_buf_thresh[index++] << >> + CDNS_DP_ENC_RC_BUF_THRESH_THRESH_2_SHIFT) & >> + CDNS_DP_ENC_RC_BUF_THRESH_2_THRESH_10; >> + >> + reg_val |= (mhdp->dsc_config.rc_buf_thresh[index++] << >> + CDNS_DP_ENC_RC_BUF_THRESH_THRESH_3_SHIFT) & >> + CDNS_DP_ENC_RC_BUF_THRESH_2_THRESH_11; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_BUF_THRESH_2(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.rc_buf_thresh[index++] & >> + CDNS_DP_ENC_RC_BUF_THRESH_3_THRESH_12); >> + >> + reg_val |= (mhdp->dsc_config.rc_buf_thresh[index++] << >> + CDNS_DP_ENC_RC_BUF_THRESH_THRESH_1_SHIFT) & >> + CDNS_DP_ENC_RC_BUF_THRESH_3_THRESH_13; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_BUF_THRESH_3(stream_id)); >> +} >> + >> +static void write_enc_rc_min_qp(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val; >> + int index = 0; >> + >> + reg_val = (mhdp->dsc_config.rc_range_params[index++].range_min_qp & >> + CDNS_DP_ENC_RC_MIN_QP_0_RANGE_0); >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_1_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_0_RANGE_1; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_2_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_0_RANGE_2; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_3_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_0_RANGE_3; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_4_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_0_RANGE_4; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_MIN_QP_0(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.rc_range_params[index++].range_min_qp & >> + CDNS_DP_ENC_RC_MIN_QP_1_RANGE_5); >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_1_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_1_RANGE_6; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_2_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_1_RANGE_7; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_3_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_1_RANGE_8; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_4_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_1_RANGE_9; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_MIN_QP_1(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.rc_range_params[index++].range_min_qp & >> + CDNS_DP_ENC_RC_MIN_QP_2_RANGE_10); >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_1_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_2_RANGE_11; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_2_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_2_RANGE_12; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_3_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_2_RANGE_13; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_min_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_4_SHIFT) & >> + CDNS_DP_ENC_RC_MIN_QP_2_RANGE_14; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_MIN_QP_2(stream_id)); >> +} >> + >> +static void write_enc_rc_max_qp(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val; >> + int index = 0; >> + >> + reg_val = (mhdp->dsc_config.rc_range_params[index++].range_max_qp & >> + CDNS_DP_ENC_RC_MAX_QP_0_RANGE_0); >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_1_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_0_RANGE_1; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_2_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_0_RANGE_2; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_3_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_0_RANGE_3; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_4_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_0_RANGE_4; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_MAX_QP_0(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.rc_range_params[index++].range_max_qp & >> + CDNS_DP_ENC_RC_MAX_QP_1_RANGE_5); >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_1_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_1_RANGE_6; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_2_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_1_RANGE_7; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_3_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_1_RANGE_8; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_4_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_1_RANGE_9; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_MAX_QP_1(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.rc_range_params[index++].range_max_qp & >> + CDNS_DP_ENC_RC_MAX_QP_2_RANGE_10); >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_1_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_2_RANGE_11; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_2_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_2_RANGE_12; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_3_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_2_RANGE_13; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_max_qp << >> + CDNS_DP_ENC_RC_QP_RANGE_4_SHIFT) & >> + CDNS_DP_ENC_RC_MAX_QP_2_RANGE_14; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_MAX_QP_2(stream_id)); >> +} >> + >> +static void write_enc_rc_range_bpg(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + u32 reg_val; >> + int index = 0; >> + >> + reg_val = (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_0); >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_1_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_1; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_2_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_2; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_3_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_3; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_4_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_4; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_5); >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_1_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_6; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_2_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_7; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_3_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_8; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_4_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_9; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_1(stream_id)); >> + >> + reg_val = (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_10); >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_1_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_11; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_2_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_12; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_3_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_13; >> + >> + reg_val |= (mhdp->dsc_config.rc_range_params[index++].range_bpg_offset << >> + CDNS_DP_ENC_RC_QP_RANGE_4_SHIFT) & >> + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_14; >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_2(stream_id)); >> +} >> + >> +static void write_enc_dpi_ctrl(struct cdns_mhdp_device *mhdp, int stream_id, >> + const struct drm_display_mode *mode) >> +{ >> + u32 reg_val = 0; >> + >> + reg_val = ((mode->crtc_htotal * cdns_mhdp_dsc_compute_initial_lines(mhdp)) & >> + CDNS_DP_ENC_DPI_CTRL_OUT_DELAY_CYCLES); >> + >> + writel(reg_val, mhdp->dsc_regs + CDNS_DP_ENC_DPI_CTRL_OUT_DELAY(stream_id)); >> +} >> + >> +void cdns_mhdp_dsc_write_enc_config(struct cdns_mhdp_device *mhdp, int stream_id, >> + const struct drm_display_mode *mode) >> +{ >> + write_enc_main_conf(mhdp, stream_id); >> + write_enc_picture_size(mhdp, stream_id); >> + write_enc_slice_size(mhdp, stream_id); >> + write_enc_misc_size(mhdp, stream_id); >> + write_enc_hrd_delays(mhdp, stream_id); >> + write_enc_rc_scale(mhdp, stream_id); >> + write_enc_rc_scale_inc_dec(mhdp, stream_id); >> + write_enc_rc_offsets(mhdp, stream_id); >> + write_enc_flatness_detection(mhdp, stream_id); >> + write_enc_rc_model_size(mhdp, stream_id); >> + write_enc_rc_config(mhdp, stream_id); >> + write_enc_rc_buf_thresh(mhdp, stream_id); >> + write_enc_rc_min_qp(mhdp, stream_id); >> + write_enc_rc_max_qp(mhdp, stream_id); >> + write_enc_rc_range_bpg(mhdp, stream_id); >> + write_enc_dpi_ctrl(mhdp, stream_id, mode); >> +} >> + >> +int cdns_mhdp_dsc_sink_support(struct cdns_mhdp_device *mhdp) >> +{ >> + int ret; >> + >> + ret = drm_dp_dpcd_read(&mhdp->aux, DP_DSC_SUPPORT, &mhdp->dsc_params.dsc_cap, >> + DP_DSC_RECEIVER_CAP_SIZE); >> + if (ret != DP_DSC_RECEIVER_CAP_SIZE) { >> + DRM_DEV_ERROR(mhdp->dev, "cannot read sink DSC DPCD: %d\n", ret); >> + goto err; >> + } >> + if (!(mhdp->dsc_params.dsc_cap[0] & DP_DSC_DECOMPRESSION_IS_SUPPORTED)) { >> + ret = -EOPNOTSUPP; >> + DRM_DEV_ERROR(mhdp->dev, "sink does not support DSC: %d\n", ret); >> + goto err; >> + } >> + >> + ret = 0; >> +err: >> + return ret; >> +} >> + >> +int cdns_mhdp_compute_dsc_params(struct cdns_mhdp_device *mhdp) >> +{ >> + struct drm_bridge *bridge = &mhdp->bridge; >> + struct drm_dsc_config *dsc_cfg = &mhdp->dsc_config; >> + struct drm_crtc_state *crtc_state = bridge->encoder->crtc->state; >> + u8 *dsc_dpcd = (u8 *)&mhdp->dsc_params.dsc_cap; >> + int ret; >> + >> + dsc_cfg->pic_width = crtc_state->adjusted_mode.crtc_hdisplay; >> + dsc_cfg->pic_height = crtc_state->adjusted_mode.crtc_vdisplay; >> + >> + dsc_cfg->slice_width = dsc_cfg->pic_width; >> + dsc_cfg->slice_height = DIV_ROUND_UP(dsc_cfg->pic_height, >> + mhdp->dsc_params.slice_count); >> + >> + dsc_cfg->dsc_version_major = (dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] & >> + DP_DSC_MAJOR_MASK) >> DP_DSC_MAJOR_SHIFT; >> + dsc_cfg->dsc_version_minor = >> + min(DSC_SUPPORTED_VERSION_MIN, >> + (dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] & >> + DP_DSC_MINOR_MASK) >> DP_DSC_MINOR_SHIFT); >> + >> + dsc_cfg->convert_rgb = >> + dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT] & DP_DSC_RGB; >> + >> + dsc_cfg->vbr_enable = false; >> + >> + dsc_cfg->block_pred_enable = >> + dsc_dpcd[DP_DSC_BLK_PREDICTION_SUPPORT - DP_DSC_SUPPORT] & >> + DP_DSC_BLK_PREDICTION_IS_SUPPORTED; >> + >> + dsc_cfg->bits_per_pixel = mhdp->dsc_params.compressed_bpp << 4; >> + >> + dsc_cfg->bits_per_component = mhdp->display_fmt.bpc; >> + >> + if (mhdp->dsc_config.bits_per_component == 8) >> + dsc_cfg->line_buf_depth = min(9, drm_dp_dsc_sink_line_buf_depth(dsc_dpcd)); >> + else if (mhdp->dsc_config.bits_per_component == 10) >> + dsc_cfg->line_buf_depth = min(11, drm_dp_dsc_sink_line_buf_depth(dsc_dpcd)); >> + >> + drm_dsc_set_const_params(dsc_cfg); >> + drm_dsc_set_rc_buf_thresh(dsc_cfg); >> + >> + ret = drm_dsc_setup_rc_params(dsc_cfg, DRM_DSC_1_1_PRE_SCR); >> + if (ret) { >> + dev_err(mhdp->dev, "could not find DSC RC parameters"); >> + return ret; >> + } >> + >> + dsc_cfg->initial_scale_value = drm_dsc_initial_scale_value(dsc_cfg); >> + dsc_cfg->slice_count = mhdp->dsc_params.slice_count; >> + >> + return drm_dsc_compute_rc_parameters(dsc_cfg); >> +} > Please consider extracting code common with Intel driver. will check and make changes. > >> + >> +static void cdns_mhdp_write_data_packet(struct cdns_mhdp_device *mhdp, u32 *buf, >> + int length, int stream_id) >> +{ >> + int i; >> + u32 reg_val; >> + >> + for (i = 0; i < length; i++) { >> + reg_val = buf[i]; >> + writel(reg_val, mhdp->regs + CDNS_SOURCE_PIF_DATA_WR(stream_id)); >> + } >> +} >> + >> +static void cdns_mhdp_write_pps_header(struct cdns_mhdp_device *mhdp, u32 *buf, >> + int stream_id) >> +{ >> + writel(SOURCE_PIF_PPS_PPS, mhdp->regs + CDNS_SOURCE_PIF_PPS(stream_id)); >> + writel(*buf, mhdp->regs + CDNS_SOURCE_PIF_PPS_HEADER(stream_id)); >> +} >> + >> +static int cdns_mhdp_write_pps_infoframe(struct cdns_mhdp_device *mhdp, int stream_id, >> + struct drm_dsc_pps_infoframe *pps_infoframe) >> +{ >> + u32 reg_val; >> + u32 entry_id = 0; >> + >> + writel(1, mhdp->regs + CDNS_SOURCE_PIF_FIFO1_FLUSH(stream_id)); >> + >> + cdns_mhdp_write_pps_header(mhdp, (u32 *)&pps_infoframe->pps_header, 0); >> + cdns_mhdp_write_data_packet(mhdp, (u32 *)&pps_infoframe->pps_payload, >> + DP_DSC_PPS_SIZE / 4, 0); > sizeof(foo) / 4 Noted. > >> + >> + /* Entry ID */ >> + writel(entry_id, mhdp->regs + CDNS_SOURCE_PIF_WR_ADDR(stream_id)); >> + >> + writel(SOURCE_PIF_WR_REQ_HOST_WR, mhdp->regs + CDNS_SOURCE_PIF_WR_REQ(stream_id)); >> + >> + reg_val = SOURCE_PIF_PKT_ALLOC_REG_ACTIVE_IDLE_TYPE | >> + SOURCE_PIF_PKT_ALLOC_REG_TYPE_VALID | >> + ((DP_SDP_PPS << SOURCE_PIF_PKT_ALLOC_REG_PACKET_TYPE_SHIFT) & >> + SOURCE_PIF_PKT_ALLOC_REG_PACKET_TYPE) | >> + (entry_id & SOURCE_PIF_PKT_ALLOC_REG_PKT_ALLOC_ADDR); >> + >> + writel(reg_val, mhdp->regs + CDNS_SOURCE_PIF_PKT_ALLOC_REG(stream_id)); >> + >> + writel >> + (SOURCE_PIF_PKT_ALLOC_WR_EN_EN, mhdp->regs + CDNS_SOURCE_PIF_PKT_ALLOC_WR_EN(stream_id)); > Ugh. Newline after comma, please. will make changes. >> + >> + return 0; >> +} >> + >> +int cdns_mhdp_dsc_send_pps_sdp(struct cdns_mhdp_device *mhdp, int stream_id) >> +{ >> + struct drm_dsc_config *dsc_cfg = &mhdp->dsc_config; >> + struct drm_dsc_pps_infoframe dp_dsc_pps_sdp; >> + >> + drm_dsc_dp_pps_header_init(&dp_dsc_pps_sdp.pps_header); >> + >> + drm_dsc_pps_payload_pack(&dp_dsc_pps_sdp.pps_payload, dsc_cfg); >> + >> + return cdns_mhdp_write_pps_infoframe(mhdp, stream_id, &dp_dsc_pps_sdp); >> +} >> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-dsc.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-dsc.h >> new file mode 100644 >> index 000000000000..c44d7e3d0002 >> --- /dev/null >> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-dsc.h >> @@ -0,0 +1,285 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +/* >> + * Copyright (C) Cadence Design Systems, Inc. >> + * >> + * Author: Swapnil Jakhade >> + */ >> + >> +#ifndef CDNS_MHDP_DSC_H_ >> +#define CDNS_MHDP_DSC_H_ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include > Please don't include unnecessary headers through the header file. Use > forward declarations for structs where possible. Noted, will make appropriate changes. > >> + >> +#define DSC_SUPPORTED_VERSION_MIN 1 >> + >> +#define DSC_OUTPUT_BUFFER_MAX_ADDRESS 3667U >> +#define DP_DSC_PPS_SIZE 128 >> + >> +#define CDNS_DP_COM_MAIN_CONF 0 >> +#define CDNS_DP_COM_MAIN_CONF_SPLIT_PANEL BIT(0) >> +#define CDNS_DP_COM_MAIN_CONF_MUX_MODE BIT(1) >> +#define CDNS_DP_COM_MAIN_CONF_MUX_SEL_OUT BIT(2) >> +#define CDNS_DP_COM_MAIN_CONF_DE_RASTER_EN BIT(3) >> +#define CDNS_DP_COM_MAIN_CONF_INPUT_MODE BIT(4) >> +#define CDNS_DP_COM_MAIN_CONF_MUX_EOC_EN BIT(5) >> +#define CDNS_DP_COM_MAIN_CONF_AUTO_DB_UPDATE BIT(6) >> + >> +#define CDNS_DP_ENC_MAIN_CONF(d) (0x120 + ((d) * 0x100)) >> +#define CDNS_DP_ENC_MAIN_CONF_INPUT_BPC GENMASK(1, 0) >> +#define CDNS_DP_ENC_MAIN_CONF_CONVERT_RGB BIT(2) >> +#define CDNS_DP_ENC_MAIN_CONF_ENABLE_422 BIT(3) >> +#define CDNS_DP_ENC_MAIN_CONF_LINEBUF_DEPTH GENMASK(7, 4) >> +#define CDNS_DP_ENC_MAIN_CONF_LINEBUF_DEPTH_SHIFT 4 >> +#define CDNS_DP_ENC_MAIN_CONF_BITS_PER_PIXEL GENMASK(17, 8) >> +#define CDNS_DP_ENC_MAIN_CONF_BITS_PER_PIXEL_SHIFT 8 >> +#define CDNS_DP_ENC_MAIN_CONF_BLOCK_PRED_EN BIT(18) >> +#define CDNS_DP_ENC_MAIN_CONF_VIDEO_MODE BIT(19) >> +#define CDNS_DP_ENC_MAIN_CONF_ICH_RST_EOL BIT(20) >> +#define CDNS_DP_ENC_MAIN_CONF_INITIAL_LINES GENMASK(31, 24) >> +#define CDNS_DP_ENC_MAIN_CONF_INITIAL_LINES_SHIFT 24 >> + >> +#define CDNS_DP_ENC_PICTURE_SIZE(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x4) >> +#define CDNS_DP_ENC_PICTURE_SIZE_HEIGHT GENMASK(31, 16) >> +#define CDNS_DP_ENC_PICTURE_SIZE_HEIGHT_SHIFT 16 >> +#define CDNS_DP_ENC_PICTURE_SIZE_WIDTH GENMASK(15, 0) >> + >> +#define CDNS_DP_ENC_SLICE_SIZE(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x8) >> +#define CDNS_DP_ENC_SLICE_SIZE_HEIGHT GENMASK(31, 16) >> +#define CDNS_DP_ENC_SLICE_SIZE_HEIGHT_SHIFT 16 >> +#define CDNS_DP_ENC_SLICE_SIZE_WIDTH GENMASK(15, 0) >> + >> +#define CDNS_DP_ENC_MISC_SIZE(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0xc) >> +#define CDNS_DP_ENC_MISC_SIZE_CHUNK_SIZE GENMASK(31, 16) >> +#define CDNS_DP_ENC_MISC_SIZE_CHUNK_SIZE_SHIFT 16 >> +#define CDNS_DP_ENC_MISC_SIZE_OB_MAX_ADDR GENMASK(15, 2) >> +#define CDNS_DP_ENC_MISC_SIZE_OB_MAX_ADDR_SHIFT 2 >> +#define CDNS_DP_ENC_MISC_SIZE_LAST_GRP_SIZE GENMASK(1, 0) >> + >> +#define CDNS_DP_ENC_HRD_DELAYS(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x10) >> +#define CDNS_DP_ENC_HRD_DELAYS_INIT_DEC_DELAY GENMASK(31, 16) >> +#define CDNS_DP_ENC_HRD_DELAYS_INIT_DEC_DELAY_SHIFT 16 >> +#define CDNS_DP_ENC_HRD_DELAYS_INIT_XMIT_DELAY GENMASK(9, 0) >> + >> +#define CDNS_DP_ENC_RC_SCALE(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x14) >> +#define CDNS_DP_ENC_RC_SCALE_INIT_SCALE_VALUE GENMASK(5, 0) >> + >> +#define CDNS_DP_ENC_RC_SCALE_INC_DEC(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x18) >> +#define CDNS_DP_ENC_RC_SCALE_DEC_INTERVAL GENMASK(27, 16) >> +#define CDNS_DP_ENC_RC_SCALE_DEC_INTERVAL_SHIFT 16 >> +#define CDNS_DP_ENC_RC_SCALE_INC_INTERVAL GENMASK(15, 0) >> + >> +#define CDNS_DP_ENC_RC_OFFSETS_1(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x1c) >> +#define CDNS_DP_ENC_RC_OFFSETS_1_FL_BPG_OFFSET GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_RC_OFFSETS_2(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x20) >> +#define CDNS_DP_ENC_RC_OFFSETS_2_SL_BPG_OFFSET GENMASK(31, 16) >> +#define CDNS_DP_ENC_RC_OFFSETS_2_SL_BPG_OFFSET_SHIFT 16 >> +#define CDNS_DP_ENC_RC_OFFSETS_2_NFL_BPG_OFFSET GENMASK(15, 0) >> + >> +#define CDNS_DP_ENC_RC_OFFSETS_3(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x24) >> +#define CDNS_DP_ENC_RC_OFFSETS_3_FINAL_OFFSET GENMASK(31, 16) >> +#define CDNS_DP_ENC_RC_OFFSETS_3_FINAL_OFFSET_SHIFT 16 >> +#define CDNS_DP_ENC_RC_OFFSETS_3_INIT_OFFSET GENMASK(15, 0) >> + >> +#define CDNS_DP_ENC_FLATNESS_DETECTION(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x28) >> +#define CDNS_DP_ENC_FLATNESS_DETECTION_THRESH GENMASK(17, 10) >> +#define CDNS_DP_ENC_FLATNESS_DETECTION_THRESH_SHIFT 10 >> +#define CDNS_DP_ENC_FLATNESS_DETECTION_MAX_QP GENMASK(9, 5) >> +#define CDNS_DP_ENC_FLATNESS_DETECTION_MAX_QP_SHIFT 5 >> +#define CDNS_DP_ENC_FLATNESS_DETECTION_MIN_QP GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_RC_MODEL_SIZE(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x2c) >> +#define CDNS_DP_ENC_RC_MODEL_SIZE_RC_MODEL_SIZE GENMASK(15, 0) >> + >> +#define CDNS_DP_ENC_RC_CONFIG(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x30) >> +#define CDNS_DP_ENC_RC_CONFIG_TGT_OFFSET_LO GENMASK(27, 24) >> +#define CDNS_DP_ENC_RC_CONFIG_TGT_OFFSET_LO_SHIFT 24 >> +#define CDNS_DP_ENC_RC_CONFIG_TGT_OFFSET_HI GENMASK(23, 20) >> +#define CDNS_DP_ENC_RC_CONFIG_TGT_OFFSET_HI_SHIFT 20 >> +#define CDNS_DP_ENC_RC_CONFIG_QUANT_INC_LIM_1 GENMASK(17, 13) >> +#define CDNS_DP_ENC_RC_CONFIG_QUANT_INC_LIM_1_SHIFT 13 >> +#define CDNS_DP_ENC_RC_CONFIG_QUANT_INC_LIM_0 GENMASK(12, 8) >> +#define CDNS_DP_ENC_RC_CONFIG_QUANT_INC_LIM_0_SHIFT 8 >> +#define CDNS_DP_ENC_RC_CONFIG_EDGE_FACTOR GENMASK(3, 0) >> + >> +#define CDNS_DP_ENC_RC_BUF_THRESH_0(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x34) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_0_THRESH_3 GENMASK(31, 24) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_0_THRESH_2 GENMASK(23, 16) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_0_THRESH_1 GENMASK(15, 8) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_0_THRESH_0 GENMASK(7, 0) >> + >> +#define CDNS_DP_ENC_RC_BUF_THRESH_1(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x38) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_1_THRESH_7 GENMASK(31, 24) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_1_THRESH_6 GENMASK(23, 16) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_1_THRESH_5 GENMASK(15, 8) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_1_THRESH_4 GENMASK(7, 0) >> + >> +#define CDNS_DP_ENC_RC_BUF_THRESH_2(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x3c) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_2_THRESH_11 GENMASK(31, 24) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_2_THRESH_10 GENMASK(23, 16) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_2_THRESH_9 GENMASK(15, 8) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_2_THRESH_8 GENMASK(7, 0) >> + >> +#define CDNS_DP_ENC_RC_BUF_THRESH_3(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x40) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_3_THRESH_13 GENMASK(15, 8) >> +#define CDNS_DP_ENC_RC_BUF_THRESH_3_THRESH_12 GENMASK(7, 0) >> + >> +#define CDNS_DP_ENC_RC_BUF_THRESH_THRESH_3_SHIFT 24 >> +#define CDNS_DP_ENC_RC_BUF_THRESH_THRESH_2_SHIFT 16 >> +#define CDNS_DP_ENC_RC_BUF_THRESH_THRESH_1_SHIFT 8 >> + >> +#define CDNS_DP_ENC_RC_MIN_QP_0(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x44) >> +#define CDNS_DP_ENC_RC_MIN_QP_0_RANGE_4 GENMASK(24, 20) >> +#define CDNS_DP_ENC_RC_MIN_QP_0_RANGE_3 GENMASK(19, 15) >> +#define CDNS_DP_ENC_RC_MIN_QP_0_RANGE_2 GENMASK(14, 10) >> +#define CDNS_DP_ENC_RC_MIN_QP_0_RANGE_1 GENMASK(9, 5) >> +#define CDNS_DP_ENC_RC_MIN_QP_0_RANGE_0 GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_RC_MIN_QP_1(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x48) >> +#define CDNS_DP_ENC_RC_MIN_QP_1_RANGE_9 GENMASK(24, 20) >> +#define CDNS_DP_ENC_RC_MIN_QP_1_RANGE_8 GENMASK(19, 15) >> +#define CDNS_DP_ENC_RC_MIN_QP_1_RANGE_7 GENMASK(14, 10) >> +#define CDNS_DP_ENC_RC_MIN_QP_1_RANGE_6 GENMASK(9, 5) >> +#define CDNS_DP_ENC_RC_MIN_QP_1_RANGE_5 GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_RC_MIN_QP_2(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x4c) >> +#define CDNS_DP_ENC_RC_MIN_QP_2_RANGE_14 GENMASK(24, 20) >> +#define CDNS_DP_ENC_RC_MIN_QP_2_RANGE_13 GENMASK(19, 15) >> +#define CDNS_DP_ENC_RC_MIN_QP_2_RANGE_12 GENMASK(14, 10) >> +#define CDNS_DP_ENC_RC_MIN_QP_2_RANGE_11 GENMASK(9, 5) >> +#define CDNS_DP_ENC_RC_MIN_QP_2_RANGE_10 GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_RC_MAX_QP_0(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x50) >> +#define CDNS_DP_ENC_RC_MAX_QP_0_RANGE_4 GENMASK(24, 20) >> +#define CDNS_DP_ENC_RC_MAX_QP_0_RANGE_3 GENMASK(19, 15) >> +#define CDNS_DP_ENC_RC_MAX_QP_0_RANGE_2 GENMASK(14, 10) >> +#define CDNS_DP_ENC_RC_MAX_QP_0_RANGE_1 GENMASK(9, 5) >> +#define CDNS_DP_ENC_RC_MAX_QP_0_RANGE_0 GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_RC_MAX_QP_1(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x54) >> +#define CDNS_DP_ENC_RC_MAX_QP_1_RANGE_9 GENMASK(24, 20) >> +#define CDNS_DP_ENC_RC_MAX_QP_1_RANGE_8 GENMASK(19, 15) >> +#define CDNS_DP_ENC_RC_MAX_QP_1_RANGE_7 GENMASK(14, 10) >> +#define CDNS_DP_ENC_RC_MAX_QP_1_RANGE_6 GENMASK(9, 5) >> +#define CDNS_DP_ENC_RC_MAX_QP_1_RANGE_5 GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_RC_MAX_QP_2(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x58) >> +#define CDNS_DP_ENC_RC_MAX_QP_2_RANGE_14 GENMASK(24, 20) >> +#define CDNS_DP_ENC_RC_MAX_QP_2_RANGE_13 GENMASK(19, 15) >> +#define CDNS_DP_ENC_RC_MAX_QP_2_RANGE_12 GENMASK(14, 10) >> +#define CDNS_DP_ENC_RC_MAX_QP_2_RANGE_11 GENMASK(9, 5) >> +#define CDNS_DP_ENC_RC_MAX_QP_2_RANGE_10 GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_RC_QP_RANGE_4_SHIFT 20 >> +#define CDNS_DP_ENC_RC_QP_RANGE_3_SHIFT 15 >> +#define CDNS_DP_ENC_RC_QP_RANGE_2_SHIFT 10 >> +#define CDNS_DP_ENC_RC_QP_RANGE_1_SHIFT 5 >> + >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x5c) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_4 GENMASK(24, 20) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_3 GENMASK(19, 15) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_2 GENMASK(14, 10) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_1 GENMASK(9, 5) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_0 GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_1(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x60) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_9 GENMASK(24, 20) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_8 GENMASK(19, 15) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_7 GENMASK(14, 10) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_6 GENMASK(9, 5) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_5 GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_2(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x64) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_14 GENMASK(24, 20) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_13 GENMASK(19, 15) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_12 GENMASK(14, 10) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_11 GENMASK(9, 5) >> +#define CDNS_DP_ENC_RC_RANGE_BPG_OFFSETS_0_10 GENMASK(4, 0) >> + >> +#define CDNS_DP_ENC_DPI_CTRL_OUT_DELAY(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0x68) >> +#define CDNS_DP_ENC_DPI_CTRL_OUT_DELAY_CYCLES GENMASK(15, 0) >> + >> +#define CDNS_DP_ENC_GENERAL_STATUS(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0xa0) >> +#define CDNS_DP_ENC_GENERAL_STATUS_OUT_BUFF_FULL_1 BIT(6) >> +#define CDNS_DP_ENC_GENERAL_STATUS_OUT_BUFF_FULL_0 BIT(5) >> +#define CDNS_DP_ENC_GENERAL_STATUS_OUT_BUFF_EMPTY_1 BIT(4) >> +#define CDNS_DP_ENC_GENERAL_STATUS_OUT_BUFF_EMPTY_0 BIT(3) >> +#define CDNS_DP_ENC_GENERAL_STATUS_FRAME_DONE BIT(2) >> +#define CDNS_DP_ENC_GENERAL_STATUS_FRAME_STARTED BIT(1) >> +#define CDNS_DP_ENC_GENERAL_STATUS_CE BIT(0) >> + >> +#define CDNS_DP_ENC_HSLICE_STATUS(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0xa4) >> +#define CDNS_DP_ENC_HSLICE_STATUS_ACTUAL_SLICE GENMASK(31, 16) >> +#define CDNS_DP_ENC_HSLICE_STATUS_ACTUAL_LINE GENMASK(15, 0) >> + >> +#define CDNS_DP_ENC_OUT_STATUS(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0xa8) >> +#define CDNS_DP_ENC_OUT_STATUS_ACTUAL_SLICE GENMASK(31, 16) >> +#define CDNS_DP_ENC_OUT_STATUS_ACTUAL_LINE GENMASK(15, 0) >> + >> +#define CDNS_DP_ENC_INT_STAT(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0xac) >> +#define CDNS_DP_ENC_INT_STAT_OUT_BUFF_FULL_1 BIT(10) >> +#define CDNS_DP_ENC_INT_STAT_OUT_BUFF_FULL_0 BIT(9) >> +#define CDNS_DP_ENC_INT_STAT_OUT_BUFF_EMPTY_1 BIT(8) >> +#define CDNS_DP_ENC_INT_STAT_OUT_BUFF_EMPTY_0 BIT(7) >> +#define CDNS_DP_ENC_INT_STAT_FRAME_DONE BIT(6) >> +#define CDNS_DP_ENC_INT_STAT_FRAME_STARTED BIT(5) >> +#define CDNS_DP_ENC_INT_STAT_CE BIT(4) >> +#define CDNS_DP_ENC_INT_STAT_RC_BUFF_OVER_1 BIT(3) >> +#define CDNS_DP_ENC_INT_STAT_RC_BUFF_OVER_0 BIT(2) >> +#define CDNS_DP_ENC_INT_STAT_OUT_BUFF_UND_1 BIT(1) >> +#define CDNS_DP_ENC_INT_STAT_OUT_BUFF_UND_0 BIT(0) >> + >> +#define CDNS_DP_ENC_INT_CLR(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0xb0) >> +#define CDNS_DP_ENC_INT_CLR_OUT_BUFF_FULL_1 BIT(10) >> +#define CDNS_DP_ENC_INT_CLR_OUT_BUFF_FULL_0 BIT(9) >> +#define CDNS_DP_ENC_INT_CLR_OUT_BUFF_EMPTY_1 BIT(8) >> +#define CDNS_DP_ENC_INT_CLR_OUT_BUFF_EMPTY_0 BIT(7) >> +#define CDNS_DP_ENC_INT_CLR_FRAME_DONE BIT(6) >> +#define CDNS_DP_ENC_INT_CLR_FRAME_STARTED BIT(5) >> +#define CDNS_DP_ENC_INT_CLR_CE BIT(4) >> +#define CDNS_DP_ENC_INT_CLR_RC_BUFF_OVER_1 BIT(3) >> +#define CDNS_DP_ENC_INT_CLR_RC_BUFF_OVER_0 BIT(2) >> +#define CDNS_DP_ENC_INT_CLR_OUT_BUFF_UND_1 BIT(1) >> +#define CDNS_DP_ENC_INT_CLR_OUT_BUFF_UND_0 BIT(0) >> + >> +#define CDNS_DP_ENC_INT_MASK(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0xb4) >> +#define CDNS_DP_ENC_INT_MASK_OUT_BUFF_FULL_1 BIT(10) >> +#define CDNS_DP_ENC_INT_MASK_OUT_BUFF_FULL_0 BIT(9) >> +#define CDNS_DP_ENC_INT_MASK_OUT_BUFF_EMPTY_1 BIT(8) >> +#define CDNS_DP_ENC_INT_MASK_OUT_BUFF_EMPTY_0 BIT(7) >> +#define CDNS_DP_ENC_INT_MASK_FRAME_DONE BIT(6) >> +#define CDNS_DP_ENC_INT_MASK_FRAME_STARTED BIT(5) >> +#define CDNS_DP_ENC_INT_MASK_CE BIT(4) >> +#define CDNS_DP_ENC_INT_MASK_RC_BUFF_OVER_1 BIT(3) >> +#define CDNS_DP_ENC_INT_MASK_RC_BUFF_OVER_0 BIT(2) >> +#define CDNS_DP_ENC_INT_MASK_OUT_BUFF_UND_1 BIT(1) >> +#define CDNS_DP_ENC_INT_MASK_OUT_BUFF_UND_0 BIT(0) >> + >> +#define CDNS_DP_ENC_INT_TEST(d) (CDNS_DP_ENC_MAIN_CONF(d) + 0xb8) >> +#define CDNS_DP_ENC_INT_TEST_OUT_BUFF_FULL_1 BIT(10) >> +#define CDNS_DP_ENC_INT_TEST_OUT_BUFF_FULL_0 BIT(9) >> +#define CDNS_DP_ENC_INT_TEST_OUT_BUFF_EMPTY_1 BIT(8) >> +#define CDNS_DP_ENC_INT_TEST_OUT_BUFF_EMPTY_0 BIT(7) >> +#define CDNS_DP_ENC_INT_TEST_FRAME_DONE BIT(6) >> +#define CDNS_DP_ENC_INT_TEST_FRAME_STARTED BIT(5) >> +#define CDNS_DP_ENC_INT_TEST_CE BIT(4) >> +#define CDNS_DP_ENC_INT_TEST_RC_BUFF_OVER_1 BIT(3) >> +#define CDNS_DP_ENC_INT_TEST_RC_BUFF_OVER_0 BIT(2) >> +#define CDNS_DP_ENC_INT_TEST_OUT_BUFF_UND_1 BIT(1) >> +#define CDNS_DP_ENC_INT_TEST_OUT_BUFF_UND_0 BIT(0) >> + >> +void cdns_mhdp_dsc_write_config(struct cdns_mhdp_device *mhdp); >> +void cdns_mhdp_dsc_write_enc_config(struct cdns_mhdp_device *mhdp, int stream_id, >> + const struct drm_display_mode *mode); >> +int cdns_mhdp_dsc_sink_support(struct cdns_mhdp_device *mhdp); >> +int cdns_mhdp_compute_dsc_params(struct cdns_mhdp_device *mhdp); >> +int cdns_mhdp_dsc_send_pps_sdp(struct cdns_mhdp_device *mhdp, int stream_id); >> + >> +#endif /* MHDP_DSC_H_ */ >> -- >> 2.34.1 Regards. Hari