// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2015 Broadcom
*/
/**
* DOC: VC4 CRTC module
*
* In VC4, the Pixel Valve is what most closely corresponds to the
* DRM's concept of a CRTC. The PV generates video timings from the
* encoder's clock plus its configuration. It pulls scaled pixels from
* the HVS at that timing, and feeds it to the encoder.
*
* However, the DRM CRTC also collects the configuration of all the
* DRM planes attached to it. As a result, the CRTC is also
* responsible for writing the display list for the HVS channel that
* the CRTC will use.
*
* The 2835 has 3 different pixel valves. pv0 in the audio power
* domain feeds DSI0 or DPI, while pv1 feeds DS1 or SMI. pv2 in the
* image domain can feed either HDMI or the SDTV controller. The
* pixel valve chooses from the CPRMAN clocks (HSM for HDMI, VEC for
* SDTV, etc.) according to which output type is chosen in the mux.
*
* For power management, the pixel valve's registers are all clocked
* by the AXI clock, while the timings and FIFOs make use of the
* output-specific clock. Since the encoders also directly consume
* the CPRMAN clocks, and know what timings they need, they are the
* ones that set the clock.
*/
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_drv.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
#include "vc4_drv.h"
#include "vc4_hdmi.h"
#include "vc4_regs.h"
#define HVS_FIFO_LATENCY_PIX 6
#define CRTC_WRITE(offset, val) \
do { \
kunit_fail_current_test("Accessing a register in a unit test!\n"); \
writel(val, vc4_crtc->regs + (offset)); \
} while (0)
#define CRTC_READ(offset) \
({ \
kunit_fail_current_test("Accessing a register in a unit test!\n"); \
readl(vc4_crtc->regs + (offset)); \
})
static const struct debugfs_reg32 crtc_regs[] = {
VC4_REG32(PV_CONTROL),
VC4_REG32(PV_V_CONTROL),
VC4_REG32(PV_VSYNCD_EVEN),
VC4_REG32(PV_HORZA),
VC4_REG32(PV_HORZB),
VC4_REG32(PV_VERTA