All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jordan Crouse <jcrouse-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
To: Rajesh Yadav <ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Subject: Re: [DPU PATCH 03/11] drm/msm/dpu: add MDSS top level driver for dpu
Date: Thu, 10 May 2018 10:56:01 -0600	[thread overview]
Message-ID: <20180510165601.GD4995@jcrouse-lnx.qualcomm.com> (raw)
In-Reply-To: <1525940985-30428-4-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

On Thu, May 10, 2018 at 01:59:37PM +0530, Rajesh Yadav wrote:
> SoCs containing dpu have a MDSS top level wrapper
> which includes sub-blocks as dpu, dsi, phy, dp etc.
> MDSS top level wrapper manages common resources like
> common clocks, power and irq for its sub-blocks.
> 
> Currently, in dpu driver, all the power resource
> management is part of power_handle which manages
> these resources via a custom implementation. And
> the resource relationships are not modelled properly
> in dt.  Moreover the irq domain handling code is part
> of dpu device (which is a child device) due to lack
> of a dedicated driver for MDSS top level wrapper
> device.
> 
> This change adds dpu_mdss top level driver to handle
> common clock like - core clock, ahb clock
> (for register access), main power supply (i.e. gdsc)
> and irq management.
> The top level mdss device/driver acts as an interrupt
> controller and manage hwirq mapping for its child
> devices.
> 
> It implements runtime_pm support for resource management.
> Child nodes can control these resources via runtime_pm
> get/put calls on their corresponding devices due to parent
> child relationship defined in dt.
> 
> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
> ---
>  drivers/gpu/drm/msm/Makefile                      |   1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c      |  97 -------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h      |  14 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |   9 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   7 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  29 +--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  11 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c           |  48 +---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c           |   6 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h           |   2 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c          | 301 ++++++++++++++++++++++
>  drivers/gpu/drm/msm/dpu_io_util.c                 |  55 ++++
>  drivers/gpu/drm/msm/msm_drv.c                     |  26 +-
>  drivers/gpu/drm/msm/msm_drv.h                     |   2 +-
>  drivers/gpu/drm/msm/msm_kms.h                     |   2 +
>  include/linux/dpu_io_util.h                       |   2 +
>  16 files changed, 390 insertions(+), 222 deletions(-)
>  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c

<snip>

