dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Krzysztof Kozlowski <krzk@kernel.org>
To: Kisung Lee <kiisung.lee@samsung.com>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Alim Akhtar <alim.akhtar@samsung.com>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	Inki Dae <inki.dae@samsung.com>
Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-samsung-soc@vger.kernel.org, linux-media@vger.kernel.org
Subject: Re: [PATCH 2/4] media: samsung: scaler: add scaler driver code
Date: Wed, 27 Aug 2025 08:38:09 +0200	[thread overview]
Message-ID: <ef3822a5-d3f8-41dc-984c-8c63d60eaec5@kernel.org> (raw)
In-Reply-To: <20250827044720.3751272-3-kiisung.lee@samsung.com>

On 27/08/2025 06:47, Kisung Lee wrote:
> +
> +static int sc_probe(struct platform_device *pdev)
> +{
> +	struct sc_dev *sc;
> +	struct resource *res;
> +	int ret = 0;
> +	size_t ivar;
> +	u32 hwver = 0;
> +	int irq_num;
> +
> +	sc = devm_kzalloc(&pdev->dev, sizeof(struct sc_dev), GFP_KERNEL);


Oh yeah, 10 year old coding style. Very dissapointing :(

> +	if (!sc)
> +		goto err_dev;
> +
> +	sc->dev = &pdev->dev;
> +	spin_lock_init(&sc->ctxlist_lock);
> +	INIT_LIST_HEAD(&sc->ctx_list_high_prio);
> +	INIT_LIST_HEAD(&sc->ctx_list_low_prio);
> +	spin_lock_init(&sc->slock);
> +	mutex_init(&sc->lock);
> +	init_waitqueue_head(&sc->wait);
> +
> +	sc->fence_context = dma_fence_context_alloc(1);
> +	spin_lock_init(&sc->fence_lock);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	pr_err("Resource start: 0x%pa, end: 0x%pa, size: 0x%lx, flags: 0x%lx\n",

No, drop.

> +	       &res->start, &res->end,
> +	       (unsigned long)resource_size(res),
> +	       (unsigned long)res->flags);
> +	sc->regs = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(sc->regs)) {
> +		pr_err("devm_ioremap_resource failed: %pe\n", sc->regs);
> +		goto err_io_resource;
> +	}
> +	dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
> +
> +	atomic_set(&sc->wdt.cnt, 0);
> +	timer_setup(&sc->wdt.timer, sc_watchdog, 0);
> +
> +	if (pdev->dev.of_node) {
> +		sc->dev_id = of_alias_get_id(pdev->dev.of_node, "scaler");

NAK, check my DT talk.

> +		if (sc->dev_id < 0) {
> +			dev_err(&pdev->dev,
> +				"Failed to read scaler node id(%d)!\n", sc->dev_id);
> +			ret = -EINVAL;
> +			goto err_node_id;
> +		}
> +	} else {
> +		sc->dev_id = pdev->id;
> +	}
> +
> +	platform_set_drvdata(pdev, sc);
> +
> +	pm_runtime_enable(&pdev->dev);
> +
> +	ret = sc_populate_dt(sc);
> +	if (ret)
> +		goto err_dt;
> +
> +	ret = sc_register_m2m_device(sc, sc->dev_id);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to register m2m device\n");
> +		goto err_m2m;
> +	}
> +
> +#if defined(CONFIG_PM_DEVFREQ) && defined(NEVER_DEFINED)

You must be joking?

