devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Paul Cercueil <paul@crapouillou.net>
To: Sam Ravnborg <sam@ravnborg.org>
Cc: David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>,
	Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <maxime.ripard@bootlin.com>,
	Sean Paul <sean@poorly.run>,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v2 3/3] DRM: Add KMS driver for the Ingenic JZ47xx SoCs
Date: Sun, 17 Mar 2019 02:14:32 +0100	[thread overview]
Message-ID: <1552785272.1562.2@crapouillou.net> (raw)
In-Reply-To: <20190316215944.GB11309@ravnborg.org>

Hi Sam,

Le sam. 16 mars 2019 à 22:59, Sam Ravnborg <sam@ravnborg.org> a écrit 
:
> Hi Paul.
> 
> Thanks for the v2 submission.
> 
> Did you analyze the possibility to utilize 
> drm_simple_display_pipe_init()
> and the related infrastructure?
> If this fits it should simplify the driver.
> If it does not fit please let us know why.
> As this is a one crtc / one connector / one panel the drm_simple_*
> infrastructure is supposed to be a good fit.

In the current state of the driver it would be possible to use the
drm_simple_display_pipe stuff, yes. However the SoCs support multiple
planes, and multiple outputs, and the plan is to upload the driver
to support these.

> Some smaller comments in the following.
> Most are suggestion, do not follow these blindly.

Ok, thanks.

Regards,
-Paul

