linux_dsm_epyc7002/drivers/gpu/drm/armada/armada_510.c

159 lines
3.6 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2012 Russell King
*
* Armada 510 (aka Dove) variant support
*/
#include <linux/clk.h>
#include <linux/io.h>
drm: Split out drm_probe_helper.h Having the probe helper stuff (which pretty much everyone needs) in the drm_crtc_helper.h file (which atomic drivers should never need) is confusing. Split them out. To make sure I actually achieved the goal here I went through all drivers. And indeed, all atomic drivers are now free of drm_crtc_helper.h includes. v2: Make it compile. There was so much compile fail on arm drivers that I figured I'll better not include any of the acks on v1. v3: Massive rebase because i915 has lost a lot of drmP.h includes, but not all: Through drm_crtc_helper.h > drm_modeset_helper.h -> drmP.h there was still one, which this patch largely removes. Which means rolling out lots more includes all over. This will also conflict with ongoing drmP.h cleanup by others I expect. v3: Rebase on top of atomic bochs. v4: Review from Laurent for bridge/rcar/omap/shmob/core bits: - (re)move some of the added includes, use the better include files in other places (all suggested from Laurent adopted unchanged). - sort alphabetically v5: Actually try to sort them, and while at it, sort all the ones I touch. v6: Rebase onto i915 changes. v7: Rebase once more. Acked-by: Harry Wentland <harry.wentland@amd.com> Acked-by: Sam Ravnborg <sam@ravnborg.org> Cc: Sam Ravnborg <sam@ravnborg.org> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Acked-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> Acked-by: Jani Nikula <jani.nikula@intel.com> Acked-by: Neil Armstrong <narmstrong@baylibre.com> Acked-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> Acked-by: CK Hu <ck.hu@mediatek.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Sam Ravnborg <sam@ravnborg.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Liviu Dudau <liviu.dudau@arm.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Cc: linux-arm-kernel@lists.infradead.org Cc: virtualization@lists.linux-foundation.org Cc: etnaviv@lists.freedesktop.org Cc: linux-samsung-soc@vger.kernel.org Cc: intel-gfx@lists.freedesktop.org Cc: linux-mediatek@lists.infradead.org Cc: linux-amlogic@lists.infradead.org Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: nouveau@lists.freedesktop.org Cc: spice-devel@lists.freedesktop.org Cc: amd-gfx@lists.freedesktop.org Cc: linux-renesas-soc@vger.kernel.org Cc: linux-rockchip@lists.infradead.org Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-tegra@vger.kernel.org Cc: xen-devel@lists.xen.org Link: https://patchwork.freedesktop.org/patch/msgid/20190117210334.13234-1-daniel.vetter@ffwll.ch
2019-01-18 04:03:34 +07:00
#include <drm/drm_probe_helper.h>
#include "armada_crtc.h"
#include "armada_drm.h"
#include "armada_hw.h"
struct armada510_variant_data {
struct clk *clks[4];
struct clk *sel_clk;
};
static int armada510_crtc_init(struct armada_crtc *dcrtc, struct device *dev)
{
struct armada510_variant_data *v;
struct clk *clk;
int idx;
v = devm_kzalloc(dev, sizeof(*v), GFP_KERNEL);
if (!v)
return -ENOMEM;
dcrtc->variant_data = v;
if (dev->of_node) {
struct property *prop;
const char *s;
of_property_for_each_string(dev->of_node, "clock-names", prop,
s) {
if (!strcmp(s, "ext_ref_clk0"))
idx = 0;
else if (!strcmp(s, "ext_ref_clk1"))
idx = 1;
else if (!strcmp(s, "plldivider"))
idx = 2;
else if (!strcmp(s, "axibus"))
idx = 3;
else
continue;
clk = devm_clk_get(dev, s);
if (IS_ERR(clk))
return PTR_ERR(clk) == -ENOENT ? -EPROBE_DEFER :
PTR_ERR(clk);
v->clks[idx] = clk;
}
} else {
clk = devm_clk_get(dev, "ext_ref_clk1");
if (IS_ERR(clk))
return PTR_ERR(clk) == -ENOENT ? -EPROBE_DEFER :
PTR_ERR(clk);
v->clks[1] = clk;
}
/*
* Lower the watermark so to eliminate jitter at higher bandwidths.
* Disable SRAM read wait state to avoid system hang with external
* clock.
*/
armada_updatel(CFG_DMA_WM(0x20), CFG_SRAM_WAIT | CFG_DMA_WM_MASK,
dcrtc->base + LCD_CFG_RDREG4F);
/* Initialise SPU register */
writel_relaxed(ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND,
dcrtc->base + LCD_SPU_ADV_REG);
return 0;
}
static const u32 armada510_clk_sels[] = {
SCLK_510_EXTCLK0,
SCLK_510_EXTCLK1,
SCLK_510_PLL,
SCLK_510_AXI,
};
static const struct armada_clocking_params armada510_clocking = {
/* HDMI requires -0.6%..+0.5% */
.permillage_min = 994,
.permillage_max = 1005,
.settable = BIT(0) | BIT(1),
.div_max = SCLK_510_INT_DIV_MASK,
};
/*
* 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.
*/
static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
const struct drm_display_mode *mode, uint32_t *sclk)
{
struct armada510_variant_data *v = dcrtc->variant_data;
unsigned long desired_khz = mode->crtc_clock;
struct armada_clk_result res;
int ret, idx;
idx = armada_crtc_select_clock(dcrtc, &res, &armada510_clocking,
v->clks, ARRAY_SIZE(v->clks),
desired_khz);
if (idx < 0)
return idx;
ret = clk_prepare_enable(res.clk);
if (ret)
return ret;
if (sclk) {
clk_set_rate(res.clk, res.desired_clk_hz);
*sclk = res.div | armada510_clk_sels[idx];
/* We are now using this clock */
v->sel_clk = res.clk;
swap(dcrtc->clk, res.clk);
}
clk_disable_unprepare(res.clk);
return 0;
}
static void armada510_crtc_disable(struct armada_crtc *dcrtc)
{
if (dcrtc->clk) {
clk_disable_unprepare(dcrtc->clk);
dcrtc->clk = NULL;
}
}
static void armada510_crtc_enable(struct armada_crtc *dcrtc,
const struct drm_display_mode *mode)
{
struct armada510_variant_data *v = dcrtc->variant_data;
if (!dcrtc->clk && v->sel_clk) {
if (!WARN_ON(clk_prepare_enable(v->sel_clk)))
dcrtc->clk = v->sel_clk;
}
}
const struct armada_variant armada510_ops = {
.has_spu_adv_reg = true,
.init = armada510_crtc_init,
.compute_clock = armada510_crtc_compute_clock,
.disable = armada510_crtc_disable,
.enable = armada510_crtc_enable,
};