> +	if (!of_property_read_u32(pdev->dev.of_node, "mscl,int_qos_minlock",

NAK

> +				  (u32 *)&sc->qosreq_int_level)) {
> +		if (sc->qosreq_int_level > 0) {
> +			exynos_pm_qos_add_request(&sc->qosreq_int,
> +						  PM_QOS_DEVICE_THROUGHPUT, 0);
> +			dev_info(&pdev->dev, "INT Min.Lock Freq. = %u\n",
> +				 sc->qosreq_int_level);
> +		}
> +	}
> +#endif
> +	if (of_property_read_u32(pdev->dev.of_node, "mscl,cfw",

Cannot express more: NAK. You cannot add such undocumented ABI.

> +				 (u32 *)&sc->cfw))
> +		sc->cfw = 0;
> +
> +	ret = sc_get_hwversion(sc);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "%s: failed to get hw version (err %d)\n",
> +			__func__, ret);
> +		goto err_m2m;
> +	} else {
> +		hwver = ret;
> +	}
> +
> +	for (ivar = 0; ivar < ARRAY_SIZE(sc_variant); ivar++) {
> +		if (sc->version >= sc_variant[ivar].version) {
> +			sc->variant = &sc_variant[ivar];
> +			break;
> +		}
> +	}
> +
> +	if (sc->version >= SCALER_VERSION(7, 0, 1)) {
> +		sc->sysreg_offset = SCALER_SYSREG_OFFSET(res->start);
> +		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +		if (res) {
> +			sc->sysreg = devm_ioremap_resource(&pdev->dev, res);
> +			if (IS_ERR(sc->sysreg)) {
> +				dev_info(&pdev->dev, "SCALER LLC SYSREG is not setted.\n");
> +			} else {
> +				writel(SCALER_LLC_NO_HINT, sc->sysreg + sc->sysreg_offset);
> +				dev_info(&pdev->dev, "SCALER LLC SYSREG is setted with NO_HINT.\n");
> +			}
> +		}
> +	}
> +
> +	sc_hwset_soft_reset(sc);
> +
> +	if (!IS_ERR(sc->aclk))
> +		clk_disable_unprepare(sc->aclk);
> +	if (!IS_ERR(sc->pclk))
> +		clk_disable_unprepare(sc->pclk);
> +	pm_runtime_put(&pdev->dev);
> +
> +	irq_num = platform_get_irq(pdev, 0);
> +	if (irq_num < 0) {
> +		dev_err(&pdev->dev, "failed to get IRQ resource\n");

you just upstream 10 year old code, right?

Please carefully check the slides of my Monday's talk from OSSE25 about
static analyzers. Look at slides about upstreaming 10 year old vendor
code (that's a very bad idea).


> +		ret = -ENOENT;

Wrong error code.

> +		goto err_get_irq_res;
> +	}
> +
> +	ret = devm_request_irq(&pdev->dev, irq_num, sc_irq_handler, 0,
> +			       pdev->name, sc);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to install irq\n");
> +		goto err_request_irq;
> +	}
> +
> +	dev_info(&pdev->dev,
> +		 "Driver probed successfully(version: %08x(%x))\n",
> +		 hwver, sc->version);

NAK, don't add such code. Ever.

> +
> +	return 0;
> +
> +err_request_irq:
> +err_get_irq_res:
> +err_m2m:
> +err_dt:
> +err_node_id:
> +err_io_resource:
> +	if (sc)
> +		devm_kfree(&pdev->dev, sc);
> +err_dev:
> +	dev_err(&pdev->dev,
> +		"Driver probed failed!\n");


No, drop. Useless.

> +
> +	return ret;
> +}
> +




...

