Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d88b5b5c authored by Abhinav Kumar's avatar Abhinav Kumar Committed by Gerrit - the friendly Code Review server
Browse files

disp: msm: add hardware register ops for VDC-m block



Add hardware register set and programming for VDC-m block.

Change-Id: I60ef27b507284521abdd10bb679a85303475ddc3
Signed-off-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
parent 88a43f24
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ msm_drm-$(CONFIG_DRM_MSM_SDE) += sde/sde_crtc.o \
	sde/sde_hw_reg_dma_v1.o \
	sde/sde_hw_dsc.o \
	sde/sde_hw_dsc_1_2.o \
	sde/sde_hw_vdc.o \
	sde/sde_hw_ds.o \
	sde/sde_fence.o \
	sde/sde_hw_qdss.o \
+4 −0
Original line number Diff line number Diff line
@@ -220,10 +220,12 @@ enum msm_mdp_conn_property {
 * enum msm_display_compression_type - compression method used for pixel stream
 * @MSM_DISPLAY_COMPRESSION_NONE:     Pixel data is not compressed
 * @MSM_DISPLAY_COMPRESSION_DSC:      DSC compresison is used
 * @MSM_DISPLAY_COMPRESSION_VDC:      VDC compresison is used
 */
enum msm_display_compression_type {
	MSM_DISPLAY_COMPRESSION_NONE,
	MSM_DISPLAY_COMPRESSION_DSC,
	MSM_DISPLAY_COMPRESSION_VDC
};

/**
@@ -652,6 +654,7 @@ struct msm_mode_info {
 * struct msm_resource_caps_info - defines hw resources
 * @num_lm              number of layer mixers available
 * @num_dsc             number of dsc available
 * @num_vdc             number of vdc available
 * @num_ctl             number of ctl available
 * @num_3dmux           number of 3d mux available
 * @max_mixer_width:    max width supported by layer mixer
@@ -659,6 +662,7 @@ struct msm_mode_info {
struct msm_resource_caps_info {
	uint32_t num_lm;
	uint32_t num_dsc;
	uint32_t num_vdc;
	uint32_t num_ctl;
	uint32_t num_3dmux;
	uint32_t max_mixer_width;
+6 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ enum sde_hw_blk_type {
	SDE_HW_BLK_INTF,
	SDE_HW_BLK_WB,
	SDE_HW_BLK_DSC,
	SDE_HW_BLK_VDC,
	SDE_HW_BLK_MERGE_3D,
	SDE_HW_BLK_QDSS,
	SDE_HW_BLK_MAX,
@@ -526,6 +527,7 @@ struct sde_mdss_color {
#define SDE_DBG_MASK_UIDLE    (1 << 15)
#define SDE_DBG_MASK_SID      (1 << 15)
#define SDE_DBG_MASK_QDSS     (1 << 16)
#define SDE_DBG_MASK_VDC      (1 << 17)

/**
 * struct sde_hw_cp_cfg: hardware dspp/lm feature payload.
@@ -603,10 +605,12 @@ struct sde_sspp_index_info {
 * @ctl_ids:	Stores the valid MDSS ctl block ids for the current mode
 * @lm_ids:	Stores the valid MDSS layer mixer block ids for the current mode
 * @dsc_ids:	Stores the valid MDSS DSC block ids for the current mode
 * @vdc_ids:	Stores the valid MDSS VDC block ids for the current mode
 * @pipes:      Array of sspp info detected on this display
 * @ctl_cnt:    Stores the active number of MDSS "top" blks of the current mode
 * @lm_cnt:	Stores the active number of MDSS "LM" blks for the current mode
 * @dsc_cnt:	Stores the active number of MDSS "dsc" blks for the current mode
 * @vdc_cnt:	Stores the valid MDSS VDC block ids for the current mode
 * @pipe_cnt:	Stores the active number of "sspp" blks connected
 */
struct sde_splash_display {
@@ -616,10 +620,12 @@ struct sde_splash_display {
	u8 ctl_ids[MAX_DATA_PATH_PER_DSIPLAY];
	u8 lm_ids[MAX_DATA_PATH_PER_DSIPLAY];
	u8 dsc_ids[MAX_DATA_PATH_PER_DSIPLAY];
	u8 vdc_ids[MAX_DATA_PATH_PER_DSIPLAY];
	struct sde_sspp_index_info pipes[MAX_DATA_PATH_PER_DSIPLAY];
	u8 ctl_cnt;
	u8 lm_cnt;
	u8 dsc_cnt;
	u8 vdc_cnt;
	u8 pipe_cnt;
};

msm/sde/sde_hw_vdc.c

0 → 100644
+453 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 */

#include "sde_hw_mdss.h"
#include "sde_hwio.h"
#include "sde_hw_catalog.h"
#include "sde_hw_dsc.h"
#include "sde_hw_pingpong.h"
#include "sde_dbg.h"
#include "sde_kms.h"
#include "sde_hw_vdc.h"
#include "sde_vdc_helper.h"

#define VDC_CMN_MAIN_CNF           0x00

/* SDE_VDC_ENC register offsets */
#define ENC_OUT_BF_CTRL            0x00
#define ENC_GENERAL_STATUS         0x04
#define ENC_HSLICE_STATUS          0x08
#define ENC_OUT_STATUS             0x0C
#define ENC_INT_STAT               0x10
#define ENC_INT_CLR                0x14
#define ENC_INT_ENABLE             0x18
#define ENC_R2B_BUF_CTRL           0x1c
#define ENC_ORIG_SLICE             0x40
#define ENC_DF_CTRL                0x44
#define ENC_VDC_VERSION            0x80
#define ENC_VDC_FRAME_SIZE         0x84
#define ENC_VDC_SLICE_SIZE         0x88
#define ENC_VDC_SLICE_PX           0x8c
#define ENC_VDC_MAIN_CONF          0x90
#define ENC_VDC_CHUNK_SIZE         0x94
#define ENC_VDC_RC_CONFIG_0        0x98
#define ENC_VDC_RC_CONFIG_1        0x9c
#define ENC_VDC_RC_CONFIG_2        0xa0
#define ENC_VDC_RC_CONFIG_3        0xa4
#define ENC_VDC_RC_CONFIG_4        0xa8
#define ENC_VDC_FLAT_CONFIG        0xac
#define ENC_VDC_FLAT_LUT_3_0       0xb0
#define ENC_VDC_FLAT_LUT_7_4       0xb4
#define ENC_VDC_MAX_QP_LUT_3_0     0xb8
#define ENC_VDC_MAX_QP_LUT_7_4     0xbc
#define ENC_VDC_TAR_RATE_LUT_3_0   0xc0
#define ENC_VDC_TAR_RATE_LUT_7_4   0xc4
#define ENC_VDC_TAR_RATE_LUT_11_8  0xc8
#define ENC_VDC_TAR_RATE_LUT_15_12 0xcc
#define ENC_VDC_MPPF_CONFIG        0xd0
#define ENC_VDC_SSM_CONFIG         0xd4
#define ENC_VDC_SLICE_NUM_BITS_0   0xd8
#define ENC_VDC_SLICE_NUM_BITS_1   0xdc
#define ENC_VDC_RC_PRECOMPUTE      0xe0
#define ENC_VDC_MPP_CONFIG         0xe4
#define ENC_VDC_LBDA_BRATE_LUT     0x100
#define ENC_VDC_LBDA_BF_LUT        0x180
#define ENC_VDC_OTHER_RC           0x1c0

/* SDE_VDC_CTL register offsets */
#define VDC_CTL                    0x00
#define VDC_CFG                    0x04
#define VDC_DATA_IN_SWAP           0x08
#define VDC_CLK_CTRL               0x0C

#define VDC_CTL_BLOCK_SIZE         0x300

static inline _vdc_subblk_offset(struct sde_hw_vdc *hw_vdc, int s_id,
		u32 *idx)
{
	int rc = 0;
	const struct sde_vdc_sub_blks *sblk;

	if (!hw_vdc)
		return -EINVAL;

	sblk = hw_vdc->caps->sblk;

	switch (s_id) {
	case SDE_VDC_ENC:
		*idx = sblk->enc.base;
		break;
	case SDE_VDC_CTL:
		*idx = sblk->ctl.base;
		break;
	default:
		rc = -EINVAL;
	}

	return rc;
}

static void sde_hw_vdc_disable(struct sde_hw_vdc *hw_vdc)
{
	struct sde_hw_blk_reg_map *vdc_reg;
	u32 idx;

	if (!hw_vdc)
		return;

	if (_vdc_subblk_offset(hw_vdc, SDE_VDC_CTL, &idx))
		return;

	vdc_reg = &hw_vdc->hw;
	SDE_REG_WRITE(vdc_reg, VDC_CFG + idx, 0);

	/* common register */
	SDE_REG_WRITE(vdc_reg, VDC_CMN_MAIN_CNF, 0);
}

static void sde_hw_vdc_config(struct sde_hw_vdc *hw_vdc,
	struct msm_display_vdc_info *vdc)
{
	struct sde_hw_blk_reg_map *vdc_reg = &hw_vdc->hw;
	u32 idx;
	u32 data = 0;
	int i = 0;
	u8 bits_per_component;
	int addr_off = 0;
	u32 slice_num_bits_ub, slice_num_bits_ldw;

	if (!hw_vdc)
		return;

	if (_vdc_subblk_offset(hw_vdc, SDE_VDC_ENC, &idx))
		return;

	data = ((vdc->ob1_max_addr & 0xffff) << 16);
	data |= (vdc->ob0_max_addr & 0xffff);
	SDE_REG_WRITE(vdc_reg, ENC_OUT_BF_CTRL + idx, data);

	data = ((vdc->r2b1_max_addr & 0xffff) << 16);
	data |= (vdc->r2b0_max_addr & 0xffff);
	SDE_REG_WRITE(vdc_reg, ENC_R2B_BUF_CTRL + idx, data);

	data = vdc->slice_width_orig;
	SDE_REG_WRITE(vdc_reg, ENC_ORIG_SLICE + idx, data);

	data = 0;
	if (vdc->panel_mode == VDC_VIDEO_MODE)
		data |= BIT(9);
	data |= ((vdc->num_of_active_ss - 1) << 12);
	data |= vdc->initial_lines;
	SDE_REG_WRITE(vdc_reg, ENC_DF_CTRL + idx, data);

	data = 0;
	data |= (vdc->version_major << 24);
	data |= (vdc->version_minor << 16);
	data |= (vdc->version_release << 8);
	SDE_REG_WRITE(vdc_reg, ENC_VDC_VERSION + idx, data);

	data = 0;
	data |= (vdc->frame_width << 16);
	data |= vdc->frame_height;
	SDE_REG_WRITE(vdc_reg, ENC_VDC_FRAME_SIZE + idx, data);

	data = 0;
	data |= (vdc->slice_width << 16);
	data |=  vdc->slice_height;
	SDE_REG_WRITE(vdc_reg, ENC_VDC_SLICE_SIZE + idx, data);

	SDE_REG_WRITE(vdc_reg, ENC_VDC_SLICE_PX + idx,
		vdc->slice_num_px);

	data = 0;
	data |= (vdc->bits_per_pixel << 16);
	if (vdc->bits_per_component == 8)
		bits_per_component = 0;
	else if (vdc->bits_per_component == 10)
		bits_per_component = 1;
	else
		bits_per_component = 2;
	data |= (bits_per_component << 4);
	data |= (vdc->source_color_space << 2);
	data |= vdc->chroma_format;
	SDE_REG_WRITE(vdc_reg, ENC_VDC_MAIN_CONF + idx,
		data);

	SDE_REG_WRITE(vdc_reg, ENC_VDC_CHUNK_SIZE + idx,
		vdc->chunk_size);

	SDE_REG_WRITE(vdc_reg, ENC_VDC_RC_CONFIG_0 + idx,
		vdc->rc_buffer_init_size);

	data = 0;
	data |= (vdc->rc_stuffing_bits << 24);
	data |= (vdc->rc_init_tx_delay << 16);
	data |= vdc->rc_buffer_max_size;
	SDE_REG_WRITE(vdc_reg, ENC_VDC_RC_CONFIG_1 + idx, data);

	SDE_REG_WRITE(vdc_reg, ENC_VDC_RC_CONFIG_2 + idx,
		vdc->rc_target_rate_threshold);

	data = 0;
	data |= (vdc->rc_tar_rate_scale << 24);
	data |= (vdc->rc_buffer_fullness_scale << 16);
	data |= vdc->rc_fullness_offset_thresh;

	SDE_REG_WRITE(vdc_reg, ENC_VDC_RC_CONFIG_3 + idx, data);

	data = 0;
	data |= (vdc->rc_fullness_offset_slope << 8);
	data |= RC_TARGET_RATE_EXTRA_FTBLS;

	SDE_REG_WRITE(vdc_reg, ENC_VDC_RC_CONFIG_4 + idx, data);

	data = 0;
	data |= (vdc->flatqp_vf_fbls << 24);
	data |= (vdc->flatqp_vf_nbls << 16);
	data |= (vdc->flatqp_sw_fbls << 8);
	data |= vdc->flatqp_sw_nbls;
	SDE_REG_WRITE(vdc_reg, ENC_VDC_FLAT_CONFIG + idx, data);

	data = 0;
	data |= (vdc->flatness_qp_lut[0] << 24);
	data |= (vdc->flatness_qp_lut[1] << 16);
	data |= (vdc->flatness_qp_lut[2] << 8);
	data |= vdc->flatness_qp_lut[3];
	SDE_REG_WRITE(vdc_reg, ENC_VDC_FLAT_LUT_3_0 + idx, data);

	data = 0;
	data |= (vdc->flatness_qp_lut[4] << 24);
	data |= (vdc->flatness_qp_lut[5] << 16);
	data |= (vdc->flatness_qp_lut[6] << 8);
	data |= vdc->flatness_qp_lut[7];
	SDE_REG_WRITE(vdc_reg, ENC_VDC_FLAT_LUT_7_4 + idx, data);

	data = 0;
	data |= (vdc->max_qp_lut[0] << 24);
	data |= (vdc->max_qp_lut[1] << 16);
	data |= (vdc->max_qp_lut[2] << 8);
	data |= vdc->max_qp_lut[3];
	SDE_REG_WRITE(vdc_reg, ENC_VDC_MAX_QP_LUT_3_0 + idx, data);

	data = 0;
	data |= (vdc->max_qp_lut[4] << 24);
	data |= (vdc->max_qp_lut[5] << 16);
	data |= (vdc->max_qp_lut[6] << 8);
	data |= vdc->max_qp_lut[7];
	SDE_REG_WRITE(vdc_reg, ENC_VDC_MAX_QP_LUT_7_4 + idx, data);

	data = 0;
	data |= (vdc->tar_del_lut[0] << 24);
	data |= (vdc->tar_del_lut[1] << 16);
	data |= (vdc->tar_del_lut[2] << 8);
	data |= vdc->tar_del_lut[3];
	SDE_REG_WRITE(vdc_reg, ENC_VDC_TAR_RATE_LUT_3_0 + idx, data);

	data = 0;
	data |= (vdc->tar_del_lut[4] << 24);
	data |= (vdc->tar_del_lut[5] << 16);
	data |= (vdc->tar_del_lut[6] << 8);
	data |= vdc->tar_del_lut[7];
	SDE_REG_WRITE(vdc_reg, ENC_VDC_TAR_RATE_LUT_7_4 + idx, data);

	data = 0;
	data |= (vdc->tar_del_lut[8] << 24);
	data |= (vdc->tar_del_lut[9] << 16);
	data |= (vdc->tar_del_lut[10] << 8);
	data |= vdc->tar_del_lut[11];
	SDE_REG_WRITE(vdc_reg, ENC_VDC_TAR_RATE_LUT_11_8 + idx, data);

	data = 0;
	data |= (vdc->tar_del_lut[12] << 24);
	data |= (vdc->tar_del_lut[13] << 16);
	data |= (vdc->tar_del_lut[14] << 8);
	data |= vdc->tar_del_lut[15];
	SDE_REG_WRITE(vdc_reg, ENC_VDC_TAR_RATE_LUT_15_12 + idx, data);

	data = 0;
	data |= (vdc->mppf_bpc_r_y << 20);
	data |= (vdc->mppf_bpc_g_cb << 16);
	data |= (vdc->mppf_bpc_b_cr << 12);
	data |= (vdc->mppf_bpc_y << 8);
	data |= (vdc->mppf_bpc_co << 4);
	data |= vdc->mppf_bpc_cg;
	SDE_REG_WRITE(vdc_reg, ENC_VDC_MPPF_CONFIG + idx, data);

	SDE_REG_WRITE(vdc_reg, ENC_VDC_SSM_CONFIG + idx,
			SSM_MAX_SE_SIZE);

	slice_num_bits_ldw = (u32)vdc->slice_num_bits;
	slice_num_bits_ub = vdc->slice_num_bits >> 32;

	SDE_REG_WRITE(vdc_reg, ENC_VDC_SLICE_NUM_BITS_0 + idx,
			(slice_num_bits_ub & 0x0ff));

	SDE_REG_WRITE(vdc_reg, ENC_VDC_SLICE_NUM_BITS_1 + idx,
			slice_num_bits_ldw);

	data = 0;
	data |= (vdc->chunk_adj_bits << 16);
	data |= vdc->num_extra_mux_bits;
	SDE_REG_WRITE(vdc_reg, ENC_VDC_RC_PRECOMPUTE + idx, data);

	for (i = 0; i < VDC_LBDA_BRATE_REG_SIZE; i += 2) {
		data = 0;
		data |= (vdc->lbda_brate_lut_interp[i] << 16);
		data |= vdc->lbda_brate_lut_interp[i + 1];
		SDE_REG_WRITE(vdc_reg,
			ENC_VDC_LBDA_BRATE_LUT + idx +
			(addr_off * 4),
			data);
		addr_off++;
	}

	for (i = 0; i < VDC_LBDA_BRATE_REG_SIZE; i += 4) {
		data = 0;
		data |= (vdc->lbda_bf_lut_interp[i] << 24);
		data |= (vdc->lbda_bf_lut_interp[i + 1] << 16);
		data |= (vdc->lbda_bf_lut_interp[i + 2] << 8);
		data |= vdc->lbda_bf_lut_interp[i + 3];
		SDE_REG_WRITE(vdc_reg, ENC_VDC_LBDA_BF_LUT + idx + i,
				data);
	}

	data = 0;
	data |= (vdc->min_block_bits << 16);
	data |= vdc->rc_lambda_bitrate_scale;
	SDE_REG_WRITE(vdc_reg, ENC_VDC_OTHER_RC + idx,
			data);
	/* program the vdc wrapper */
	if (_vdc_subblk_offset(hw_vdc, SDE_VDC_CTL, &idx))
		return;

	data = 0;
	data = BIT(0); /* encoder enable */
	if (vdc->bits_per_component == 8)
		data |= BIT(11);
	if (vdc->chroma_format == MSM_CHROMA_422) {
		data |= BIT(8);
		data |= BIT(10);
	}

	SDE_REG_WRITE(vdc_reg, VDC_CFG + idx, data);
}

static void sde_hw_vdc_bind_pingpong_blk(
		struct sde_hw_vdc *hw_vdc,
		bool enable,
		const enum sde_pingpong pp)
{
	struct sde_hw_blk_reg_map *vdc_reg;
	int idx;
	int mux_cfg = 0xF; /* Disabled */

	if (!hw_vdc)
		return;

	if (_vdc_subblk_offset(hw_vdc, SDE_VDC_CTL, &idx))
		return;

	vdc_reg = &hw_vdc->hw;
	if (enable)
		mux_cfg = (pp - PINGPONG_0) & 0xf;

	SDE_REG_WRITE(vdc_reg, VDC_CTL + idx, mux_cfg);
}

static struct sde_vdc_cfg *_vdc_offset(enum sde_vdc vdc,
		struct sde_mdss_cfg *m,
		void __iomem *addr,
		struct sde_hw_blk_reg_map *b)
{
	int i;

	for (i = 0; i < m->vdc_count; i++) {
		if (vdc == m->vdc[i].id) {
			b->base_off = addr;
			b->blk_off = m->vdc[i].base;
			b->length = m->vdc[i].len;
			b->hwversion = m->hwversion;
			b->log_mask = SDE_DBG_MASK_VDC;
			return &m->vdc[i];
		}
	}

	return NULL;
}

static void _setup_vdc_ops(struct sde_hw_vdc_ops *ops,
		unsigned long features)
{
	ops->vdc_disable = sde_hw_vdc_disable;
	ops->vdc_config = sde_hw_vdc_config;
	ops->bind_pingpong_blk = sde_hw_vdc_bind_pingpong_blk;
}

static struct sde_hw_blk_ops sde_hw_ops = {
	.start = NULL,
	.stop = NULL,
};

struct sde_hw_vdc *sde_hw_vdc_init(enum sde_vdc idx,
		void __iomem *addr,
		struct sde_mdss_cfg *m)
{
	struct sde_hw_vdc *c;
	struct sde_vdc_cfg *cfg;
	int rc;
	u32 vdc_ctl_reg;

	c = kzalloc(sizeof(*c), GFP_KERNEL);
	if (!c)
		return ERR_PTR(-ENOMEM);

	cfg = _vdc_offset(idx, m, addr, &c->hw);
	if (IS_ERR_OR_NULL(cfg)) {
		kfree(c);
		return ERR_PTR(-EINVAL);
	}

	c->idx = idx;
	c->caps = cfg;

	_setup_vdc_ops(&c->ops, c->caps->features);

	rc = sde_hw_blk_init(&c->base, SDE_HW_BLK_VDC, idx, &sde_hw_ops);
	if (rc) {
		SDE_ERROR("failed to init hw blk %d\n", rc);
		goto blk_init_error;
	}

	sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name, c->hw.blk_off,
		c->hw.blk_off + c->hw.length, c->hw.xin_id);

	if (_vdc_subblk_offset(c, SDE_VDC_CTL, &vdc_ctl_reg)) {
		SDE_ERROR("vdc ctl not found\n");
		kfree(c);
		return ERR_PTR(-EINVAL);
	}

	if (c->idx == VDC_0) {
		sde_dbg_reg_register_dump_range(SDE_DBG_NAME, "vdc_ctl",
				vdc_ctl_reg,
				vdc_ctl_reg + VDC_CTL_BLOCK_SIZE,
				c->hw.xin_id);
	}

	return c;

blk_init_error:
	kfree(c);

	return ERR_PTR(rc);
}

void sde_hw_vdc_destroy(struct sde_hw_vdc *vdc)
{
	if (vdc) {
		sde_hw_blk_destroy(&vdc->base);
		kfree(vdc);
	}
}

msm/sde/sde_hw_vdc.h

0 → 100644
+88 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _SDE_HW_VDC_H
#define _SDE_HW_VDC_H

#include "sde_hw_catalog.h"
#include "sde_hw_mdss.h"
#include "sde_hw_util.h"
#include "sde_hw_blk.h"

struct sde_hw_vdc;
struct msm_display_vdc_info;

/**
 * struct sde_hw_vdc_ops - interface to the vdc hardware driver functions
 * Assumption is these functions will be called after clocks are enabled
 */
struct sde_hw_vdc_ops {
	/**
	 * vdc_disable - disable vdc
	 * @hw_vdc: Pointer to vdc context
	 */
	void (*vdc_disable)(struct sde_hw_vdc *hw_vdc);

	/**
	 * vdc_config - configures vdc encoder
	 * @hw_vdc: Pointer to vdc context
	 * @vdc: panel vdc parameters
	 */
	void (*vdc_config)(struct sde_hw_vdc *hw_vdc,
					   struct msm_display_vdc_info *vdc);

	/**
	 * bind_pingpong_blk - enable/disable the connection with pp
	 * @hw_vdc: Pointer to vdc context
	 * @enable: enable/disable connection
	 * @pp: pingpong blk id
	 */
	void (*bind_pingpong_blk)(struct sde_hw_vdc *hw_vdc,
			bool enable,
			const enum sde_pingpong pp);
};

struct sde_hw_vdc {
	struct sde_hw_blk base;
	struct sde_hw_blk_reg_map hw;

	/* vdc */
	enum sde_vdc idx;
	const struct sde_vdc_cfg *caps;

	/* ops */
	struct sde_hw_vdc_ops ops;
};

/**
 * sde_hw_vdc - convert base object sde_hw_base to container
 * @hw: Pointer to base hardware block
 * return: Pointer to hardware block container
 */
static inline struct sde_hw_vdc *to_sde_hw_vdc(struct sde_hw_blk *hw)
{
	return container_of(hw, struct sde_hw_vdc, base);
}

/**
 * sde_hw_vdc_init - initializes the vdc block for the passed
 *                   vdc idx.
 * @idx:  VDC index for which driver object is required
 * @addr: Mapped register io address of MDP
 * @m:    Pointer to mdss catalog data
 * Returns: Error code or allocated sde_hw_vdc context
 */
struct sde_hw_vdc *sde_hw_vdc_init(enum sde_vdc idx,
		void __iomem *addr,
		struct sde_mdss_cfg *m);

/**
 * sde_hw_vdc_destroy - destroys vdc driver context
 *                      should be called to free the context
 * @vdc:   Pointer to vdc driver context returned by sde_hw_vdc_init
 */
void sde_hw_vdc_destroy(struct sde_hw_vdc *vdc);

#endif /*_SDE_HW_VDC_H */
Loading