mbox series

[0/4] drm/msm/dpu: Qualcomm SC8180x MDSS/DPU support

Message ID 20210511041852.592295-1-bjorn.andersson@linaro.org
Headers show
Series drm/msm/dpu: Qualcomm SC8180x MDSS/DPU support | expand

Message

Bjorn Andersson May 11, 2021, 4:18 a.m. UTC
These patches adds MDSS and DPU support for the Qualcomm SC8180x platform.

The platform supports running 2 pixels per pixel clock cycle and the bootloader
enables this, so the first patch adds enough support to the DPU driver to
disable this again.

The second patch shoots down the data path configured in CTL_0, as the DPU
driver picks CTL_2 on the laptops, causing graphical artifacts.

The third patch adds the SC8180x to the hw catalog.

The forth patch is included for "completeness", but needs to be reworked. It
updates the IRQ mapping for INTF_5, which is where we find the eDP controller.

Bjorn Andersson (3):
  drm/msm/dpu: Introduce knowledge of widebus feature
  drm/msm/dpu: Clear boot loader configured data paths
  dpu: hack up the irq table for 8180 intf_5

Rob Clark (1):
  drm/msm/dpu: Add SC8180x to hw catalog

 .../devicetree/bindings/display/msm/dpu.txt   |   4 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 121 ++++++++++++++++++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   5 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c    |   4 +
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  14 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   |   3 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c       |   3 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c        |  36 ++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h        |   8 ++
 drivers/gpu/drm/msm/msm_drv.c                 |   1 +
 10 files changed, 188 insertions(+), 11 deletions(-)

Comments

Dmitry Baryshkov May 12, 2021, 11:06 p.m. UTC | #1
On Tue, 11 May 2021 at 07:18, Bjorn Andersson
<bjorn.andersson@linaro.org> wrote:
>
> It's typical for the bootloader to configure CTL_0 for the boot splash
> or EFIFB, but for non-DSI use cases the DPU driver tend to pick another
> CTL and the system might end up with two configured data paths producing
> data on the same INTF - with resulting graphical artifacts.
>
> Naturally the end goal would be to inherit the bootloader's
> configuration and provide the user with a glitch free handover from the
> boot configuration to a running DPU.
> But such effort will affect clocks, regulators, power-domains etc, so in
> the meantime this patch simply disables all INTFs and clear all
> configured data paths, to avoid the graphical artifacts.

Good idea. We'd have to be careful to test this with interfaces in command mode.