> 	Sam
> 
>>  Add a KMS driver for the Ingenic JZ47xx family of SoCs.
>>  This driver is meant to replace the aging jz4740-fb driver.
>> 
>>  Signed-off-by: Paul Cercueil <paul@crapouillou.net>
>>  Tested-by: Artur Rojek <contact@artur-rojek.eu>
> 
>>  +struct ingenic_drm {
>>  +	struct device *dev;
>>  +	void __iomem *base;
>>  +	struct regmap *map;
>>  +	struct clk *lcd_clk, *pix_clk;
>>  +
>>  +	u32 lcd_mode;
>>  +
>>  +	struct ingenic_dma_hwdesc *framedesc;
> 
> Consider the name "dma_hwdesc" for this.
> The struct is named so, which give a good indication
> this is a more descriptive name.
> 
> That said, the current solution looks much cleaner than the
> previous one.
> 
>>  +	dma_addr_t framedesc_phys;
> Likewise.
> 
> 
>>  +
>>  +	struct drm_device *drm;
> If drm is embedded you can use devm_drm_dev_init()
> recently added to drm-misc.
> 
> See the very nice example in drivers/gu/drm/drm_drv.c
> (only in drm-misc-next for now)
> 
>>  +	struct drm_plane primary;
>>  +	struct drm_crtc crtc;
>>  +	struct drm_encoder encoder;
>>  +};
>>  +
>>  +
>>  +static int ingenic_drm_probe(struct platform_device *pdev)
>>  +{
>>  +	const struct jz_soc_info *soc_info;
>>  +	struct device *dev = &pdev->dev;
>>  +	struct ingenic_drm *priv;
>>  +	struct clk *parent_clk;
>>  +	struct drm_bridge *bridge;
>>  +	struct drm_panel *panel;
>>  +	struct drm_device *drm;
>>  +	struct resource *mem;
>>  +	void __iomem *base;
>>  +	long parent_rate;
>>  +	int ret, irq;
>>  +
>>  +	soc_info = device_get_match_data(dev);
> Everyone else uses of_device_... here. You should most
> likely do the same.
> 
>>  +	if (!soc_info)
>>  +		return -EINVAL;
> Also, consider to print an error here.
> 
>>  +
>>  +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>>  +	if (!priv)
>>  +		return -ENOMEM;
> Use of devm_kzalloc() here is not good. See driver example in 
> drm_drv.c
> 
>>  +
>>  +	priv->dev = dev;
>>  +
>>  +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>  +	priv->base = base = devm_ioremap_resource(dev, mem);
>>  +	if (IS_ERR(base))
>>  +		return PTR_ERR(base);
>>  +
>>  +	irq = platform_get_irq(pdev, 0);
>>  +	if (irq < 0) {
>>  +		dev_err(dev, "Failed to get platform irq\n");
>>  +		return -ENOENT;
>>  +	}
>>  +
>>  +	priv->map = devm_regmap_init_mmio(dev, base,
>>  +					  &ingenic_drm_regmap_config);
>>  +	if (IS_ERR(priv->map)) {
>>  +		dev_err(dev, "Failed to create regmap\n");
>>  +		return PTR_ERR(priv->map);
>>  +	}
>>  +
>>  +	if (soc_info->needs_dev_clk) {
>>  +		priv->lcd_clk = devm_clk_get(dev, "lcd");
>>  +		if (IS_ERR(priv->lcd_clk)) {
>>  +			dev_err(dev, "Failed to get lcd clock\n");
>>  +			return PTR_ERR(priv->lcd_clk);
>>  +		}
>>  +	}
>>  +
>>  +	priv->pix_clk = devm_clk_get(dev, "lcd_pclk");
>>  +	if (IS_ERR(priv->pix_clk)) {
>>  +		dev_err(dev, "Failed to get pixel clock\n");
>>  +		return PTR_ERR(priv->pix_clk);
>>  +	}
>>  +
>>  +	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &panel, 
>> &bridge);
>>  +	if (ret) {
>>  +		if (ret != -EPROBE_DEFER)
>>  +			dev_err(dev, "Failed to get panel handle\n");
>>  +		return ret;
>>  +	}
>>  +
>>  +	if (panel) {
>>  +		bridge = devm_drm_panel_bridge_add(dev, panel,
>>  +						   DRM_MODE_CONNECTOR_Unknown);
>>  +	}
>>  +
>>  +	device_property_read_u32(dev, "ingenic,lcd-mode", 
>> &priv->lcd_mode);
>>  +
>>  +	priv->framedesc = dma_alloc_coherent(dev, 
>> sizeof(*priv->framedesc),
>>  +					     &priv->framedesc_phys, GFP_KERNEL);
>>  +	if (!priv->framedesc)
>>  +		return -ENOMEM;
>>  +
>>  +	priv->framedesc->next = priv->framedesc_phys;
>>  +	priv->framedesc->id = 0xdeafbead;
>>  +
>>  +	drm = drm_dev_alloc(&ingenic_drm_driver_data, dev);
>>  +	if (IS_ERR(drm)) {
>>  +		ret = PTR_ERR(drm);
>>  +		goto err_free_dma;
>>  +	}
>>  +
>>  +	priv->drm = drm;
>>  +
>>  +	drm_mode_config_init(drm);
>>  +	drm->mode_config.min_width = 0;
>>  +	drm->mode_config.min_height = 0;
>>  +	drm->mode_config.max_width = 800;
>>  +	drm->mode_config.max_height = 600;
>>  +	drm->mode_config.funcs = &ingenic_drm_mode_config_funcs;
>>  +
>>  +	drm_plane_helper_add(&priv->primary, 
>> &ingenic_drm_plane_helper_funcs);
>>  +
>>  +	ret = drm_universal_plane_init(drm, &priv->primary,
>>  +				       0, &ingenic_drm_primary_plane_funcs,
>>  +				       ingenic_drm_primary_formats,
>>  +				       ARRAY_SIZE(ingenic_drm_primary_formats),
>>  +				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
>>  +	if (ret) {
>>  +		dev_err(dev, "Failed to register primary plane: %i\n", ret);
>>  +		goto err_unref_drm;
>>  +	}
>>  +
>>  +	drm_crtc_helper_add(&priv->crtc, &ingenic_drm_crtc_helper_funcs);
>>  +
>>  +	ret = drm_crtc_init_with_planes(drm, &priv->crtc, &priv->primary,
>>  +					NULL, &ingenic_drm_crtc_funcs, NULL);
>>  +	if (ret) {
>>  +		dev_err(dev, "Failed to init CRTC: %i\n", ret);
>>  +		goto err_cleanup_plane;
>>  +	}
>>  +
>>  +	priv->encoder.possible_crtcs = 1;
>>  +
>>  +	drm_encoder_helper_add(&priv->encoder,
>>  +			       &ingenic_drm_encoder_helper_funcs);
>>  +
>>  +	ret = drm_encoder_init(drm, &priv->encoder, 
>> &ingenic_drm_encoder_funcs,
>>  +			       DRM_MODE_ENCODER_DPI, NULL);
>>  +	if (ret) {
>>  +		dev_err(dev, "Failed to init encoder: %i\n", ret);
>>  +		goto err_cleanup_crtc;
>>  +	}
>>  +
>>  +	ret = drm_bridge_attach(&priv->encoder, bridge, NULL);
>>  +	if (ret) {
>>  +		dev_err(dev, "Unable to attach bridge\n");
>>  +		goto err_cleanup_encoder;
>>  +	}
>>  +
>>  +	platform_set_drvdata(pdev, drm);
>>  +	priv->drm = drm;
>>  +	drm->dev_private = priv;
>>  +
>>  +	ret = drm_irq_install(drm, irq);
>>  +	if (ret) {
>>  +		dev_err(dev, "Unable to install IRQ handler\n");
>>  +		goto err_cleanup_encoder;
>>  +	}
>>  +
>>  +	ret = drm_vblank_init(drm, 1);
>>  +	if (ret) {
>>  +		dev_err(dev, "Failed calling drm_vblank_init()\n");
>>  +		goto err_uninstall_irq;
>>  +	}
>>  +
>>  +	drm_mode_config_reset(drm);
>>  +
>>  +	ret = clk_prepare_enable(priv->pix_clk);
>>  +	if (ret) {
>>  +		dev_err(dev, "Unable to start pixel clock\n");
>>  +		goto err_uninstall_irq;
>>  +	}
>>  +
>>  +	if (priv->lcd_clk) {
>>  +		parent_clk = clk_get_parent(priv->lcd_clk);
>>  +		parent_rate = clk_get_rate(parent_clk);
>>  +
>>  +		/* LCD Device clock must be 3x the pixel clock for STN panels,
>>  +		 * or 1.5x the pixel clock for TFT panels. To avoid having to
>>  +		 * check for the LCD device clock everytime we do a mode change,
>>  +		 * we set the LCD device clock to the highest rate possible.
>>  +		 */
>>  +		ret = clk_set_rate(priv->lcd_clk, parent_rate);
>>  +		if (ret) {
>>  +			dev_err(dev, "Unable to set LCD clock rate\n");
>>  +			goto err_pixclk_disable;
>>  +		}
>>  +
>>  +		ret = clk_prepare_enable(priv->lcd_clk);
>>  +		if (ret) {
>>  +			dev_err(dev, "Unable to start lcd clock\n");
>>  +			goto err_pixclk_disable;
>>  +		}
>>  +	}
>>  +
>>  +	ret = drm_fbdev_generic_setup(drm, 16);
>>  +	if (ret) {
>>  +		dev_err(dev, "Failed to init fbdev\n");
>>  +		goto err_devclk_disable;
>>  +	}
> fbdev is usually considered an optionl feature that do not prevent
> the display driver from loading.
> Consider what to do in the error case.
> 

  reply	other threads:[~2019-03-17  1:14 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-15 17:06 [PATCH v2 1/3] dt-bindings: Add doc for the ingenic-drm driver Paul Cercueil
2019-03-15 17:07 ` [PATCH v2 2/3] dt-bindings: Add header for the ingenic-drm driver bindings Paul Cercueil
2019-03-15 17:07 ` [PATCH v2 3/3] DRM: Add KMS driver for the Ingenic JZ47xx SoCs Paul Cercueil
2019-03-16 21:59   ` Sam Ravnborg
2019-03-17  1:14     ` Paul Cercueil [this message]
2019-04-02 16:16     ` Paul Cercueil
2019-04-15 16:09     ` Daniel Vetter
2019-03-16 12:29 ` [PATCH v2 1/3] dt-bindings: Add doc for the ingenic-drm driver Paul Cercueil
2019-03-16 20:59 ` Sam Ravnborg
2019-03-16 21:56   ` Paul Cercueil

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=1552785272.1562.2@crapouillou.net \
    --to=paul@crapouillou.net \
    --cc=airlied@linux.ie \
    --cc=daniel@ffwll.ch \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mark.rutland@arm.com \
    --cc=maxime.ripard@bootlin.com \
    --cc=robh+dt@kernel.org \
    --cc=sam@ravnborg.org \
    --cc=sean@poorly.run \
    /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).