mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-25 11:09:59 +07:00
42bac89a17
The MCDE DSI link hardware which is modeled like a bridge in DRM, connected further to the panel bridge, creating a pipeline. We have been using the .pre_enable(), .enable(), .disable() and .post_disable() callbacks from the bridge to set this up in a chained manner: first the display controller goes online and then in successive order each bridge in the pipeline. Inside DRM it works like this: drm_atomic_helper_commit_tail() drm_atomic_helper_commit_modeset_enables() struct drm_crtc_helper_funcs .atomic_enable() struct drm_simple_display_pipe_funcs .enable() MCDE display enable call drm_atomic_bridge_chain_enable() struct drm_bridge_funcs .pre_enable() mcde_dsi_bridge_pre_enable() panel_bridge_pre_enable() struct drm_panel_funcs .prepare() struct drm_bridge_funcs .enable() mcde_dsi_bridge_enable() panel_bridge_enable() struct drm_panel_funcs .enable() A similar sequence is executed for disabling. Unfortunately this is not what the hardware needs: at a certain stage in the enablement of the display controller the DSI link needs to come up to support video mode, else something (like a FIFO flow) locks up the hardware and we never get picture. Fix this by simply leaving the pre|enable and post|disable callbacks unused, and establish two cross-calls from the display controller to bring up the DSI link at the right place in the display bring-up sequence and vice versa in the shutdown sequence. For command mode displays, it works just fine to also enable the display flow early. The only time we hold it back right now is in one-shot mode, on-demand display updates. When combined with the previous patch and some patches for the S6E63M0 display controller to support DSI mode, this gives working display on the Samsung GT-I8190 (Golden) phone. It has also been tested working on the Samsung GT-S7710 (Skomer) phone. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: newbytee@protonmail.com Cc: Stephan Gerhold <stephan@gerhold.net> Link: https://patchwork.freedesktop.org/patch/msgid/20200808223122.1492124-4-linus.walleij@linaro.org
109 lines
3.2 KiB
C
109 lines
3.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
/*
|
|
* Copyright (C) 2018 Linus Walleij <linus.walleij@linaro.org>
|
|
* Parts of this file were based on the MCDE driver by Marcus Lorentzon
|
|
* (C) ST-Ericsson SA 2013
|
|
*/
|
|
#include <drm/drm_simple_kms_helper.h>
|
|
|
|
#ifndef _MCDE_DRM_H_
|
|
#define _MCDE_DRM_H_
|
|
|
|
/* Shared basic registers */
|
|
#define MCDE_CR 0x00000000
|
|
#define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_SHIFT 0
|
|
#define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_MASK 0x0000003F
|
|
#define MCDE_CR_IFIFOCTRLEN BIT(15)
|
|
#define MCDE_CR_UFRECOVERY_MODE_V422 BIT(16)
|
|
#define MCDE_CR_WRAP_MODE_V422_SHIFT BIT(17)
|
|
#define MCDE_CR_AUTOCLKG_EN BIT(30)
|
|
#define MCDE_CR_MCDEEN BIT(31)
|
|
|
|
#define MCDE_CONF0 0x00000004
|
|
#define MCDE_CONF0_SYNCMUX0 BIT(0)
|
|
#define MCDE_CONF0_SYNCMUX1 BIT(1)
|
|
#define MCDE_CONF0_SYNCMUX2 BIT(2)
|
|
#define MCDE_CONF0_SYNCMUX3 BIT(3)
|
|
#define MCDE_CONF0_SYNCMUX4 BIT(4)
|
|
#define MCDE_CONF0_SYNCMUX5 BIT(5)
|
|
#define MCDE_CONF0_SYNCMUX6 BIT(6)
|
|
#define MCDE_CONF0_SYNCMUX7 BIT(7)
|
|
#define MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT 12
|
|
#define MCDE_CONF0_IFIFOCTRLWTRMRKLVL_MASK 0x00007000
|
|
#define MCDE_CONF0_OUTMUX0_SHIFT 16
|
|
#define MCDE_CONF0_OUTMUX0_MASK 0x00070000
|
|
#define MCDE_CONF0_OUTMUX1_SHIFT 19
|
|
#define MCDE_CONF0_OUTMUX1_MASK 0x00380000
|
|
#define MCDE_CONF0_OUTMUX2_SHIFT 22
|
|
#define MCDE_CONF0_OUTMUX2_MASK 0x01C00000
|
|
#define MCDE_CONF0_OUTMUX3_SHIFT 25
|
|
#define MCDE_CONF0_OUTMUX3_MASK 0x0E000000
|
|
#define MCDE_CONF0_OUTMUX4_SHIFT 28
|
|
#define MCDE_CONF0_OUTMUX4_MASK 0x70000000
|
|
|
|
#define MCDE_SSP 0x00000008
|
|
#define MCDE_AIS 0x00000100
|
|
#define MCDE_IMSCERR 0x00000110
|
|
#define MCDE_RISERR 0x00000120
|
|
#define MCDE_MISERR 0x00000130
|
|
#define MCDE_SISERR 0x00000140
|
|
|
|
enum mcde_flow_mode {
|
|
/* One-shot mode: flow stops after one frame */
|
|
MCDE_COMMAND_ONESHOT_FLOW,
|
|
/* Command mode with tearing effect (TE) IRQ sync */
|
|
MCDE_COMMAND_TE_FLOW,
|
|
/*
|
|
* Command mode with bus turn-around (BTA) and tearing effect
|
|
* (TE) IRQ sync.
|
|
*/
|
|
MCDE_COMMAND_BTA_TE_FLOW,
|
|
/* Video mode with tearing effect (TE) sync IRQ */
|
|
MCDE_VIDEO_TE_FLOW,
|
|
/* Video mode with the formatter itself as sync source */
|
|
MCDE_VIDEO_FORMATTER_FLOW,
|
|
};
|
|
|
|
struct mcde {
|
|
struct drm_device drm;
|
|
struct device *dev;
|
|
struct drm_panel *panel;
|
|
struct drm_bridge *bridge;
|
|
struct drm_connector *connector;
|
|
struct drm_simple_display_pipe pipe;
|
|
struct mipi_dsi_device *mdsi;
|
|
s16 stride;
|
|
enum mcde_flow_mode flow_mode;
|
|
unsigned int flow_active;
|
|
spinlock_t flow_lock; /* Locks the channel flow control */
|
|
|
|
void __iomem *regs;
|
|
|
|
struct clk *mcde_clk;
|
|
struct clk *lcd_clk;
|
|
struct clk *hdmi_clk;
|
|
|
|
struct regulator *epod;
|
|
struct regulator *vana;
|
|
};
|
|
|
|
#define to_mcde(dev) container_of(dev, struct mcde, drm)
|
|
|
|
static inline bool mcde_flow_is_video(struct mcde *mcde)
|
|
{
|
|
return (mcde->flow_mode == MCDE_VIDEO_TE_FLOW ||
|
|
mcde->flow_mode == MCDE_VIDEO_FORMATTER_FLOW);
|
|
}
|
|
|
|
bool mcde_dsi_irq(struct mipi_dsi_device *mdsi);
|
|
void mcde_dsi_te_request(struct mipi_dsi_device *mdsi);
|
|
void mcde_dsi_enable(struct drm_bridge *bridge);
|
|
void mcde_dsi_disable(struct drm_bridge *bridge);
|
|
extern struct platform_driver mcde_dsi_driver;
|
|
|
|
void mcde_display_irq(struct mcde *mcde);
|
|
void mcde_display_disable_irqs(struct mcde *mcde);
|
|
int mcde_display_init(struct drm_device *drm);
|
|
|
|
#endif /* _MCDE_DRM_H_ */
|