>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c |  4 +++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c    |  2 ++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c     | 36 ++++++++++++++++++++++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h     |  8 +++++
>  4 files changed, 50 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> index 2d4645e01ebf..7aba27c1055a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> @@ -349,9 +349,13 @@ static void dpu_hw_ctl_clear_all_blendstages(struct dpu_hw_ctl *ctx)
>                 DPU_REG_WRITE(c, CTL_LAYER_EXT(LM_0 + i), 0);
>                 DPU_REG_WRITE(c, CTL_LAYER_EXT2(LM_0 + i), 0);
>                 DPU_REG_WRITE(c, CTL_LAYER_EXT3(LM_0 + i), 0);
> +
> +               ctx->pending_flush_mask |= dpu_hw_ctl_get_bitmask_mixer(ctx, LM_0 + i);
>         }
>
>         DPU_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, 0);
> +
> +       ctx->pending_flush_mask |= CTL_FLUSH_MASK_CTL;
>  }
>
>  static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index 88e9cc38c13b..8b01cb660381 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -970,6 +970,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>
>         dpu_kms->rm_init = true;
>
> +       dpu_rm_clear_boot_config(&dpu_kms->rm, dpu_kms->catalog);
> +
>         dpu_kms->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, dpu_kms->mmio,
>                                              dpu_kms->catalog);
>         if (IS_ERR(dpu_kms->hw_mdp)) {
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index fd2d104f0a91..2cf47084482f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> @@ -4,6 +4,7 @@
>   */
>
>  #define pr_fmt(fmt)    "[drm:%s] " fmt, __func__
> +#include <linux/delay.h>
>  #include "dpu_kms.h"
>  #include "dpu_hw_lm.h"
>  #include "dpu_hw_ctl.h"
> @@ -229,6 +230,41 @@ int dpu_rm_init(struct dpu_rm *rm,
>         return rc ? rc : -EFAULT;
>  }
>
> +void dpu_rm_clear_boot_config(struct dpu_rm *rm, struct dpu_mdss_cfg *cat)
> +{
> +       struct dpu_hw_intf *intf;
> +       struct dpu_hw_ctl *ctl;
> +       int i;
> +
> +       for (i = INTF_0; i < INTF_MAX; i++) {
> +               if (!rm->intf_blks[i - INTF_0])
> +                       continue;
> +
> +               DPU_DEBUG("disabling intf%d timing engine\n", i - INTF_0);
> +
> +               intf = to_dpu_hw_intf(rm->intf_blks[i - INTF_0]);
> +               intf->ops.enable_timing(intf, 0);
> +       }
> +
> +       /*
> +        * Wait one frame for the INTF timing engine to stop, and then wait one
> +        * more frame, per the documentation.
> +        */
> +       msleep(32);
> +
> +       for (i = CTL_0; i < CTL_MAX; i++) {
> +               if (!rm->ctl_blks[i - CTL_0])
> +                       continue;
> +
> +               DPU_DEBUG("clearing ctl%d layer configuration\n", i - CTL_0);
> +
> +               ctl = to_dpu_hw_ctl(rm->ctl_blks[i - CTL_0]);
> +               ctl->ops.clear_all_blendstages(ctl);
> +               ctl->ops.trigger_flush(ctl);
> +               ctl->ops.trigger_start(ctl);
> +       }
> +}
> +
>  static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top)
>  {
>         return top->num_intf > 1;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> index 1f12c8d5b8aa..53cd649614a3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> @@ -88,5 +88,13 @@ void dpu_rm_release(struct dpu_global_state *global_state,
>  int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
>         struct dpu_global_state *global_state, uint32_t enc_id,
>         enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size);
> +
> +/**
> + * dpu_rm_clear_boot_config() - Tear down any data paths configured by boot
> + * @rm: DPU Resource Manger handle
> + * @cat: Pointer to hardware catalog
> + */
> +void dpu_rm_clear_boot_config(struct dpu_rm *rm, struct dpu_mdss_cfg *cat);
> +
>  #endif /* __DPU_RM_H__ */
>
> --
> 2.29.2
>
Dmitry Baryshkov May 12, 2021, 11:14 p.m. UTC | #2
On Tue, 11 May 2021 at 07:18, Bjorn Andersson
<bjorn.andersson@linaro.org> wrote:
>
> Some hardware supports clocking 2 pixels per pixel clock pulse, known as
> "widebus". The configuration needs to match between the DPU and the
> interface controller, and the timing parameters must be adjusted.
>
> As a first step towards supporting this, start by adding a INTF mask
> flag to signal the timing configuration code that the INTF_CONFIG2
> register should be written - which will clear the bit, in the case that
> the bootloader left it set.
>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c    | 3 ++-
>  2 files changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> index 4dfd8a20ad5c..c2f34a4f82d9 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -196,12 +196,14 @@ enum {
>   * @DPU_INTF_TE                 INTF block has TE configuration support
>   * @DPU_DATA_HCTL_EN            Allows data to be transferred at different rate
>                                  than video timing
> + * @DPU_INTF_WIDEBUS            INTF block supports driving 2 pixels per clock
>   * @DPU_INTF_MAX
>   */
>  enum {
>         DPU_INTF_INPUT_CTRL = 0x1,
>         DPU_INTF_TE,
>         DPU_DATA_HCTL_EN,
> +       DPU_INTF_WIDEBUS,
>         DPU_INTF_MAX
>  };
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> index 1599e3f49a4f..933485d8c03c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> @@ -183,7 +183,6 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx,
>         if (ctx->cap->features & BIT(DPU_DATA_HCTL_EN)) {
>                 intf_cfg2 |= BIT(4);
>                 display_data_hctl = display_hctl;
> -               DPU_REG_WRITE(c, INTF_CONFIG2, intf_cfg2);
>                 DPU_REG_WRITE(c, INTF_DISPLAY_DATA_HCTL, display_data_hctl);
>         }
>
> @@ -204,6 +203,8 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx,
>         DPU_REG_WRITE(c, INTF_FRAME_LINE_COUNT_EN, 0x3);
>         DPU_REG_WRITE(c, INTF_CONFIG, intf_cfg);
>         DPU_REG_WRITE(c, INTF_PANEL_FORMAT, panel_format);
> +       if (ctx->cap->features & (BIT(DPU_DATA_HCTL_EN) | BIT(DPU_INTF_WIDEBUS)))
> +               DPU_REG_WRITE(c, INTF_CONFIG2, intf_cfg2);
>  }
>
>  static void dpu_hw_intf_enable_timing_engine(
> --
> 2.29.2
>