> -static struct dpu_mdss_base_cfg *__intr_offset(struct dpu_mdss_cfg *m,
> +static int __intr_offset(struct dpu_mdss_cfg *m,
>  		void __iomem *addr, struct dpu_hw_blk_reg_map *hw)
>  {
>  	if (!m || !addr || !hw || m->mdp_count == 0)
> -		return NULL;
> +		return -EINVAL;

It looks like this is only used by dpu_hw_intr_init and you know that m, addr
and hw will all be valid and I'm assuming that if we get this far there is at
least some assumption that mdp_count is set so it looks like you can skip this
error path and make this a void function.

>  	hw->base_off = addr;
> -	hw->blk_off = m->mdss[0].base;
> +	hw->blk_off = m->mdp[0].base;
>  	hw->hwversion = m->hwversion;
> -	return &m->mdss[0];
> +	return 0;
>  }
>  
>  struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
>  		struct dpu_mdss_cfg *m)
>  {
>  	struct dpu_hw_intr *intr;
> -	struct dpu_mdss_base_cfg *cfg;
> +	int ret;
>  
>  	if (!addr || !m)
>  		return ERR_PTR(-EINVAL);
> @@ -1195,10 +1182,10 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
>  	if (!intr)
>  		return ERR_PTR(-ENOMEM);
>  
> -	cfg = __intr_offset(m, addr, &intr->hw);
> -	if (!cfg) {
> +	ret = __intr_offset(m, addr, &intr->hw);
> +	if (ret) {
>  		kfree(intr);
> -		return ERR_PTR(-EINVAL);
> +		return ERR_PTR(ret);
>  	}

And making that a void function has the added benefit of skipping all of this

>  	__setup_intr_ops(&intr->ops);
>  

<snip>

> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> new file mode 100644
> index 0000000..26bf2c1
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> @@ -0,0 +1,301 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0
> + * Copyright (c) 2018, The Linux Foundation
> + */
> +
> +#include "dpu_kms.h"
> +
> +#define to_dpu_mdss(x) container_of(x, struct dpu_mdss, base)
> +
> +#define HW_INTR_STATUS			0x0010
> +
> +struct dpu_mdss {
> +	struct msm_mdss base;
> +	void __iomem *mmio;
> +	unsigned long mmio_len;
> +	u32 hwversion;
> +	struct dss_module_power mp;
> +	struct dpu_irq_controller irq_controller;
> +};
> +
> +static inline void _dpu_mdss_hw_rev_init(struct dpu_mdss *dpu_mdss)
> +{
> +	dpu_mdss->hwversion = readl_relaxed(dpu_mdss->mmio + 0x0);
> +}
> +
> +static int _dpu_mdss_get_intr_sources(struct dpu_mdss *dpu_mdss,
> +		uint32_t *sources)
> +{
> +	*sources = readl_relaxed(dpu_mdss->mmio + HW_INTR_STATUS);
> +	return 0;
> +}

It seems like this could just as easily be:

static u32 _dpu_mdss_get_intr_sources(struct dpu_mdss *dpu_mdss)
{
    return readl_relaxed(dpu_mdss->mmio + HW_INTR_STATUS);
}

Or it shouldn't return a 0 for no great reason but if you are going to go
out of your way to create a sub function I feel like it should do work.

> +static irqreturn_t dpu_mdss_irq(int irq, void *arg)
> +{
> +	struct dpu_mdss *dpu_mdss = arg;
> +	u32 interrupts;
> +
> +	if (!arg)
> +		return IRQ_NONE;

This is only possible if you are passing a NULL argument to the handler which I
doubt you are.

> +	_dpu_mdss_get_intr_sources(dpu_mdss, &interrupts);
> +

See how this could just as easily be

interrupts = _dpu_mdss_get_intr_sources(dpu_mdss);

> +	while (interrupts) {
> +		irq_hw_number_t hwirq = fls(interrupts) - 1;
> +		unsigned int mapping;
> +		int rc;
> +
> +		mapping = irq_find_mapping(dpu_mdss->irq_controller.domain,
> +				hwirq);
> +		if (mapping == 0) {
> +			DPU_EVT32(hwirq, DPU_EVTLOG_ERROR);
> +			goto error;
> +		}
> +
> +		rc = generic_handle_irq(mapping);
> +		if (rc < 0) {
> +			DPU_EVT32(hwirq, mapping, rc, DPU_EVTLOG_ERROR);
> +			goto error;
> +		}
> +
> +		interrupts &= ~(1 << hwirq);
> +	}
> +
> +	return IRQ_HANDLED;
> +
> +error:
> +	/* bad situation, inform irq system, it may disable overall MDSS irq */
> +	return IRQ_NONE;
> +}
> +
> +static void dpu_mdss_irq_mask(struct irq_data *irqd)
> +{
> +	struct dpu_mdss *dpu_mdss;
> +
> +	if (!irqd || !irq_data_get_irq_chip_data(irqd)) {
> +		DPU_ERROR("invalid parameters irqd %d\n", irqd != NULL);
> +		return;
> +	}

Neither of these can be NULL at this point since you specify the chip data
from the domain host_data which is known good.  You don't need these checks.

> +	dpu_mdss = irq_data_get_irq_chip_data(irqd);
> +
> +	/* memory barrier */
> +	smp_mb__before_atomic();
> +	clear_bit(irqd->hwirq, &dpu_mdss->irq_controller.enabled_mask);
> +	/* memory barrier */
> +	smp_mb__after_atomic();
> +}
> +
> +static void dpu_mdss_irq_unmask(struct irq_data *irqd)
> +{
> +	struct dpu_mdss *dpu_mdss;
> +
> +	if (!irqd || !irq_data_get_irq_chip_data(irqd)) {
> +		DPU_ERROR("invalid parameters irqd %d\n", irqd != NULL);
> +		return;
> +	}

Same as above.

> +	dpu_mdss = irq_data_get_irq_chip_data(irqd);
> +
> +	/* memory barrier */
> +	smp_mb__before_atomic();
> +	set_bit(irqd->hwirq, &dpu_mdss->irq_controller.enabled_mask);
> +	/* memory barrier */
> +	smp_mb__after_atomic();
> +}
> +
> +static struct irq_chip dpu_mdss_irq_chip = {
> +	.name = "dpu_mdss",
> +	.irq_mask = dpu_mdss_irq_mask,
> +	.irq_unmask = dpu_mdss_irq_unmask,
> +};
> +
> +static int dpu_mdss_irqdomain_map(struct irq_domain *domain,
> +		unsigned int irq, irq_hw_number_t hwirq)
> +{
> +	struct dpu_mdss *dpu_mdss;
> +	int ret;
> +
> +	if (!domain || !domain->host_data) {
> +		DPU_ERROR("invalid parameters domain %d\n", domain != NULL);
> +		return -EINVAL;
> +	}

The pointer to this function is derived from the domain pointer so it is known
good. You specify host_data when allocating the domain from a known good
pointer.  Neither of these checks are needed.

> +	dpu_mdss = domain->host_data;
> +
> +	irq_set_chip_and_handler(irq, &dpu_mdss_irq_chip, handle_level_irq);
> +	ret = irq_set_chip_data(irq, dpu_mdss);
> +
> +	return ret;
> +}
> +
> +static const struct irq_domain_ops dpu_mdss_irqdomain_ops = {
> +	.map = dpu_mdss_irqdomain_map,
> +	.xlate = irq_domain_xlate_onecell,
> +};
> +
> +static int _dpu_mdss_irq_domain_add(struct dpu_mdss *dpu_mdss)
> +{
> +	struct device *dev;
> +	struct irq_domain *domain;
> +
> +	dev = dpu_mdss->base.dev->dev;
> +
> +	domain = irq_domain_add_linear(dev->of_node, 32,
> +			&dpu_mdss_irqdomain_ops, dpu_mdss);
> +	if (!domain) {
> +		DPU_ERROR("failed to add irq_domain\n");
> +		return -EINVAL;
> +	}
> +
> +	dpu_mdss->irq_controller.enabled_mask = 0;
> +	dpu_mdss->irq_controller.domain = domain;
> +
> +	return 0;
> +}
> +
> +int _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss)
> +{
> +	if (dpu_mdss->irq_controller.domain) {
> +		irq_domain_remove(dpu_mdss->irq_controller.domain);
> +		dpu_mdss->irq_controller.domain = NULL;
> +	}
> +	return 0;
> +}
> +static int dpu_mdss_enable(struct msm_mdss *mdss)
> +{
> +	struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss);
> +	struct dss_module_power *mp = &dpu_mdss->mp;
> +	int ret = 0;

You don't need to initialize ret.

> +	ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
> +	if (ret)
> +		DPU_ERROR("clock enable failed, ret:%d\n", ret);
> +
> +	return 0;

You should return 'ret' here - presumably the calling function cares about
the result.

> +}
> +
> +static int dpu_mdss_disable(struct msm_mdss *mdss)
> +{
> +	struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss);
> +	struct dss_module_power *mp = &dpu_mdss->mp;
> +	int ret = 0;

