Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e4e3ba9 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-tda998x-3.12' of git://ftp.arm.linux.org.uk/~rmk/linux-cubox into drm-next

This adds support for the Armada 510 display subsystem found on the
Marvell Dove devices.  This IP is re-used across several different Marvell
SoCs with various tweaks, and this driver has been structured to allow
the other IPs to re-use the bulk of this code; further work in this area
is expected from interested parties.

This has been extensively tested on the SolidRun Cubox platform and
appears to work well there.

[airlied: update for api changes merged previous to this]
parents 5bdebb18 585b691e
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -225,6 +225,8 @@ source "drivers/gpu/drm/mgag200/Kconfig"


source "drivers/gpu/drm/cirrus/Kconfig"
source "drivers/gpu/drm/cirrus/Kconfig"


source "drivers/gpu/drm/armada/Kconfig"

source "drivers/gpu/drm/rcar-du/Kconfig"
source "drivers/gpu/drm/rcar-du/Kconfig"


source "drivers/gpu/drm/shmobile/Kconfig"
source "drivers/gpu/drm/shmobile/Kconfig"
+1 −0
Original line number Original line Diff line number Diff line
@@ -49,6 +49,7 @@ obj-$(CONFIG_DRM_EXYNOS) +=exynos/
obj-$(CONFIG_DRM_GMA500) += gma500/
obj-$(CONFIG_DRM_GMA500) += gma500/
obj-$(CONFIG_DRM_UDL) += udl/
obj-$(CONFIG_DRM_UDL) += udl/
obj-$(CONFIG_DRM_AST) += ast/
obj-$(CONFIG_DRM_AST) += ast/
obj-$(CONFIG_DRM_ARMADA) += armada/
obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
obj-$(CONFIG_DRM_OMAP)	+= omapdrm/
obj-$(CONFIG_DRM_OMAP)	+= omapdrm/
+24 −0
Original line number Original line Diff line number Diff line
config DRM_ARMADA
	tristate "DRM support for Marvell Armada SoCs"
	depends on DRM && HAVE_CLK
	select FB_CFB_FILLRECT
	select FB_CFB_COPYAREA
	select FB_CFB_IMAGEBLIT
	select DRM_KMS_HELPER
	help
	  Support the "LCD" controllers found on the Marvell Armada 510
	  devices.  There are two controllers on the device, each controller
	  supports graphics and video overlays.

	  This driver provides no built-in acceleration; acceleration is
	  performed by other IP found on the SoC.  This driver provides
	  kernel mode setting and buffer management to userspace.

config DRM_ARMADA_TDA1998X
	bool "Support TDA1998X HDMI output"
	depends on DRM_ARMADA != n
	depends on I2C && DRM_I2C_NXP_TDA998X = y
	default y
	help
	  Support the TDA1998x HDMI output device found on the Solid-Run
	  CuBox.
+7 −0
Original line number Original line Diff line number Diff line
armada-y	:= armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
		   armada_gem.o armada_output.o armada_overlay.o \
		   armada_slave.o
armada-y	+= armada_510.o
armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o

obj-$(CONFIG_DRM_ARMADA) := armada.o
+87 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2012 Russell King
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Armada 510 (aka Dove) variant support
 */
#include <linux/clk.h>
#include <linux/io.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include "armada_crtc.h"
#include "armada_drm.h"
#include "armada_hw.h"

static int armada510_init(struct armada_private *priv, struct device *dev)
{
	priv->extclk[0] = devm_clk_get(dev, "ext_ref_clk_1");

	if (IS_ERR(priv->extclk[0]) && PTR_ERR(priv->extclk[0]) == -ENOENT)
		priv->extclk[0] = ERR_PTR(-EPROBE_DEFER);

	return PTR_RET(priv->extclk[0]);
}

static int armada510_crtc_init(struct armada_crtc *dcrtc)
{
	/* Lower the watermark so to eliminate jitter at higher bandwidths */
	armada_updatel(0x20, (1 << 11) | 0xff, dcrtc->base + LCD_CFG_RDREG4F);
	return 0;
}

/*
 * Armada510 specific SCLK register selection.
 * This gets called with sclk = NULL to test whether the mode is
 * supportable, and again with sclk != NULL to set the clocks up for
 * that.  The former can return an error, but the latter is expected
 * not to.
 *
 * We currently are pretty rudimentary here, always selecting
 * EXT_REF_CLK_1 for LCD0 and erroring LCD1.  This needs improvement!
 */
static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
	const struct drm_display_mode *mode, uint32_t *sclk)
{
	struct armada_private *priv = dcrtc->crtc.dev->dev_private;
	struct clk *clk = priv->extclk[0];
	int ret;

	if (dcrtc->num == 1)
		return -EINVAL;

	if (IS_ERR(clk))
		return PTR_ERR(clk);

	if (dcrtc->clk != clk) {
		ret = clk_prepare_enable(clk);
		if (ret)
			return ret;
		dcrtc->clk = clk;
	}

	if (sclk) {
		uint32_t rate, ref, div;

		rate = mode->clock * 1000;
		ref = clk_round_rate(clk, rate);
		div = DIV_ROUND_UP(ref, rate);
		if (div < 1)
			div = 1;

		clk_set_rate(clk, ref);
		*sclk = div | SCLK_510_EXTCLK1;
	}

	return 0;
}

const struct armada_variant armada510_ops = {
	.has_spu_adv_reg = true,
	.spu_adv_reg = ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND,
	.init = armada510_init,
	.crtc_init = armada510_crtc_init,
	.crtc_compute_clock = armada510_crtc_compute_clock,
};
Loading