Commit 29a1da27 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm/tegra/for-4.21-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next



drm/tegra: Changes for v4.21-rc1

These changes contain a couple of minor fixes for host1x and the Falcon
library in Tegra DRM. There are also a couple of missing pieces that
finally enable support for host1x, VIC and display on Tegra194. I've
also added a patch that enables audio over HDMI using the SOR which has
been tested, and works, on both Tegra186 and Tegra194.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Thierry Reding <thierry.reding@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181207134712.32683-1-thierry.reding@gmail.com
parents e7df065a 180b46ec
Loading
Loading
Loading
Loading
+22 −16
Original line number Diff line number Diff line
@@ -1978,6 +1978,23 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
	return IRQ_HANDLED;
}

static bool tegra_dc_has_window_groups(struct tegra_dc *dc)
{
	unsigned int i;

	if (!dc->soc->wgrps)
		return true;

	for (i = 0; i < dc->soc->num_wgrps; i++) {
		const struct tegra_windowgroup_soc *wgrp = &dc->soc->wgrps[i];

		if (wgrp->dc == dc->pipe && wgrp->num_windows > 0)
			return true;
	}

	return false;
}

static int tegra_dc_init(struct host1x_client *client)
{
	struct drm_device *drm = dev_get_drvdata(client->parent);
@@ -1993,22 +2010,8 @@ static int tegra_dc_init(struct host1x_client *client)
	 * assign a primary plane to them, which in turn will cause KMS to
	 * crash.
	 */
	if (dc->soc->wgrps) {
		bool has_wgrps = false;
		unsigned int i;

		for (i = 0; i < dc->soc->num_wgrps; i++) {
			const struct tegra_windowgroup_soc *wgrp = &dc->soc->wgrps[i];

			if (wgrp->dc == dc->pipe && wgrp->num_windows > 0) {
				has_wgrps = true;
				break;
			}
		}

		if (!has_wgrps)
	if (!tegra_dc_has_window_groups(dc))
		return 0;
	}

	dc->syncpt = host1x_syncpt_request(client, flags);
	if (!dc->syncpt)
@@ -2094,6 +2097,9 @@ static int tegra_dc_exit(struct host1x_client *client)
	struct tegra_dc *dc = host1x_client_to_dc(client);
	int err;

	if (!tegra_dc_has_window_groups(dc))
		return 0;

	devm_free_irq(dc->dev, dc->irq, dc);

	err = tegra_dc_rgb_exit(dc);
+1 −0
Original line number Diff line number Diff line
@@ -1274,6 +1274,7 @@ static const struct of_device_id host1x_drm_subdevs[] = {
	{ .compatible = "nvidia,tegra194-display", },
	{ .compatible = "nvidia,tegra194-dc", },
	{ .compatible = "nvidia,tegra194-sor", },
	{ .compatible = "nvidia,tegra194-vic", },
	{ /* sentinel */ }
};

+11 −3
Original line number Diff line number Diff line
@@ -141,9 +141,9 @@ int falcon_load_firmware(struct falcon *falcon)
	/* allocate iova space for the firmware */
	falcon->firmware.vaddr = falcon->ops->alloc(falcon, firmware->size,
						    &falcon->firmware.paddr);
	if (!falcon->firmware.vaddr) {
		dev_err(falcon->dev, "dma memory mapping failed\n");
		return -ENOMEM;
	if (IS_ERR(falcon->firmware.vaddr)) {
		dev_err(falcon->dev, "DMA memory mapping failed\n");
		return PTR_ERR(falcon->firmware.vaddr);
	}

	/* copy firmware image into local area. this also ensures endianness */
@@ -197,11 +197,19 @@ void falcon_exit(struct falcon *falcon)
int falcon_boot(struct falcon *falcon)
{
	unsigned long offset;
	u32 value;
	int err;

	if (!falcon->firmware.vaddr)
		return -EINVAL;

	err = readl_poll_timeout(falcon->regs + FALCON_DMACTL, value,
				 (value & (FALCON_DMACTL_IMEM_SCRUBBING |
					   FALCON_DMACTL_DMEM_SCRUBBING)) == 0,
				 10, 10000);
	if (err < 0)
		return err;

	falcon_writel(falcon, 0, FALCON_DMACTL);

	/* setup the address of the binary data so Falcon can access it later */
+46 −2
Original line number Diff line number Diff line
@@ -742,7 +742,9 @@ static const struct host1x_client_ops tegra_display_hub_ops = {

static int tegra_display_hub_probe(struct platform_device *pdev)
{
	struct device_node *child = NULL;
	struct tegra_display_hub *hub;
	struct clk *clk;
	unsigned int i;
	int err;

@@ -801,6 +803,34 @@ static int tegra_display_hub_probe(struct platform_device *pdev)
			return err;
	}

	hub->num_heads = of_get_child_count(pdev->dev.of_node);

	hub->clk_heads = devm_kcalloc(&pdev->dev, hub->num_heads, sizeof(clk),
				      GFP_KERNEL);
	if (!hub->clk_heads)
		return -ENOMEM;

	for (i = 0; i < hub->num_heads; i++) {
		child = of_get_next_child(pdev->dev.of_node, child);
		if (!child) {
			dev_err(&pdev->dev, "failed to find node for head %u\n",
				i);
			return -ENODEV;
		}

		clk = devm_get_clk_from_child(&pdev->dev, child, "dc");
		if (IS_ERR(clk)) {
			dev_err(&pdev->dev, "failed to get clock for head %u\n",
				i);
			of_node_put(child);
			return PTR_ERR(clk);
		}

		hub->clk_heads[i] = clk;
	}

	of_node_put(child);

	/* XXX: enable clock across reset? */
	err = reset_control_assert(hub->rst);
	if (err < 0)
@@ -840,12 +870,16 @@ static int tegra_display_hub_remove(struct platform_device *pdev)
static int __maybe_unused tegra_display_hub_suspend(struct device *dev)
{
	struct tegra_display_hub *hub = dev_get_drvdata(dev);
	unsigned int i = hub->num_heads;
	int err;

	err = reset_control_assert(hub->rst);
	if (err < 0)
		return err;

	while (i--)
		clk_disable_unprepare(hub->clk_heads[i]);

	clk_disable_unprepare(hub->clk_hub);
	clk_disable_unprepare(hub->clk_dsc);
	clk_disable_unprepare(hub->clk_disp);
@@ -856,6 +890,7 @@ static int __maybe_unused tegra_display_hub_suspend(struct device *dev)
static int __maybe_unused tegra_display_hub_resume(struct device *dev)
{
	struct tegra_display_hub *hub = dev_get_drvdata(dev);
	unsigned int i;
	int err;

	err = clk_prepare_enable(hub->clk_disp);
@@ -870,13 +905,22 @@ static int __maybe_unused tegra_display_hub_resume(struct device *dev)
	if (err < 0)
		goto disable_dsc;

	for (i = 0; i < hub->num_heads; i++) {
		err = clk_prepare_enable(hub->clk_heads[i]);
		if (err < 0)
			goto disable_heads;
	}

	err = reset_control_deassert(hub->rst);
	if (err < 0)
		goto disable_hub;
		goto disable_heads;

	return 0;

disable_hub:
disable_heads:
	while (i--)
		clk_disable_unprepare(hub->clk_heads[i]);

	clk_disable_unprepare(hub->clk_hub);
disable_dsc:
	clk_disable_unprepare(hub->clk_dsc);
+3 −0
Original line number Diff line number Diff line
@@ -49,6 +49,9 @@ struct tegra_display_hub {
	struct clk *clk_hub;
	struct reset_control *rst;

	unsigned int num_heads;
	struct clk **clk_heads;

	const struct tegra_display_hub_soc *soc;
	struct tegra_windowgroup *wgrps;
};
Loading