You don't need to initialize ret.

> +	ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
> +	if (ret)
> +		DPU_ERROR("clock disable failed, ret:%d\n", ret);
> +
> +	return 0;

You should return 'ret' to the calling function.

> +}
> +
> +static void dpu_mdss_destroy(struct drm_device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev->dev);
> +	struct msm_drm_private *priv = dev->dev_private;
> +	struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss);
> +	struct dss_module_power *mp = &dpu_mdss->mp;
> +
> +	if (!dpu_mdss)
> +		return;

to_dpu_mdss is a container_of() so this can never be NULL. The check should
be on priv->mdss instead.

> +	_dpu_mdss_irq_domain_fini(dpu_mdss);
> +
> +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> +	devm_kfree(&pdev->dev, mp->clk_config);

You don't need to free these if you went out of your way to use devm in the
first place.

> +
> +	if (dpu_mdss->mmio)
> +		msm_iounmap(pdev, dpu_mdss->mmio);
> +	dpu_mdss->mmio = NULL;
> +
> +	pm_runtime_disable(dev->dev);
> +
> +	devm_kfree(dev->dev, dpu_mdss);
> +	priv->mdss = NULL;
> +}
> +
> +static const struct msm_mdss_funcs mdss_funcs = {
> +	.enable	= dpu_mdss_enable,
> +	.disable = dpu_mdss_disable,
> +	.destroy = dpu_mdss_destroy,
> +};
> +
> +int dpu_mdss_init(struct drm_device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev->dev);
> +	struct msm_drm_private *priv = dev->dev_private;
> +	struct dpu_mdss *dpu_mdss;
> +	struct dss_module_power *mp;
> +	int ret = 0;
> +
> +	if (!of_device_is_compatible(dev->dev->of_node, "qcom,dpu-mdss"))
> +		return 0;
> +
> +	dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL);
> +	if (!dpu_mdss)
> +		return -ENOMEM;
> +
> +	dpu_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "mdss_phys");
> +	if (IS_ERR(dpu_mdss->mmio)) {
> +		ret = PTR_ERR(dpu_mdss->mmio);
> +		DPU_ERROR("mdss register memory map failed: %d\n", ret);
> +		dpu_mdss->mmio = NULL;

You don't need to set this to NULL - you are going to immediately free
this structure.

> +		goto error;
> +	}
> +	DRM_INFO("mapped mdss address space @%p\n", dpu_mdss->mmio);

