linux-stable/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
Marijn Suijten babdb815ef drm/msm/dpu: Pass catalog pointers in RM to replace for-loop ID lookups
The Resource Manager already iterates over all available blocks from the
catalog, only to pass their ID to a dpu_hw_xxx_init() function which
uses an _xxx_offset() helper to search for and find the exact same
catalog pointer again to initialize the block with, fallible error
handling and all.

Instead, pass const pointers to the catalog entries directly to these
_init functions and drop the for loops entirely, saving on both
readability complexity and unnecessary cycles at boot.

Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/533861/
Link: https://lore.kernel.org/r/20230418-dpu-drop-useless-for-lookup-v3-3-e8d869eea455@somainline.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-05-22 10:14:16 +03:00

99 lines
2.1 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/
#include "dpu_hwio.h"
#include "dpu_hw_catalog.h"
#include "dpu_hw_lm.h"
#include "dpu_hw_dspp.h"
#include "dpu_kms.h"
/* DSPP_PCC */
#define PCC_EN BIT(0)
#define PCC_DIS 0
#define PCC_RED_R_OFF 0x10
#define PCC_RED_G_OFF 0x1C
#define PCC_RED_B_OFF 0x28
#define PCC_GREEN_R_OFF 0x14
#define PCC_GREEN_G_OFF 0x20
#define PCC_GREEN_B_OFF 0x2C
#define PCC_BLUE_R_OFF 0x18
#define PCC_BLUE_G_OFF 0x24
#define PCC_BLUE_B_OFF 0x30
static void dpu_setup_dspp_pcc(struct dpu_hw_dspp *ctx,
struct dpu_hw_pcc_cfg *cfg)
{
u32 base;
if (!ctx) {
DRM_ERROR("invalid ctx %pK\n", ctx);
return;
}
base = ctx->cap->sblk->pcc.base;
if (!base) {
DRM_ERROR("invalid ctx %pK pcc base 0x%x\n", ctx, base);
return;
}
if (!cfg) {
DRM_DEBUG_DRIVER("disable pcc feature\n");
DPU_REG_WRITE(&ctx->hw, base, PCC_DIS);
return;
}
DPU_REG_WRITE(&ctx->hw, base + PCC_RED_R_OFF, cfg->r.r);
DPU_REG_WRITE(&ctx->hw, base + PCC_RED_G_OFF, cfg->r.g);
DPU_REG_WRITE(&ctx->hw, base + PCC_RED_B_OFF, cfg->r.b);
DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_R_OFF, cfg->g.r);
DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_G_OFF, cfg->g.g);
DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_B_OFF, cfg->g.b);
DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_R_OFF, cfg->b.r);
DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_G_OFF, cfg->b.g);
DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_B_OFF, cfg->b.b);
DPU_REG_WRITE(&ctx->hw, base, PCC_EN);
}
static void _setup_dspp_ops(struct dpu_hw_dspp *c,
unsigned long features)
{
if (test_bit(DPU_DSPP_PCC, &features))
c->ops.setup_pcc = dpu_setup_dspp_pcc;
}
struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg,
void __iomem *addr)
{
struct dpu_hw_dspp *c;
if (!addr)
return ERR_PTR(-EINVAL);
c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
c->hw.blk_addr = addr + cfg->base;
c->hw.log_mask = DPU_DBG_MASK_DSPP;
/* Assign ops */
c->idx = cfg->id;
c->cap = cfg;
_setup_dspp_ops(c, c->cap->features);
return c;
}
void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp)
{
kfree(dspp);
}