Re: [Freedreno] [PATCH 08/11] drm/msm/disp/dpu1: Add support for DSC in encoder

2021-10-06 Thread Vinod Koul
On 02-08-21, 17:57, abhin...@codeaurora.org wrote:
> On 2021-07-14 23:52, Vinod Koul wrote:
> > When DSC is enabled in DT, we need to configure the encoder for DSC
> > configuration, calculate DSC parameters for the given timing.
> > 
> > This patch adds that support by adding dpu_encoder_prep_dsc() which is
> > invoked when DSC is enabled in DT
> correct me if wrong but this commit text is not valid anymore in my opinion.
> are there any params you are getting from DT now? I thought its all coming
> from the panel
> driver directly.

Yes thanks for spotting this, updated!

> > 
> > Signed-off-by: Vinod Koul 
> agree with dmitry's comment's
> https://patchwork.freedesktop.org/patch/444078/?series=90413=2
> 
> instead of dsc being part of priv->dsc it should be per encoder.
> 
> On top of his comment, I also think that like on the newer chipsets, moving
> the dsc related
> encoder configuration to a dpu_encoder_dce.c will help for future expansion
> of other topologies
> and also for other compression algorithms.

As replied to Dimitry, the DP and other topology support needs to be
comprehended so this should be done when we know how DP, other
compression algorithms and other topologies would be modeled here :)

-- 
~Vinod


Re: [Freedreno] [PATCH 08/11] drm/msm/disp/dpu1: Add support for DSC in encoder

2021-08-02 Thread abhinavk

On 2021-07-14 23:52, Vinod Koul wrote:

When DSC is enabled in DT, we need to configure the encoder for DSC
configuration, calculate DSC parameters for the given timing.

This patch adds that support by adding dpu_encoder_prep_dsc() which is
invoked when DSC is enabled in DT
correct me if wrong but this commit text is not valid anymore in my 
opinion.
are there any params you are getting from DT now? I thought its all 
coming from the panel

driver directly.


Signed-off-by: Vinod Koul 
agree with dmitry's comment's 
https://patchwork.freedesktop.org/patch/444078/?series=90413=2


instead of dsc being part of priv->dsc it should be per encoder.

On top of his comment, I also think that like on the newer chipsets, 
moving the dsc related
encoder configuration to a dpu_encoder_dce.c will help for future 
expansion of other topologies

and also for other compression algorithms.


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 142 +++-
 1 file changed, 141 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 8d942052db8a..41140b781e66 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -21,12 +21,17 @@
 #include "dpu_hw_intf.h"
 #include "dpu_hw_ctl.h"
 #include "dpu_hw_dspp.h"
+#include "dpu_hw_dsc.h"
 #include "dpu_formats.h"
 #include "dpu_encoder_phys.h"
 #include "dpu_crtc.h"
 #include "dpu_trace.h"
 #include "dpu_core_irq.h"

+#define DSC_MODE_SPLIT_PANEL   BIT(0)
+#define DSC_MODE_MULTIPLEX BIT(1)
+#define DSC_MODE_VIDEO BIT(2)
+
 #define DPU_DEBUG_ENC(e, fmt, ...) DPU_DEBUG("enc%d " fmt,\
(e) ? (e)->base.base.id : -1, ##__VA_ARGS__)

@@ -135,6 +140,7 @@ enum dpu_enc_rc_states {
  * @cur_slave: As above but for the slave encoder.
  * @hw_pp: Handle to the pingpong blocks used for the display. No.
  * pingpong blocks can be different than num_phys_encs.
+ * @hw_dsc Handle to the DSC blocks used for the display.
  * @intfs_swapped:	Whether or not the phys_enc interfaces have been 
swapped

  * for partial update right-only cases, such as pingpong
  * split where virtual pingpong does not generate IRQs
@@ -180,6 +186,7 @@ struct dpu_encoder_virt {
struct dpu_encoder_phys *cur_master;
struct dpu_encoder_phys *cur_slave;
struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
+   struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];

bool intfs_swapped;

@@ -1008,7 +1015,8 @@ static void dpu_encoder_virt_mode_set(struct
drm_encoder *drm_enc,
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
-   int num_lm, num_ctl, num_pp;
+   struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
+   int num_lm, num_ctl, num_pp, num_dsc;
int i, j;

if (!drm_enc) {
@@ -1061,11 +1069,16 @@ static void dpu_encoder_virt_mode_set(struct
drm_encoder *drm_enc,
dpu_rm_get_assigned_resources(_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
ARRAY_SIZE(hw_dspp));
+   num_dsc = dpu_rm_get_assigned_resources(_kms->rm, global_state,
+   drm_enc->base.id, DPU_HW_BLK_DSC, hw_dsc, ARRAY_SIZE(hw_dsc));

for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
: NULL;

+   for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
+   dpu_enc->hw_dsc[i] = i < num_dsc ? to_dpu_hw_dsc(hw_dsc[i]) : 
NULL;
+
cstate = to_dpu_crtc_state(drm_crtc->state);

for (i = 0; i < num_lm; i++) {
@@ -1810,10 +1823,133 @@ static void
dpu_encoder_vsync_event_work_handler(struct kthread_work *work)
nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
 }

+static void
+dpu_encoder_dsc_pclk_param_calc(struct msm_display_dsc_config *dsc, 
u32 width)

+{
+   int slice_count, slice_per_intf;
+   int bytes_in_slice, total_bytes_per_intf;
+
+   if (!dsc || !dsc->drm->slice_width || !dsc->drm->slice_count) {
+   DPU_ERROR("Invalid DSC/slices\n");
+   return;
+   }
+
+   slice_count = dsc->drm->slice_count;
+   slice_per_intf = DIV_ROUND_UP(width, dsc->drm->slice_width);
+
+   /*
+* If slice_count is greater than slice_per_intf then default to 1.
+* This can happen during partial update.
+*/
+   if (slice_count > slice_per_intf)
+   slice_count = 1;
+
+   bytes_in_slice = DIV_ROUND_UP(dsc->drm->slice_width *
+ dsc->drm->bits_per_pixel, 8);
+   total_bytes_per_intf = bytes_in_slice * slice_per_intf;
+
+   dsc->eol_byte_num =