This should be debug or removed.  In any event, don't be using %p.

> +	dpu_mdss->mmio_len = msm_iomap_size(pdev, "mdss_phys");
> +
> +	mp = &dpu_mdss->mp;
> +	ret = msm_dss_parse_clock(pdev, mp);
> +	if (ret) {
> +		DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
> +		goto clk_parse_err;
> +	}
> +
> +	ret = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
> +	if (ret) {
> +		DPU_ERROR("failed to get clocks, ret=%d\n", ret);
> +		goto clk_get_error;
> +	}
> +
> +	ret = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
> +	if (ret) {
> +		DPU_ERROR("failed to set clock rate, ret=%d\n", ret);
> +		goto clk_rate_error;
> +	}
> +
> +	dpu_mdss->base.dev = dev;
> +	dpu_mdss->base.funcs = &mdss_funcs;
> +
> +	ret = _dpu_mdss_irq_domain_add(dpu_mdss);
> +	if (ret)
> +		goto irq_domain_error;
> +
> +	ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0),
> +			dpu_mdss_irq, 0, "dpu_mdss_isr", dpu_mdss);
> +	if (ret) {
> +		DPU_ERROR("failed to init irq: %d\n", ret);
> +		goto irq_error;
> +	}
> +
> +	pm_runtime_enable(dev->dev);
> +
> +	pm_runtime_get_sync(dev->dev);
> +	_dpu_mdss_hw_rev_init(dpu_mdss);
> +	pm_runtime_put_sync(dev->dev);
> +
> +	priv->mdss = &dpu_mdss->base;
> +
> +	return ret;
> +
> +irq_error:
> +	_dpu_mdss_irq_domain_fini(dpu_mdss);
> +irq_domain_error:
> +clk_rate_error:
> +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> +clk_get_error:
> +	devm_kfree(&pdev->dev, mp->clk_config);
> +clk_parse_err:
> +	if (dpu_mdss->mmio)
> +		msm_iounmap(pdev, dpu_mdss->mmio);
> +	dpu_mdss->mmio = NULL;
> +error:
> +	devm_kfree(dev->dev, dpu_mdss);
> +	return ret;
> +}
> diff --git a/drivers/gpu/drm/msm/dpu_io_util.c b/drivers/gpu/drm/msm/dpu_io_util.c
> index a18bc99..efa06a8 100644
> --- a/drivers/gpu/drm/msm/dpu_io_util.c
> +++ b/drivers/gpu/drm/msm/dpu_io_util.c
> @@ -448,6 +448,61 @@ int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable)
>  } /* msm_dss_enable_clk */
>  EXPORT_SYMBOL(msm_dss_enable_clk);
>  
> +int msm_dss_parse_clock(struct platform_device *pdev,
> +		struct dss_module_power *mp)
> +{
> +	u32 i = 0, rc = 0;
> +	const char *clock_name;
> +	u32 clock_rate = 0;
> +	u32 clock_max_rate = 0;
> +	int num_clk = 0;
> +
> +	if (!pdev || !mp) {
> +		pr_err("invalid input param pdev:%pK mp:%pK\n", pdev, mp);

I don't think a log is necessary here.  WARN if you must, but I would just
return.

> +		return -EINVAL;
> +	}
> +
> +	mp->num_clk = 0;
> +	num_clk = of_property_count_strings(pdev->dev.of_node, "clock-names");
> +	if (num_clk <= 0) {
> +		pr_err/*debug*/("clocks are not defined\n");

Ouch - please don't use internal comments */
> +		goto clk_err;

rc is 0 this point - you can just return 0 here (or error if you choose).
> +	}
> +
> +	mp->num_clk = num_clk;
> +	mp->clk_config = devm_kzalloc(&pdev->dev,
> +			sizeof(struct dss_clk) * num_clk, GFP_KERNEL);
> +	if (!mp->clk_config) {
> +		rc = -ENOMEM;
> +		mp->num_clk = 0;
> +		goto clk_err;
> +	}
> +
> +	for (i = 0; i < num_clk; i++) {
> +		of_property_read_string_index(pdev->dev.of_node, "clock-names",
> +							i, &clock_name);
> +		strlcpy(mp->clk_config[i].clk_name, clock_name,
> +				sizeof(mp->clk_config[i].clk_name));
> +
> +		of_property_read_u32_index(pdev->dev.of_node, "clock-rate",
> +							i, &clock_rate);
> +		mp->clk_config[i].rate = clock_rate;
> +
> +		if (!clock_rate)
> +			mp->clk_config[i].type = DSS_CLK_AHB;
> +		else
> +			mp->clk_config[i].type = DSS_CLK_PCLK;
> +
> +		clock_max_rate = 0;
> +		of_property_read_u32_index(pdev->dev.of_node, "clock-max-rate",
> +							i, &clock_max_rate);
> +		mp->clk_config[i].max_rate = clock_max_rate;
> +	}
> +
> +clk_err:
> +	return rc;
> +}
> +EXPORT_SYMBOL(msm_dss_parse_clock);

