[PATCH v7 10/19] drm/imx: Add i.MX8qxp Display Controller pixel engine

Liu Ying victor.liu at nxp.com
Mon Dec 23 22:47:48 PST 2024


On 12/23/2024, Dmitry Baryshkov wrote:
> On Mon, Dec 23, 2024 at 02:41:38PM +0800, Liu Ying wrote:
>> i.MX8qxp Display Controller pixel engine consists of all processing
>> units that operate in the AXI bus clock domain.  Add drivers for
>> ConstFrame, ExtDst, FetchLayer, FetchWarp and LayerBlend units, as
>> well as a pixel engine driver, so that two displays with primary
>> planes can be supported.  The pixel engine driver and those unit
>> drivers are components to be aggregated by a master registered in
>> the upcoming DRM driver.
>>
>> Reviewed-by: Maxime Ripard <mripard at kernel.org>
>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>> ---
>> v7:
>> * Add kernel doc for struct dc_drm_device. (Dmitry)
>> * Fix regmap_config definitions by correcting name field, correcting read
>>   ranges and setting max_register field.
>> * Get instance numbers from device data(compatible strings) instead of OF
>>   aliases.
>> * Collect Maxime's R-b tag.
>> * Trivial tweaks.
>>
>> v6:
>> * Fix build warning by expanding sizeof(fu->name) from 13 to 21.
>>   (kernel test robot)
>>
>> v5:
>> * Replace .remove_new with .remove in dc-{cf,de,fl,fw,lb,pe}.c. (Uwe)
>> * Fix commit message to state that pixel engine driver is a component driver
>>   instead of a master/aggregate driver.
>>
>> v4:
>> * Use regmap to define register map for all registers. (Dmitry)
>> * Use regmap APIs to access registers. (Dmitry)
>> * Inline some small functions. (Dmitry)
>> * Move dc_lb_blendcontrol() function call from KMS routine to initialization
>>   stage. (Dmitry)
>> * Use devm_kzalloc() to drmm_kzalloc() to allocate dc_* data strutures.
>> * Drop unnecessary private struct dc_*_priv.
>> * Set suppress_bind_attrs driver flag to true to avoid unnecessary sys
>>   interfaces to bind/unbind the drivers.
>> * Make some fetch unit operations be aware of fractional fetch unit index(0-7).
>>
>> v3:
>> * No change.
>>
>> v2:
>> * Use OF alias id to get instance id.
> 
> Carrying several comments from previous patch:
> - shdld vs shdload

Will change IRQ names from shdld to shdload.

> - use of indices in the compat strings

Maybe keep adding indices in the compatible strings since I explained in
my replies to your comments on patch 3 and 9.

> - bind() behaviour depending on the particular order of device bindings

As I explained in the my reply to patch 9, bind() behaviour is deterministic.

> 
>>
>> +
>> +void dc_fu_common_hw_init(struct dc_fu *fu)
>> +{
>> +	enum dc_fu_frac frac;
>> +	int i;
>> +
>> +	dc_fu_baddr_autoupdate(fu, 0x0);
>> +	dc_fu_enable_shden(fu);
>> +	dc_fu_set_linemode(fu, LINEMODE_DISPLAY);
>> +	dc_fu_set_numbuffers(fu, 16);
>> +
>> +	for (i = 0; i < ARRAY_SIZE(dc_fetchunit_all_fracs); i++) {
> 
> for (i = DC_FETCHUNIT_FRAC0 ; i < DC_FETCHUNIT_FRAC_NUM; i++) ?

Ack.

> 
>> +		frac = dc_fetchunit_all_fracs[i];
>> +
>> +		dc_fu_layeroffset(fu, frac, 0, 0);
>> +		dc_fu_clipoffset(fu, frac, 0, 0);
>> +		dc_fu_clipdimensions(fu, frac, 1, 1);
>> +		dc_fu_disable_src_buf(fu, frac);
>> +		dc_fu_set_pixel_blend_mode(fu, frac);
>> +	}
>> +}
>> +
> 
> [...]
> 
>> +enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb)
>> +{
>> +	return lb->link;
>> +}
>> +
>> +void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim)
>> +{
>> +	int fixed_sels_num = ARRAY_SIZE(prim_sels) - 4;
>> +	int i;
>> +
>> +	for (i = 0; i < fixed_sels_num + lb->id; i++) {
> 
> This function and the next one silently skip writing link ID if it is
> incorrect. Can it actually become incorrect? If not, I'd say, it is
> better to drop the loop and the array. If you are not sure, there should
> be some kind of dev_warn() or drm_warn().

Will add a dev_warn() in this and the next function in case prim/sec arguments
are invalid.

> 
>> +		if (prim_sels[i] == prim) {
>> +			regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
>> +					  PIXENGCFG_DYNAMIC_PRIM_SEL_MASK,
>> +					  PIXENGCFG_DYNAMIC_PRIM_SEL(prim));
>> +			return;
>> +		}
>> +	}
>> +}
>> +
>> +void dc_lb_pec_dynamic_sec_sel(struct dc_lb *lb, enum dc_link_id sec)
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i < ARRAY_SIZE(sec_sels); i++) {
>> +		if (sec_sels[i] == sec) {
>> +			regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
>> +					  PIXENGCFG_DYNAMIC_SEC_SEL_MASK,
>> +					  PIXENGCFG_DYNAMIC_SEC_SEL(sec));
>> +			return;
>> +		}
>> +	}
>> +}
>> +
> 
> [...]
> 
>> +
>> +static int dc_lb_bind(struct device *dev, struct device *master, void *data)
>> +{
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	struct dc_drm_device *dc_drm = data;
>> +	struct dc_pe *pe = dc_drm->pe;
>> +	void __iomem *base_pec;
>> +	void __iomem *base_cfg;
>> +	struct dc_lb *lb;
>> +
>> +	lb = devm_kzalloc(dev, sizeof(*lb), GFP_KERNEL);
>> +	if (!lb)
>> +		return -ENOMEM;
>> +
>> +	lb->id = (enum dc_lb_id)(uintptr_t)device_get_match_data(dev);
>> +
>> +	base_pec = devm_platform_ioremap_resource_byname(pdev, "pec");
>> +	if (IS_ERR(base_pec))
>> +		return PTR_ERR(base_pec);
>> +
>> +	base_cfg = devm_platform_ioremap_resource_byname(pdev, "cfg");
>> +	if (IS_ERR(base_cfg))
>> +		return PTR_ERR(base_cfg);
>> +
>> +	lb->reg_pec = devm_regmap_init_mmio(dev, base_pec,
>> +					    &dc_lb_pec_regmap_config);
>> +	if (IS_ERR(lb->reg_pec))
>> +		return PTR_ERR(lb->reg_pec);
>> +
>> +	lb->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
>> +					    &dc_lb_cfg_regmap_config);
>> +	if (IS_ERR(lb->reg_cfg))
>> +		return PTR_ERR(lb->reg_cfg);
>> +
>> +	lb->link = lb_links[lb->id];
> 
> lb->link = LINK_ID_LAYERBLEND0 + lb->id ?

Ack.

> 
>> +
>> +	pe->lb[lb->id] = lb;
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct component_ops dc_lb_ops = {
>> +	.bind = dc_lb_bind,
>> +};
>> +
> 

-- 
Regards,
Liu Ying



More information about the linux-phy mailing list