> +static struct sc_csc_tab sc_y2r = {
> +	/* REC.601 Narrow */
> +	{ 0x0254, 0x0000, 0x0331, 0x0254, 0xFF37, 0xFE60, 0x0254, 0x0409, 0x0000 },
> +	/* REC.601 Wide */
> +	{ 0x0200, 0x0000, 0x02BE, 0x0200, 0xFF54, 0xFE9B, 0x0200, 0x0377, 0x0000 },
> +	/* REC.709 Narrow */
> +	{ 0x0254, 0x0000, 0x0396, 0x0254, 0xFF93, 0xFEEF, 0x0254, 0x043A, 0x0000 },
> +	/* REC.709 Wide */
> +	{ 0x0200, 0x0000, 0x0314, 0x0200, 0xFFA2, 0xFF16, 0x0200, 0x03A1, 0x0000 },
> +	/* BT.2020 Narrow */
> +	{ 0x0254, 0x0000, 0x035B, 0x0254, 0xFFA0, 0xFEB3, 0x0254, 0x0449, 0x0000 },
> +	/* BT.2020 Wide */
> +	{ 0x0200, 0x0000, 0x02E2, 0x0200, 0xFFAE, 0xFEE2, 0x0200, 0x03AE, 0x0000 },
> +};
> +
> +static struct sc_csc_tab sc_r2y = {
> +	/* REC.601 Narrow */
> +	{ 0x0083, 0x0102, 0x0032, 0xFFB4, 0xFF6B, 0x00E1, 0x00E1, 0xFF44, 0xFFDB },
> +	/* REC.601 Wide  */
> +	{ 0x0099, 0x012D, 0x003A, 0xFFA8, 0xFF53, 0x0106, 0x0106, 0xFF25, 0xFFD5 },
> +	/* REC.709 Narrow */
> +	{ 0x005D, 0x013A, 0x0020, 0xFFCC, 0xFF53, 0x00E1, 0x00E1, 0xFF34, 0xFFEB },
> +	/* REC.709 Wide */
> +	{ 0x006D, 0x016E, 0x0025, 0xFFC4, 0xFF36, 0x0106, 0x0106, 0xFF12, 0xFFE8 },
> +	/* BT.2020 Narrow */
> +	{ 0x0074, 0x012A, 0x001A, 0xFFC1, 0xFF5E, 0x00E1, 0x00E1, 0xFF31, 0xFFEE },
> +	/* BT.2020 Wide */
> +	{ 0x0087, 0x015B, 0x001E, 0xFFB7, 0xFF43, 0x0106, 0x0106, 0xFF0F, 0xFFEB },
> +};
> +
> +static struct sc_csc_tab *sc_csc_list[] = {
> +	[0] = &sc_no_csc,
> +	[1] = &sc_y2r,
> +	[2] = &sc_r2y,
> +};
> +
> +static struct sc_bl_op_val sc_bl_op_tbl[] = {


Why absolutely nothing here is const?

> +	/* Sc,	 Sa,	Dc,	Da */
> +	{ZERO,	 ZERO,	ZERO,	ZERO},		/* CLEAR */
> +	{ ONE,	 ONE,	ZERO,	ZERO},		/* SRC */
> +	{ZERO,	 ZERO,	ONE,	ONE},		/* DST */
> +	{ ONE,	 ONE,	INV_SA,	INV_SA},	/* SRC_OVER */
> +	{INV_DA, ONE,	ONE,	INV_SA},	/* DST_OVER */
> +	{DST_A,	 DST_A,	ZERO,	ZERO},		/* SRC_IN */
> +	{ZERO,	 ZERO,	SRC_A,	SRC_A},		/* DST_IN */
> +	{INV_DA, INV_DA, ZERO,	ZERO},		/* SRC_OUT */
> +	{ZERO,	 ZERO,	INV_SA,	INV_SA},	/* DST_OUT */
> +	{DST_A,	 ZERO,	INV_SA,	ONE},		/* SRC_ATOP */
> +	{INV_DA, ONE,	SRC_A,	ZERO},		/* DST_ATOP */
> +	{INV_DA, ONE,	INV_SA,	ONE},		/* XOR: need to WA */
> +	{INV_DA, ONE,	INV_SA,	INV_SA},	/* DARKEN */
> +	{INV_DA, ONE,	INV_SA,	INV_SA},	/* LIGHTEN */
> +	{INV_DA, ONE,	INV_SA,	INV_SA},	/* MULTIPLY */
> +	{ONE,	 ONE,	INV_SC,	INV_SA},	/* SCREEN */
> +	{ONE,	 ONE,	ONE,	ONE},		/* ADD */
> +};
> +

...