This needs to be exported? What other upstream modules would use this?

>  int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
>  			uint8_t reg_offset, uint8_t *read_buf)
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 5d8f1b6..a0e73ea 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -503,7 +503,18 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
>  	ddev->dev_private = priv;
>  	priv->dev = ddev;
>  
> -	ret = mdp5_mdss_init(ddev);
> +	switch (get_mdp_ver(pdev)) {
> +	case KMS_MDP5:
> +		ret = mdp5_mdss_init(ddev);
> +		break;
> +	case KMS_DPU:
> +		ret = dpu_mdss_init(ddev);
> +		break;
> +	default:
> +		ret = 0;
> +		break;
> +	}
> +
>  	if (ret)
>  		goto mdss_init_fail;
>  
> @@ -1539,12 +1550,13 @@ static int add_display_components(struct device *dev,
>  	int ret;
>  
>  	/*
> -	 * MDP5 based devices don't have a flat hierarchy. There is a top level
> -	 * parent: MDSS, and children: MDP5, DSI, HDMI, eDP etc. Populate the
> -	 * children devices, find the MDP5 node, and then add the interfaces
> -	 * to our components list.
> +	 * MDP5/DPU based devices don't have a flat hierarchy. There is a top
> +	 * level parent: MDSS, and children: MDP5/DPU, DSI, HDMI, eDP etc.
> +	 * Populate the children devices, find the MDP5/DPU node, and then add
> +	 * the interfaces to our components list.
>  	 */
> -	if (of_device_is_compatible(dev->of_node, "qcom,mdss")) {
> +	if (of_device_is_compatible(dev->of_node, "qcom,mdss") ||
> +		of_device_is_compatible(dev->of_node, "qcom,dpu-mdss")) {
>  		ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
>  		if (ret) {
>  			dev_err(dev, "failed to populate children devices\n");
> @@ -1686,7 +1698,7 @@ static int msm_pdev_remove(struct platform_device *pdev)
>  	{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
>  	{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
>  #ifdef CONFIG_DRM_MSM_DPU
> -	{ .compatible = "qcom,dpu-kms", .data = (void *)KMS_DPU },
> +	{ .compatible = "qcom,dpu-mdss", .data = (void *)KMS_DPU },
>  #endif
>  	{}
>  };
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index 90a2521..e8e5e73 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -381,7 +381,7 @@ struct msm_drm_private {
>  	/* subordinate devices, if present: */
>  	struct platform_device *gpu_pdev;
>  
> -	/* top level MDSS wrapper device (for MDP5 only) */
> +	/* top level MDSS wrapper device (for MDP5/DPU only) */
>  	struct msm_mdss *mdss;
>  
>  	/* possibly this should be in the kms component, but it is
> diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
> index 9a7bc7d..8f50613 100644
> --- a/drivers/gpu/drm/msm/msm_kms.h
> +++ b/drivers/gpu/drm/msm/msm_kms.h
> @@ -145,6 +145,8 @@ struct msm_mdss {
>  
>  int mdp5_mdss_init(struct drm_device *dev);
>  
> +int dpu_mdss_init(struct drm_device *dev);
> +
>  /**
>   * Mode Set Utility Functions
>   */
> diff --git a/include/linux/dpu_io_util.h b/include/linux/dpu_io_util.h
> index 7c73899..45e606f 100644
> --- a/include/linux/dpu_io_util.h
> +++ b/include/linux/dpu_io_util.h
> @@ -104,6 +104,8 @@ int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
>  void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);
>  int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);
>  int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable);
> +int msm_dss_parse_clock(struct platform_device *pdev,
> +		struct dss_module_power *mp);
>  
>  int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
>  		       uint8_t reg_offset, uint8_t *read_buf);

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

  parent reply	other threads:[~2018-05-10 16:56 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-10  8:29 [DPU PATCH 00/11] Refactor DPU device/driver hierarchy and add runtime_pm support Rajesh Yadav
2018-05-10  8:29 ` [DPU PATCH 01/11] drm/msm: remove redundant pm_runtime_enable call from msm_drv Rajesh Yadav
     [not found]   ` <1525940985-30428-2-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-10 15:02     ` Sean Paul
2018-05-10  8:29 ` [DPU PATCH 02/11] drm/msm/mdp5: subclass msm_mdss for mdp5 Rajesh Yadav
2018-05-10 13:37   ` Sean Paul
2018-05-10  8:29 ` [DPU PATCH 04/11] drm/msm/dpu: create new platform driver for dpu device Rajesh Yadav
     [not found]   ` <1525940985-30428-5-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-10 15:00     ` Sean Paul
2018-05-10 17:00     ` Jordan Crouse
     [not found] ` <1525940985-30428-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-10  8:29   ` [DPU PATCH 03/11] drm/msm/dpu: add MDSS top level driver for dpu Rajesh Yadav
     [not found]     ` <1525940985-30428-4-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-10 14:14       ` Sean Paul
2018-05-10 16:56       ` Jordan Crouse [this message]
2018-05-10  8:29   ` [DPU PATCH 05/11] drm/msm/dpu: update dpu sub-block offsets wrt dpu base address Rajesh Yadav
2018-05-10 15:02     ` Sean Paul
2018-05-10  8:29   ` [DPU PATCH 06/11] drm/msm/dpu: use runtime_pm calls on dpu device Rajesh Yadav
     [not found]     ` <1525940985-30428-7-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-10 15:04       ` Sean Paul
2018-05-10  8:29   ` [DPU PATCH 07/11] drm/msm/dpu: remove clock management code from dpu_power_handle Rajesh Yadav
     [not found]     ` <1525940985-30428-8-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-10 15:21       ` Sean Paul
2018-05-10  8:29   ` [DPU PATCH 08/11] drm/msm/dpu: remove power " Rajesh Yadav
     [not found]     ` <1525940985-30428-9-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-10 15:22       ` Sean Paul
2018-05-10  8:29   ` [DPU PATCH 09/11] drm/msm/dp: remove dpu_power_handle calls from dp driver Rajesh Yadav
     [not found]     ` <1525940985-30428-10-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-10 15:23       ` Sean Paul
2018-05-10  8:29 ` [DPU PATCH 10/11] drm/msm/dpu: use runtime_pm calls in dpu_dbg Rajesh Yadav
     [not found]   ` <1525940985-30428-11-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-10 15:26     ` Sean Paul
2018-05-10  8:29 ` [DPU PATCH 11/11] drm/msm/dpu: move dpu_power_handle to dpu folder Rajesh Yadav
     [not found]   ` <1525940985-30428-12-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-10 15:30     ` Sean Paul

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=20180510165601.GD4995@jcrouse-lnx.qualcomm.com \
    --to=jcrouse-sgv2jx0feol9jmxxk+q4oq@public.gmane.org \
    --cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=hoegsberg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
    --cc=linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
    --cc=seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.