From patchwork Thu Oct 7 07:08:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vinod Koul X-Patchwork-Id: 515439 Delivered-To: patch@linaro.org Received: by 2002:ac0:b5cc:0:0:0:0:0 with SMTP id x12csp1022299ime; Thu, 7 Oct 2021 00:09:19 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxNTQx6ntNBzkanLfwDbkvuR57+N8okGsCXo+usqDYeOSOREpjfwhulAjvTQ0KVOtEAyKlQ X-Received: by 2002:a17:907:7752:: with SMTP id kx18mr3708483ejc.276.1633590559700; Thu, 07 Oct 2021 00:09:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633590559; cv=none; d=google.com; s=arc-20160816; b=Y4dBU4rsxzEpdKC6rCWNcoqf2lwXTZ+W0JBeWmxUOVf5fAajdCV/eF9dEL51kiuHMS m5wRV+7wUO79HdH5CoCRDJeLd3QrLdesFcXQ/pRZcHqczU2iWSbSOjbjmGaQUQ9afFTl YptUi8Wi/r3/T8qgtbvi6cbB5WzVSb693aOiEDibuqsHm0AvKMCfX9HEb3w8hLSf6pYC JA7wXSHhUHeQjc9pNrXfMDsiLkD7vF+OSsAKA1/TL2KnHlXJTuTFM4QdKFGTmuCLasVB xVSI6NgYlBJEBzMJ17ACBU4iY4nJ3AcmU8x3/ctvzNcqs9dFV48JXNQR/YtHZhQfI/9c 2FoQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=V+ExL2Dq+g5+E4mFGLtFWDFJLFyZlh2hCl/ojwAwBEI=; b=JTMHR7EcTfRMW36q8cvp5itfbI4E517lULVTSTJR2kSzUmolhOvKAZb/yG0cSOQJme xQ8gasPzv9iV98oh4Q832NoXWxXvs4s5PsWRnqdnvpOOyy8CYHBm4TvF3kGbd0+xG9jM XSkcTvbmdMJO/uME0Nxma+3zvF3g2xor0xKAWNzrGJEgOsdAd6pf+D5dahzIMvSksypu TIORmS51YJVZYSKtFu+8md7e/0x8C4g2BvwAEKDdGuNmVC4O1wRmYC9XO1HD5ujelrj8 iwXCBREnB36XMcskBfqTdmvDiEnz8LlmIeGhIlnGqDkV8oOpTncly6meGe8FK7bA6XcO l+dg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="fMtQJ/ul"; spf=pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id mp33si42443895ejc.40.2021.10.07.00.09.19; Thu, 07 Oct 2021 00:09:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="fMtQJ/ul"; spf=pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240328AbhJGHLL (ORCPT + 17 others); Thu, 7 Oct 2021 03:11:11 -0400 Received: from mail.kernel.org ([198.145.29.99]:40274 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233691AbhJGHLL (ORCPT ); Thu, 7 Oct 2021 03:11:11 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7856560F48; Thu, 7 Oct 2021 07:09:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1633590557; bh=xS7+sa6ZJW9G5NUTaitZ/9/LN/RVQ/coK+YcqMcOlp0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fMtQJ/ulVAeU9Dyz4omFGXd6yMiOcYfyNEDAZC45PC0EE4IJUsOs8TWCvP6dANlER m4U5Z0mGjD+VoeeTp9FdNbRp6+dntsh4AKcY+ppHKxNnYuDIb+pjS8YS7XhdMPt5sD wOC/A+4bi4sBu822azyJCXP0cZnLUrHBVEvT4dGsvMut1K9QDSfyOSInhYfkHGOjhw K4FmSi8LIUt/CnDz9ATRIsBboS4Jfw66SZr0MDj+k46cEl7AaATcolh5kDG1RnS1GA UGgoKYTZpuFALllSu3BirdSG+ACk58/aB/POwbpw4rCVo1X+WMSVpb3BnZjLN1dkv4 MJlGiZbqnXh8g== From: Vinod Koul To: Rob Clark Cc: linux-arm-msm@vger.kernel.org, Bjorn Andersson , Vinod Koul , David Airlie , Daniel Vetter , Jonathan Marek , Dmitry Baryshkov , Abhinav Kumar , Jeffrey Hugo , Sumit Semwal , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [PATCH v2 01/11] drm/msm/dsi: add support for dsc data Date: Thu, 7 Oct 2021 12:38:50 +0530 Message-Id: <20211007070900.456044-2-vkoul@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211007070900.456044-1-vkoul@kernel.org> References: <20211007070900.456044-1-vkoul@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Display Stream Compression (DSC) parameters need to be calculated. Add helpers and struct msm_display_dsc_config in msm_drv for this msm_display_dsc_config uses drm_dsc_config for DSC parameters. Signed-off-by: Vinod Koul --- Changes since v1: - Drop unused fields from msm_display_dsc_config RFC: - Drop the DT parsing code - Port dsc param calculation from downstream drivers/gpu/drm/msm/dsi/dsi_host.c | 132 +++++++++++++++++++++++++++++ drivers/gpu/drm/msm/msm_drv.h | 18 ++++ 2 files changed, 150 insertions(+) -- 2.31.1 diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index e269df285136..ba24458c2e38 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -31,6 +31,8 @@ #define DSI_RESET_TOGGLE_DELAY_MS 20 +static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc); + static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) { u32 ver; @@ -156,6 +158,7 @@ struct msm_dsi_host { struct regmap *sfpb; struct drm_display_mode *mode; + struct msm_display_dsc_config *dsc; /* connected device info */ struct device_node *device_node; @@ -1748,6 +1751,135 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, return -EINVAL; } +static u32 dsi_dsc_rc_buf_thresh[DSC_NUM_BUF_RANGES - 1] = { + 0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, + 0x69, 0x70, 0x77, 0x79, 0x7b, 0x7d, 0x7e +}; + +/* only 8bpc, 8bpp added */ +static char min_qp[DSC_NUM_BUF_RANGES] = { + 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13 +}; + +static char max_qp[DSC_NUM_BUF_RANGES] = { + 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15 +}; + +static char bpg_offset[DSC_NUM_BUF_RANGES] = { + 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12 +}; + +static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc) +{ + int mux_words_size; + int groups_per_line, groups_total; + int min_rate_buffer_size; + int hrd_delay; + int pre_num_extra_mux_bits, num_extra_mux_bits; + int slice_bits; + int target_bpp_x16; + int data; + int final_value, final_scale; + int i; + + dsc->drm->rc_model_size = 8192; + dsc->drm->first_line_bpg_offset = 12; + dsc->drm->rc_edge_factor = 6; + dsc->drm->rc_tgt_offset_high = 3; + dsc->drm->rc_tgt_offset_low = 3; + dsc->drm->simple_422 = 0; + dsc->drm->convert_rgb = 1; + dsc->drm->vbr_enable = 0; + + /* handle only bpp = bpc = 8 */ + for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++) + dsc->drm->rc_buf_thresh[i] = dsi_dsc_rc_buf_thresh[i]; + + for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { + dsc->drm->rc_range_params[i].range_min_qp = min_qp[i]; + dsc->drm->rc_range_params[i].range_max_qp = max_qp[i]; + dsc->drm->rc_range_params[i].range_bpg_offset = bpg_offset[i]; + } + + dsc->drm->initial_offset = 6144; /* Not bpp 12 */ + if (dsc->drm->bits_per_pixel != 8) + dsc->drm->initial_offset = 2048; /* bpp = 12 */ + + mux_words_size = 48; /* bpc == 8/10 */ + if (dsc->drm->bits_per_component == 12) + mux_words_size = 64; + + dsc->drm->initial_xmit_delay = 512; + dsc->drm->initial_scale_value = 32; + dsc->drm->first_line_bpg_offset = 12; + dsc->drm->line_buf_depth = dsc->drm->bits_per_component + 1; + + /* bpc 8 */ + dsc->drm->flatness_min_qp = 3; + dsc->drm->flatness_max_qp = 12; + dsc->det_thresh_flatness = 7 + 2 * (dsc->drm->bits_per_component - 8); + dsc->drm->rc_quant_incr_limit0 = 11; + dsc->drm->rc_quant_incr_limit1 = 11; + dsc->drm->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC; + + /* FIXME: need to call drm_dsc_compute_rc_parameters() so that rest of + * params are calculated + */ + dsc->slice_last_group_size = 3 - (dsc->drm->slice_width % 3); + groups_per_line = DIV_ROUND_UP(dsc->drm->slice_width, 3); + dsc->drm->slice_chunk_size = dsc->drm->slice_width * dsc->drm->bits_per_pixel / 8; + if ((dsc->drm->slice_width * dsc->drm->bits_per_pixel) % 8) + dsc->drm->slice_chunk_size++; + + /* rbs-min */ + min_rate_buffer_size = dsc->drm->rc_model_size - dsc->drm->initial_offset + + dsc->drm->initial_xmit_delay * dsc->drm->bits_per_pixel + + groups_per_line * dsc->drm->first_line_bpg_offset; + + hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, dsc->drm->bits_per_pixel); + + dsc->drm->initial_dec_delay = hrd_delay - dsc->drm->initial_xmit_delay; + + dsc->drm->initial_scale_value = 8 * dsc->drm->rc_model_size / + (dsc->drm->rc_model_size - dsc->drm->initial_offset); + + slice_bits = 8 * dsc->drm->slice_chunk_size * dsc->drm->slice_height; + + groups_total = groups_per_line * dsc->drm->slice_height; + + data = dsc->drm->first_line_bpg_offset * 2048; + + dsc->drm->nfl_bpg_offset = DIV_ROUND_UP(data, (dsc->drm->slice_height - 1)); + + pre_num_extra_mux_bits = 3 * (mux_words_size + (4 * dsc->drm->bits_per_component + 4) - 2); + + num_extra_mux_bits = pre_num_extra_mux_bits - (mux_words_size - + ((slice_bits - pre_num_extra_mux_bits) % mux_words_size)); + + data = 2048 * (dsc->drm->rc_model_size - dsc->drm->initial_offset + num_extra_mux_bits); + dsc->drm->slice_bpg_offset = DIV_ROUND_UP(data, groups_total); + + /* bpp * 16 + 0.5 */ + data = dsc->drm->bits_per_pixel * 16; + data *= 2; + data++; + data /= 2; + target_bpp_x16 = data; + + data = (dsc->drm->initial_xmit_delay * target_bpp_x16) / 16; + final_value = dsc->drm->rc_model_size - data + num_extra_mux_bits; + dsc->drm->final_offset = final_value; + + final_scale = 8 * dsc->drm->rc_model_size / (dsc->drm->rc_model_size - final_value); + + data = (final_scale - 9) * (dsc->drm->nfl_bpg_offset + dsc->drm->slice_bpg_offset); + dsc->drm->scale_increment_interval = (2048 * dsc->drm->final_offset) / data; + + dsc->drm->scale_decrement_interval = groups_per_line / (dsc->drm->initial_scale_value - 8); + + return 0; +} + static int dsi_host_parse_dt(struct msm_dsi_host *msm_host) { struct device *dev = &msm_host->pdev->dev; diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 8b005d1ac899..367eb1092374 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -135,6 +136,20 @@ struct msm_drm_thread { struct kthread_worker *worker; }; +/* DSC config */ +struct msm_display_dsc_config { + struct drm_dsc_config *drm; + + u32 initial_lines; + u32 pkt_per_line; + u32 bytes_in_slice; + u32 bytes_per_pkt; + u32 eol_byte_num; + u32 pclk_per_line; + u32 slice_last_group_size; + u32 det_thresh_flatness; +}; + struct msm_drm_private { struct drm_device *dev; @@ -229,6 +244,9 @@ struct msm_drm_private { /* Properties */ struct drm_property *plane_property[PLANE_PROP_MAX_NUM]; + /* DSC configuration */ + struct msm_display_dsc_config *dsc; + /* VRAM carveout, used when no IOMMU: */ struct { unsigned long size; From patchwork Thu Oct 7 07:08:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vinod Koul X-Patchwork-Id: 515449 Delivered-To: patch@linaro.org Received: by 2002:adf:fbc8:0:0:0:0:0 with SMTP id d8csp1481059wrs; Thu, 7 Oct 2021 00:12:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxk8Q6uNUTG8zZEWoXYZz0yzHViqWg0GRrreMx9IYeAtd1GGWTeK6Nbx04ehXJSsidny7ql X-Received: by 2002:a17:906:3402:: with SMTP id c2mr3591293ejb.271.1633590615440; Thu, 07 Oct 2021 00:10:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633590615; cv=none; d=google.com; s=arc-20160816; b=FB8+tdL/qU+1InEhjZhaPh5hOAeI9d3FZKly/eKPhurOkGRvtBs5XTKMeQP07jPfvG 1sBgjasMqUosmK6pErj1R2ZJvicfoyulF7WSa/iPaygK9wMzSDQH1H+5iOklz1JJQ+49 HjM/F9k1xZDYuDzIdR02zkiSxXNSkNF81zRbQ+2Wi4pXlZm+w74QQcjLzcoMWajN0sO1 sy9VnDy3zWl4kkP1PT50K3qWuZ7tp12GN1cdpZOPV/dEDwVIc+IA6BtHUvd7tBQlFoz9 gFh0O0h2r5yOL++thROPaXx8mVG6+JDJgaGHOTg+HkzswKssEs1PCKgnTUxmDBX52KKg 1yug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=UDL8jwcOo/Lsoy03ruiQnTtCcD3g+LLqtd82T9hIIVM=; b=sG4s/+bRz6mYtfXJuK5JftGqNLKrdv4vSJ3jqnXl4/8jji+HiJJqT6cf/sFOfNar7L d++81vX/EZERWnjVQptQN/T9DI45Th/wzNqW5KyC92vz0PzWUiVxlLuUf5mGKmWglbIu Um/tbQtwbu02/fZxvKY/7Z1qB9GiicTo0Hb6VLslfyfZF1vHUNOLZvFMEhmYzi7svkKH iy2CBXITRGPmgQfn62i7JuCGVCwGVEELd4ITDVOqZqtb7/Oq9L/KCC1OBqXbaa8jqm7W tcyRDyWei4ht2EqS04Yar33wakXVsVeYGla3jEio19dqmuU0+lNanLWYULELvLR5gAHc jmHA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=m+ob9yqt; spf=pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 8si26761068ejd.70.2021.10.07.00.10.13; Thu, 07 Oct 2021 00:10:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=m+ob9yqt; spf=pass (google.com: domain of linux-arm-msm-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240407AbhJGHME (ORCPT + 17 others); Thu, 7 Oct 2021 03:12:04 -0400 Received: from mail.kernel.org ([198.145.29.99]:41354 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240434AbhJGHL4 (ORCPT ); Thu, 7 Oct 2021 03:11:56 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 117B660F48; Thu, 7 Oct 2021 07:09:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1633590603; bh=6JJpkxAXI8XphB+qAfR4aInDl3Smf4m3ajxYJh+7m7o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=m+ob9yqtFaDDNH8mfLnLPvDMWnAp8x5xWOjiINnpeoigdheXHhhtQjQ1abRmnEWdG HA7O9quqy9wZz9Wi3ZZp/r+bSUTNw7Gj8QeDnecB4Lsh9NfmZfBqDZHjlUUXobKwRh bl44JUUbO92vMpgyv1ZfYk2ud9abtzA5SZgiDykAX146AGTL2lTT+ixkUKFNZt5ZXM B//TogtH9EBnNtkvDjUVmizGs44m9mQxObtZO7XcJ7Ncbatn44+tnhD0Sax8rcBCRG dpXn9iGMkJMthd1Z07CBBtMlbgufqzMaHtA88EbM8x0PVVuKFL6j0/6RV7rtrSysWP /KQ1ej60YeEvg== From: Vinod Koul To: Rob Clark Cc: linux-arm-msm@vger.kernel.org, Bjorn Andersson , Vinod Koul , David Airlie , Daniel Vetter , Jonathan Marek , Dmitry Baryshkov , Abhinav Kumar , Jeffrey Hugo , Sumit Semwal , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [PATCH v2 10/11] drm/msm/dsi: Add support for DSC configuration Date: Thu, 7 Oct 2021 12:38:59 +0530 Message-Id: <20211007070900.456044-11-vkoul@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211007070900.456044-1-vkoul@kernel.org> References: <20211007070900.456044-1-vkoul@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org When DSC is enabled, we need to configure DSI registers accordingly and configure the respective stream compression registers. Add support to calculate the register setting based on DSC params and timing information and configure these registers. Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/dsi/dsi.xml.h | 10 +++ drivers/gpu/drm/msm/dsi/dsi_host.c | 123 ++++++++++++++++++++++++++++- 2 files changed, 132 insertions(+), 1 deletion(-) -- 2.31.1 diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h index 49b551ad1bff..c1c85df58c4b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h @@ -706,4 +706,14 @@ static inline uint32_t DSI_VERSION_MAJOR(uint32_t val) #define REG_DSI_CPHY_MODE_CTRL 0x000002d4 +#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL 0x0000029c + +#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL2 0x000002a0 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL 0x000002a4 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2 0x000002a8 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL3 0x000002ac + #endif /* DSI_XML */ diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index ba24458c2e38..86e36a3e97b6 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -946,6 +946,26 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable, dsi_write(msm_host, REG_DSI_CPHY_MODE_CTRL, BIT(0)); } +static int dsi_dsc_update_pic_dim(struct msm_display_dsc_config *dsc, + int pic_width, int pic_height) +{ + if (!dsc || !pic_width || !pic_height) { + pr_err("DSI: invalid input: pic_width: %d pic_height: %d\n", pic_width, pic_height); + return -EINVAL; + } + + if ((pic_width % dsc->drm->slice_width) || (pic_height % dsc->drm->slice_height)) { + pr_err("DSI: pic_dim %dx%d has to be multiple of slice %dx%d\n", + pic_width, pic_height, dsc->drm->slice_width, dsc->drm->slice_height); + return -EINVAL; + } + + dsc->drm->pic_width = pic_width; + dsc->drm->pic_height = pic_height; + + return 0; +} + static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { struct drm_display_mode *mode = msm_host->mode; @@ -978,7 +998,72 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) hdisplay /= 2; } + if (msm_host->dsc) { + struct msm_display_dsc_config *dsc = msm_host->dsc; + + /* update dsc params with timing params */ + dsi_dsc_update_pic_dim(dsc, mode->hdisplay, mode->vdisplay); + DBG("Mode Width- %d x Height %d\n", dsc->drm->pic_width, dsc->drm->pic_height); + + /* we do the calculations for dsc parameters here so that + * panel can use these parameters + */ + dsi_populate_dsc_params(dsc); + + /* Divide the display by 3 but keep back/font porch and + * pulse width same + */ + h_total -= hdisplay; + hdisplay /= 3; + h_total += hdisplay; + ha_end = ha_start + hdisplay; + } + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { + if (msm_host->dsc) { + struct msm_display_dsc_config *dsc = msm_host->dsc; + u32 reg, intf_width, slice_per_intf; + u32 total_bytes_per_intf; + + /* first calculate dsc parameters and then program + * compress mode registers + */ + intf_width = hdisplay; + slice_per_intf = DIV_ROUND_UP(intf_width, dsc->drm->slice_width); + + /* If slice_count > slice_per_intf, then use 1 + * This can happen during partial update + */ + dsc->drm->slice_count = 1; + + dsc->bytes_in_slice = DIV_ROUND_UP(dsc->drm->slice_width * 8, 8); + total_bytes_per_intf = dsc->bytes_in_slice * slice_per_intf; + + dsc->eol_byte_num = total_bytes_per_intf % 3; + dsc->pclk_per_line = DIV_ROUND_UP(total_bytes_per_intf, 3); + dsc->bytes_per_pkt = dsc->bytes_in_slice * dsc->drm->slice_count; + dsc->pkt_per_line = slice_per_intf / dsc->drm->slice_count; + + reg = dsc->bytes_per_pkt << 16; + reg |= (0x0b << 8); /* dtype of compressed image */ + + /* pkt_per_line: + * 0 == 1 pkt + * 1 == 2 pkt + * 2 == 4 pkt + * 3 pkt is not supported + * above translates to ffs() - 1 + */ + reg |= (ffs(dsc->pkt_per_line) - 1) << 6; + + dsc->eol_byte_num = total_bytes_per_intf % 3; + reg |= dsc->eol_byte_num << 4; + reg |= 1; + + dsi_write(msm_host, + REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg); + } + dsi_write(msm_host, REG_DSI_ACTIVE_H, DSI_ACTIVE_H_START(ha_start) | DSI_ACTIVE_H_END(ha_end)); @@ -997,8 +1082,40 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) DSI_ACTIVE_VSYNC_VPOS_START(vs_start) | DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); } else { /* command mode */ + if (msm_host->dsc) { + struct msm_display_dsc_config *dsc = msm_host->dsc; + u32 reg, reg_ctrl, reg_ctrl2; + u32 slice_per_intf, bytes_in_slice, total_bytes_per_intf; + + reg_ctrl = dsi_read(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL); + reg_ctrl2 = dsi_read(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2); + + slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->drm->slice_width); + bytes_in_slice = DIV_ROUND_UP(dsc->drm->slice_width * + dsc->drm->bits_per_pixel, 8); + dsc->drm->slice_chunk_size = bytes_in_slice; + total_bytes_per_intf = dsc->bytes_in_slice * slice_per_intf; + dsc->pkt_per_line = slice_per_intf / dsc->drm->slice_count; + + reg = 0x39 << 8; + reg |= ffs(dsc->pkt_per_line) << 6; + + dsc->eol_byte_num = total_bytes_per_intf % 3; + reg |= dsc->eol_byte_num << 4; + reg |= 1; + + reg_ctrl |= reg; + reg_ctrl2 |= bytes_in_slice; + + dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, reg); + dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, reg_ctrl2); + } + /* image data and 1 byte write_memory_start cmd */ - wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; + if (!msm_host->dsc) + wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; + else + wc = mode->hdisplay / 2 + 1; dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL, DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) | @@ -2074,6 +2191,7 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, struct msm_dsi_host *msm_host = to_msm_dsi_host(host); const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; struct platform_device *pdev = msm_host->pdev; + struct msm_drm_private *priv; int ret; msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); @@ -2093,6 +2211,9 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, } msm_host->dev = dev; + priv = dev->dev_private; + priv->dsc = msm_host->dsc; + ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K); if (ret) { pr_err("%s: alloc tx gem obj failed, %d\n", __func__, ret);