> +	yfilter = sc_get_scale_filter(yratio);
> +	cfilter = sc_get_scale_filter(cratio);
> +	bit_adj = !sc->variant->pixfmt_10bit;
> +
> +	/* reset value of the coefficient registers are the 8:8 table */
> +	for (phase = 0; phase < 9; phase++) {
> +		__raw_writel(sc_coef_adj(bit_adj, sc_coef_4t[yfilter][phase][1]),
> +			     sc->regs + SCALER_YVCOEF + phase * 8);
> +		__raw_writel(sc_coef_adj(bit_adj, sc_coef_4t[yfilter][phase][0]),
> +			     sc->regs + SCALER_YVCOEF + phase * 8 + 4);
> +	}
> +
> +	for (phase = 0; phase < 9; phase++) {
> +		__raw_writel(sc_coef_adj(bit_adj, sc_coef_4t[cfilter][phase][1]),
> +			     sc->regs + SCALER_CVCOEF + phase * 8);
> +		__raw_writel(sc_coef_adj(bit_adj, sc_coef_4t[cfilter][phase][0]),
> +			     sc->regs + SCALER_CVCOEF + phase * 8 + 4);
> +	}
> +}
> +
> +void sc_get_span(struct sc_frame *frame, u32 *yspan, u32 *cspan)
> +{
> +	if (IS_ERR_OR_NULL(frame) || IS_ERR_OR_NULL(yspan) || IS_ERR_OR_NULL(cspan)) {

Sorrry, but what? How each of these can be ERR or NULL? How is it possible?

Please provide exact cases leading to this.

> +		pr_err("[%s] frame(%p) or yspan(%p) or cspan(%p) is wrong\n",
> +		       __func__, frame, yspan, cspan);
> +		return;
> +	}
> +
> +	*yspan = frame->width;
> +
> +	if (frame->sc_fmt->num_comp == 2) {
> +		*cspan = frame->width << frame->sc_fmt->cspan;
> +	} else if (frame->sc_fmt->num_comp == 3) {
> +		if (sc_fmt_is_ayv12(frame->sc_fmt->pixelformat)) {
> +			*cspan = ALIGN(frame->width >> 1, 16);
> +		} else if (sc_fmt_is_yuv420(frame->sc_fmt->pixelformat)) { /* YUV420 */
> +			if (frame->cspanalign) {
> +				*cspan = ALIGN(frame->width >> 1,
> +					       8 << (frame->cspanalign - 1));
> +			} else {
> +				*cspan = frame->width >> 1;
> +			}
> +		} else if (frame->sc_fmt->cspan) { /* YUV444 */
> +			*cspan = frame->width;
> +		} else {
> +			*cspan = frame->width >> 1;
> +		}
> +	} else if (frame->sc_fmt->num_comp == 1) {
> +		if (sc_fmt_is_rgb888(frame->sc_fmt->pixelformat))
> +			if (frame->yspanalign)
> +				*yspan = ALIGN(frame->width,
> +					       8 << (frame->yspanalign - 1));
> +		*cspan = 0;
> +	} else {
> +		*cspan = 0;
> +	}
> +}
> +
> +void sc_hwset_src_imgsize(struct sc_dev *sc, struct sc_frame *frame)
> +{
> +	u32 yspan = 0, cspan = 0;
> +
> +	if (IS_ERR_OR_NULL(sc) || IS_ERR_OR_NULL(frame)) {

How can be ERR or NULL? This looks buggy, like you don't know flow of
own code.

> +		pr_err("[%s] sc(%p) or frame(%p) is wrong\n", __func__, sc, frame);

dev_err


This is terrible driver, poorly coded, using 10 year old coding style,
repeating many known antipatterns and mistakes. It is very dissapointing
to see Samsung sending such poor code.

Really poor code.

Best regards,
Krzysztof

  reply	other threads:[~2025-08-27  6:38 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20250827045905epcas2p2daa6599d04f38c002e396abf23d60fe7@epcas2p2.samsung.com>
2025-08-27  4:47 ` [PATCH 0/4] Add DT bindings and driver code for Scaler Kisung Lee
     [not found]   ` <CGME20250827045905epcas2p4b2cbd4b881af1c1be4b345861d1a635b@epcas2p4.samsung.com>
2025-08-27  4:47     ` [PATCH 1/4] dt-bindings: soc: samsung: scaler: exynos: Add ExynosAutov920 compatible Kisung Lee
2025-08-27  6:30       ` Krzysztof Kozlowski
     [not found]   ` <CGME20250827045905epcas2p46c8bc31d9c32168f77d1e10808e92b77@epcas2p4.samsung.com>
2025-08-27  4:47     ` [PATCH 2/4] media: samsung: scaler: add scaler driver code Kisung Lee
2025-08-27  6:38       ` Krzysztof Kozlowski [this message]
     [not found]   ` <CGME20250827045905epcas2p3a52debf186f41eef08e6d0a351d80476@epcas2p3.samsung.com>
2025-08-27  4:47     ` [PATCH 3/4] arm64: dts: exynosautov920: enable support for scaler device Kisung Lee
2025-08-27  6:38       ` Krzysztof Kozlowski
     [not found]   ` <CGME20250827045906epcas2p2198037517886df0714e24d8d908a6c57@epcas2p2.samsung.com>
2025-08-27  4:47     ` [PATCH 4/4] media: samsung: scaler: Add Kconfig and Makefile Kisung Lee
2025-08-27  6:39       ` Krzysztof Kozlowski
2025-08-27 23:18   ` [PATCH 0/4] Add DT bindings and driver code for Scaler Rob Herring (Arm)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ef3822a5-d3f8-41dc-984c-8c63d60eaec5@kernel.org \
    --to=krzk@kernel.org \
    --cc=airlied@gmail.com \
    --cc=alim.akhtar@samsung.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=inki.dae@samsung.com \
    --cc=kiisung.lee@samsung.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mchehab@kernel.org \
    --cc=mripard@kernel.org \
    --cc=robh@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).