Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
config DRM_MCDE
tristate "DRM Support for ST-Ericsson MCDE (Multichannel Display Engine)"
depends on DRM
depends on CMA
depends on ARM || COMPILE_TEST
depends on OF
depends on COMMON_CLK
select MFD_SYSCON
select DRM_CLIENT_SELECTION
select DRM_MIPI_DSI
select DRM_BRIDGE
select DRM_PANEL_BRIDGE
select DRM_KMS_HELPER
select DRM_GEM_DMA_HELPER
help
Choose this option for DRM support for the ST-Ericsson MCDE
Multi-Channel Display Engine.
If M is selected the module will be called mcde_drm.
@@ -0,0 +1,3 @@
mcde_drm-y += mcde_drv.o mcde_dsi.o mcde_clk_div.o mcde_display.o
obj-$(CONFIG_DRM_MCDE) += mcde_drm.o
@@ -0,0 +1,196 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/regulator/consumer.h>
#include "mcde_drm.h"
#include "mcde_display_regs.h"
/* The MCDE internal clock dividers for FIFO A and B */
struct mcde_clk_div {
struct clk_hw hw;
struct mcde *mcde;
u32 cr;
u32 cr_div;
};
static int mcde_clk_div_enable(struct clk_hw *hw)
{
struct mcde_clk_div *cdiv = container_of(hw, struct mcde_clk_div, hw);
struct mcde *mcde = cdiv->mcde;
u32 val;
spin_lock(&mcde->fifo_crx1_lock);
val = readl(mcde->regs + cdiv->cr);
/*
* Select the PLL72 (LCD) clock as parent
* FIXME: implement other parents.
*/
val &= ~MCDE_CRX1_CLKSEL_MASK;
val |= MCDE_CRX1_CLKSEL_CLKPLL72 << MCDE_CRX1_CLKSEL_SHIFT;
/* Internal clock */
val |= MCDE_CRA1_CLKTYPE_TVXCLKSEL1;
/* Clear then set the divider */
val &= ~(MCDE_CRX1_BCD | MCDE_CRX1_PCD_MASK);
val |= cdiv->cr_div;
writel(val, mcde->regs + cdiv->cr);
spin_unlock(&mcde->fifo_crx1_lock);
return 0;
}
static int mcde_clk_div_choose_div(struct clk_hw *hw, unsigned long rate,
unsigned long *prate, bool set_parent)
{
int best_div = 1, div;
struct clk_hw *parent = clk_hw_get_parent(hw);
unsigned long best_prate = 0;
unsigned long best_diff = ~0ul;
int max_div = (1 << MCDE_CRX1_PCD_BITS) - 1;
for (div = 1; div < max_div; div++) {
unsigned long this_prate, div_rate, diff;
if (set_parent)
this_prate = clk_hw_round_rate(parent, rate * div);
else
this_prate = *prate;
div_rate = DIV_ROUND_UP_ULL(this_prate, div);
diff = abs(rate - div_rate);
if (diff < best_diff) {
best_div = div;
best_diff = diff;
best_prate = this_prate;
}
}
*prate = best_prate;
return best_div;
}
static int mcde_clk_div_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
int div = mcde_clk_div_choose_div(hw, req->rate,
&req->best_parent_rate, true);
req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, div);
return 0;
}
static unsigned long mcde_clk_div_recalc_rate(struct clk_hw *hw,
unsigned long prate)
{
struct mcde_clk_div *cdiv = container_of(hw, struct mcde_clk_div, hw);
struct mcde *mcde = cdiv->mcde;
u32 cr;
int div;
/*
* If the MCDE is not powered we can't access registers.
* It will come up with 0 in the divider register bits, which
* means "divide by 2".
*/
if (!regulator_is_enabled(mcde->epod))
return DIV_ROUND_UP_ULL(prate, 2);
cr = readl(mcde->regs + cdiv->cr);
if (cr & MCDE_CRX1_BCD)
return prate;
/* 0 in the PCD means "divide by 2", 1 means "divide by 3" etc */
div = cr & MCDE_CRX1_PCD_MASK;
div += 2;
return DIV_ROUND_UP_ULL(prate, div);
}
static int mcde_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long prate)
{
struct mcde_clk_div *cdiv = container_of(hw, struct mcde_clk_div, hw);
int div = mcde_clk_div_choose_div(hw, rate, &prate, false);
u32 cr = 0;
/*
* We cache the CR bits to set the divide in the state so that
* we can call this before we can even write to the hardware.
*/
if (div == 1) {
/* Bypass clock divider */
cr |= MCDE_CRX1_BCD;
} else {
div -= 2;
cr |= div & MCDE_CRX1_PCD_MASK;
}
cdiv->cr_div = cr;
return 0;
}
static const struct clk_ops mcde_clk_div_ops = {
.enable = mcde_clk_div_enable,
.recalc_rate = mcde_clk_div_recalc_rate,
.determine_rate = mcde_clk_div_determine_rate,
.set_rate = mcde_clk_div_set_rate,
};
int mcde_init_clock_divider(struct mcde *mcde)
{
struct device *dev = mcde->dev;
struct mcde_clk_div *fifoa;
struct mcde_clk_div *fifob;
const char *parent_name;
struct clk_init_data fifoa_init = {
.name = "fifoa",
.ops = &mcde_clk_div_ops,
.parent_names = &parent_name,
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
};
struct clk_init_data fifob_init = {
.name = "fifob",
.ops = &mcde_clk_div_ops,
.parent_names = &parent_name,
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
};
int ret;
spin_lock_init(&mcde->fifo_crx1_lock);
parent_name = __clk_get_name(mcde->lcd_clk);
/* Allocate 2 clocks */
fifoa = devm_kzalloc(dev, sizeof(*fifoa), GFP_KERNEL);
if (!fifoa)
return -ENOMEM;
fifob = devm_kzalloc(dev, sizeof(*fifob), GFP_KERNEL);
if (!fifob)
return -ENOMEM;
fifoa->mcde = mcde;
fifoa->cr = MCDE_CRA1;
fifoa->hw.init = &fifoa_init;
ret = devm_clk_hw_register(dev, &fifoa->hw);
if (ret) {
dev_err(dev, "error registering FIFO A clock divider\n");
return ret;
}
mcde->fifoa_clk = fifoa->hw.clk;
fifob->mcde = mcde;
fifob->cr = MCDE_CRB1;
fifob->hw.init = &fifob_init;
ret = devm_clk_hw_register(dev, &fifob->hw);
if (ret) {
dev_err(dev, "error registering FIFO B clock divider\n");
return ret;
}
mcde->fifob_clk = fifob->hw.clk;
return 0;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,605 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __DRM_MCDE_DISPLAY_REGS
#define __DRM_MCDE_DISPLAY_REGS
/* PP (pixel processor) interrupts */
#define MCDE_IMSCPP 0x00000104
#define MCDE_RISPP 0x00000114
#define MCDE_MISPP 0x00000124
#define MCDE_SISPP 0x00000134
#define MCDE_PP_VCMPA BIT(0)
#define MCDE_PP_VCMPB BIT(1)
#define MCDE_PP_VSCC0 BIT(2)
#define MCDE_PP_VSCC1 BIT(3)
#define MCDE_PP_VCMPC0 BIT(4)
#define MCDE_PP_VCMPC1 BIT(5)
#define MCDE_PP_ROTFD_A BIT(6)
#define MCDE_PP_ROTFD_B BIT(7)
/* Overlay interrupts */
#define MCDE_IMSCOVL 0x00000108
#define MCDE_RISOVL 0x00000118
#define MCDE_MISOVL 0x00000128
#define MCDE_SISOVL 0x00000138
/* Channel interrupts */
#define MCDE_IMSCCHNL 0x0000010C
#define MCDE_RISCHNL 0x0000011C
#define MCDE_MISCHNL 0x0000012C
#define MCDE_SISCHNL 0x0000013C
/* X = 0..9 */
#define MCDE_EXTSRCXA0 0x00000200
#define MCDE_EXTSRCXA0_GROUPOFFSET 0x20
#define MCDE_EXTSRCXA0_BASEADDRESS0_SHIFT 3
#define MCDE_EXTSRCXA0_BASEADDRESS0_MASK 0xFFFFFFF8
#define MCDE_EXTSRCXA1 0x00000204
#define MCDE_EXTSRCXA1_GROUPOFFSET 0x20
#define MCDE_EXTSRCXA1_BASEADDRESS1_SHIFT 3
#define MCDE_EXTSRCXA1_BASEADDRESS1_MASK 0xFFFFFFF8
/* External sources 0..9 */
#define MCDE_EXTSRC0CONF 0x0000020C
#define MCDE_EXTSRC1CONF 0x0000022C
#define MCDE_EXTSRC2CONF 0x0000024C
#define MCDE_EXTSRC3CONF 0x0000026C
#define MCDE_EXTSRC4CONF 0x0000028C
#define MCDE_EXTSRC5CONF 0x000002AC
#define MCDE_EXTSRC6CONF 0x000002CC
#define MCDE_EXTSRC7CONF 0x000002EC
#define MCDE_EXTSRC8CONF 0x0000030C
#define MCDE_EXTSRC9CONF 0x0000032C
#define MCDE_EXTSRCXCONF_GROUPOFFSET 0x20
#define MCDE_EXTSRCXCONF_BUF_ID_SHIFT 0
#define MCDE_EXTSRCXCONF_BUF_ID_MASK 0x00000003
#define MCDE_EXTSRCXCONF_BUF_NB_SHIFT 2
#define MCDE_EXTSRCXCONF_BUF_NB_MASK 0x0000000C
#define MCDE_EXTSRCXCONF_PRI_OVLID_SHIFT 4
#define MCDE_EXTSRCXCONF_PRI_OVLID_MASK 0x000000F0
#define MCDE_EXTSRCXCONF_BPP_SHIFT 8
#define MCDE_EXTSRCXCONF_BPP_MASK 0x00000F00
#define MCDE_EXTSRCXCONF_BPP_1BPP_PAL 0
#define MCDE_EXTSRCXCONF_BPP_2BPP_PAL 1
#define MCDE_EXTSRCXCONF_BPP_4BPP_PAL 2
#define MCDE_EXTSRCXCONF_BPP_8BPP_PAL 3
#define MCDE_EXTSRCXCONF_BPP_RGB444 4
#define MCDE_EXTSRCXCONF_BPP_ARGB4444 5
#define MCDE_EXTSRCXCONF_BPP_IRGB1555 6
#define MCDE_EXTSRCXCONF_BPP_RGB565 7
#define MCDE_EXTSRCXCONF_BPP_RGB888 8
#define MCDE_EXTSRCXCONF_BPP_XRGB8888 9
#define MCDE_EXTSRCXCONF_BPP_ARGB8888 10
#define MCDE_EXTSRCXCONF_BPP_YCBCR422 11
#define MCDE_EXTSRCXCONF_BGR BIT(12)
#define MCDE_EXTSRCXCONF_BEBO BIT(13)
#define MCDE_EXTSRCXCONF_BEPO BIT(14)
#define MCDE_EXTSRCXCONF_TUNNELING_BUFFER_HEIGHT_SHIFT 16
#define MCDE_EXTSRCXCONF_TUNNELING_BUFFER_HEIGHT_MASK 0x0FFF0000
/* External sources 0..9 */
#define MCDE_EXTSRC0CR 0x00000210
#define MCDE_EXTSRC1CR 0x00000230
#define MCDE_EXTSRC2CR 0x00000250
#define MCDE_EXTSRC3CR 0x00000270
#define MCDE_EXTSRC4CR 0x00000290
#define MCDE_EXTSRC5CR 0x000002B0
#define MCDE_EXTSRC6CR 0x000002D0
#define MCDE_EXTSRC7CR 0x000002F0
#define MCDE_EXTSRC8CR 0x00000310
#define MCDE_EXTSRC9CR 0x00000330
#define MCDE_EXTSRCXCR_SEL_MOD_SHIFT 0
#define MCDE_EXTSRCXCR_SEL_MOD_MASK 0x00000003
#define MCDE_EXTSRCXCR_SEL_MOD_EXTERNAL_SEL 0
#define MCDE_EXTSRCXCR_SEL_MOD_AUTO_TOGGLE 1
#define MCDE_EXTSRCXCR_SEL_MOD_SOFTWARE_SEL 2
#define MCDE_EXTSRCXCR_MULTIOVL_CTRL_PRIMARY BIT(2) /* 0 = all */
#define MCDE_EXTSRCXCR_FS_DIV_DISABLE BIT(3)
#define MCDE_EXTSRCXCR_FORCE_FS_DIV BIT(4)
/* Only external source 6 has a second address register */
#define MCDE_EXTSRC6A2 0x000002C8
/* 6 overlays */
#define MCDE_OVL0CR 0x00000400
#define MCDE_OVL1CR 0x00000420
#define MCDE_OVL2CR 0x00000440
#define MCDE_OVL3CR 0x00000460
#define MCDE_OVL4CR 0x00000480
#define MCDE_OVL5CR 0x000004A0
#define MCDE_OVLXCR_OVLEN BIT(0)
#define MCDE_OVLXCR_COLCCTRL_DISABLED 0
#define MCDE_OVLXCR_COLCCTRL_ENABLED_NO_SAT (1 << 1)
#define MCDE_OVLXCR_COLCCTRL_ENABLED_SAT (2 << 1)
#define MCDE_OVLXCR_CKEYGEN BIT(3)
#define MCDE_OVLXCR_ALPHAPMEN BIT(4)
#define MCDE_OVLXCR_OVLF BIT(5)
#define MCDE_OVLXCR_OVLR BIT(6)
#define MCDE_OVLXCR_OVLB BIT(7)
#define MCDE_OVLXCR_FETCH_ROPC_SHIFT 8
#define MCDE_OVLXCR_FETCH_ROPC_MASK 0x0000FF00
#define MCDE_OVLXCR_STBPRIO_SHIFT 16
#define MCDE_OVLXCR_STBPRIO_MASK 0x000F0000
#define MCDE_OVLXCR_BURSTSIZE_SHIFT 20
#define MCDE_OVLXCR_BURSTSIZE_MASK 0x00F00000
#define MCDE_OVLXCR_BURSTSIZE_1W 0
#define MCDE_OVLXCR_BURSTSIZE_2W 1
#define MCDE_OVLXCR_BURSTSIZE_4W 2
#define MCDE_OVLXCR_BURSTSIZE_8W 3
#define MCDE_OVLXCR_BURSTSIZE_16W 4
#define MCDE_OVLXCR_BURSTSIZE_HW_1W 8
#define MCDE_OVLXCR_BURSTSIZE_HW_2W 9
#define MCDE_OVLXCR_BURSTSIZE_HW_4W 10
#define MCDE_OVLXCR_BURSTSIZE_HW_8W 11
#define MCDE_OVLXCR_BURSTSIZE_HW_16W 12
#define MCDE_OVLXCR_MAXOUTSTANDING_SHIFT 24
#define MCDE_OVLXCR_MAXOUTSTANDING_MASK 0x0F000000
#define MCDE_OVLXCR_MAXOUTSTANDING_1_REQ 0
#define MCDE_OVLXCR_MAXOUTSTANDING_2_REQ 1
#define MCDE_OVLXCR_MAXOUTSTANDING_4_REQ 2
#define MCDE_OVLXCR_MAXOUTSTANDING_8_REQ 3
#define MCDE_OVLXCR_MAXOUTSTANDING_16_REQ 4
#define MCDE_OVLXCR_ROTBURSTSIZE_SHIFT 28
#define MCDE_OVLXCR_ROTBURSTSIZE_MASK 0xF0000000
#define MCDE_OVLXCR_ROTBURSTSIZE_1W 0
#define MCDE_OVLXCR_ROTBURSTSIZE_2W 1
#define MCDE_OVLXCR_ROTBURSTSIZE_4W 2
#define MCDE_OVLXCR_ROTBURSTSIZE_8W 3
#define MCDE_OVLXCR_ROTBURSTSIZE_16W 4
#define MCDE_OVLXCR_ROTBURSTSIZE_HW_1W 8
#define MCDE_OVLXCR_ROTBURSTSIZE_HW_2W 9
#define MCDE_OVLXCR_ROTBURSTSIZE_HW_4W 10
#define MCDE_OVLXCR_ROTBURSTSIZE_HW_8W 11
#define MCDE_OVLXCR_ROTBURSTSIZE_HW_16W 12
#define MCDE_OVL0CONF 0x00000404
#define MCDE_OVL1CONF 0x00000424
#define MCDE_OVL2CONF 0x00000444
#define MCDE_OVL3CONF 0x00000464
#define MCDE_OVL4CONF 0x00000484
#define MCDE_OVL5CONF 0x000004A4
#define MCDE_OVLXCONF_PPL_SHIFT 0
#define MCDE_OVLXCONF_PPL_MASK 0x000007FF
#define MCDE_OVLXCONF_EXTSRC_ID_SHIFT 11
#define MCDE_OVLXCONF_EXTSRC_ID_MASK 0x00007800
#define MCDE_OVLXCONF_LPF_SHIFT 16
#define MCDE_OVLXCONF_LPF_MASK 0x07FF0000
#define MCDE_OVL0CONF2 0x00000408
#define MCDE_OVL1CONF2 0x00000428
#define MCDE_OVL2CONF2 0x00000448
#define MCDE_OVL3CONF2 0x00000468
#define MCDE_OVL4CONF2 0x00000488
#define MCDE_OVL5CONF2 0x000004A8
#define MCDE_OVLXCONF2_BP_PER_PIXEL_ALPHA 0
#define MCDE_OVLXCONF2_BP_CONSTANT_ALPHA BIT(0)
#define MCDE_OVLXCONF2_ALPHAVALUE_SHIFT 1
#define MCDE_OVLXCONF2_ALPHAVALUE_MASK 0x000001FE
#define MCDE_OVLXCONF2_OPQ BIT(9)
#define MCDE_OVLXCONF2_PIXOFF_SHIFT 10
#define MCDE_OVLXCONF2_PIXOFF_MASK 0x0000FC00
#define MCDE_OVLXCONF2_PIXELFETCHERWATERMARKLEVEL_SHIFT 16
#define MCDE_OVLXCONF2_PIXELFETCHERWATERMARKLEVEL_MASK 0x1FFF0000
#define MCDE_OVL0LJINC 0x0000040C
#define MCDE_OVL1LJINC 0x0000042C
#define MCDE_OVL2LJINC 0x0000044C
#define MCDE_OVL3LJINC 0x0000046C
#define MCDE_OVL4LJINC 0x0000048C
#define MCDE_OVL5LJINC 0x000004AC
#define MCDE_OVL0CROP 0x00000410
#define MCDE_OVL1CROP 0x00000430
#define MCDE_OVL2CROP 0x00000450
#define MCDE_OVL3CROP 0x00000470
#define MCDE_OVL4CROP 0x00000490
#define MCDE_OVL5CROP 0x000004B0
#define MCDE_OVLXCROP_TMRGN_SHIFT 0
#define MCDE_OVLXCROP_TMRGN_MASK 0x003FFFFF
#define MCDE_OVLXCROP_LMRGN_SHIFT 22
#define MCDE_OVLXCROP_LMRGN_MASK 0xFFC00000
#define MCDE_OVL0COMP 0x00000414
#define MCDE_OVL1COMP 0x00000434
#define MCDE_OVL2COMP 0x00000454
#define MCDE_OVL3COMP 0x00000474
#define MCDE_OVL4COMP 0x00000494
#define MCDE_OVL5COMP 0x000004B4
#define MCDE_OVLXCOMP_XPOS_SHIFT 0
#define MCDE_OVLXCOMP_XPOS_MASK 0x000007FF
#define MCDE_OVLXCOMP_CH_ID_SHIFT 11
#define MCDE_OVLXCOMP_CH_ID_MASK 0x00007800
#define MCDE_OVLXCOMP_YPOS_SHIFT 16
#define MCDE_OVLXCOMP_YPOS_MASK 0x07FF0000
#define MCDE_OVLXCOMP_Z_SHIFT 27
#define MCDE_OVLXCOMP_Z_MASK 0x78000000
/* DPI/TV configuration registers, channel A and B */
#define MCDE_TVCRA 0x00000838
#define MCDE_TVCRB 0x00000A38
#define MCDE_TVCR_MOD_TV BIT(0) /* 0 = LCD mode */
#define MCDE_TVCR_INTEREN BIT(1)
#define MCDE_TVCR_IFIELD BIT(2)
#define MCDE_TVCR_TVMODE_SDTV_656P (0 << 3)
#define MCDE_TVCR_TVMODE_SDTV_656P_LE (3 << 3)
#define MCDE_TVCR_TVMODE_SDTV_656P_BE (4 << 3)
#define MCDE_TVCR_SDTVMODE_Y0CBY1CR (0 << 6)
#define MCDE_TVCR_SDTVMODE_CBY0CRY1 (1 << 6)
#define MCDE_TVCR_AVRGEN BIT(8)
#define MCDE_TVCR_CKINV BIT(9)
/* TV blanking control register 1, channel A and B */
#define MCDE_TVBL1A 0x0000083C
#define MCDE_TVBL1B 0x00000A3C
#define MCDE_TVBL1_BEL1_SHIFT 0 /* VFP vertical front porch 11 bits */
#define MCDE_TVBL1_BSL1_SHIFT 16 /* VSW vertical sync pulse width 11 bits */
/* Pixel processing TV start line, channel A and B */
#define MCDE_TVISLA 0x00000840
#define MCDE_TVISLB 0x00000A40
#define MCDE_TVISL_FSL1_SHIFT 0 /* Field 1 identification start line 11 bits */
#define MCDE_TVISL_FSL2_SHIFT 16 /* Field 2 identification start line 11 bits */
/* Pixel processing TV DVO offset */
#define MCDE_TVDVOA 0x00000844
#define MCDE_TVDVOB 0x00000A44
#define MCDE_TVDVO_DVO1_SHIFT 0 /* VBP vertical back porch 0 = 0 */
#define MCDE_TVDVO_DVO2_SHIFT 16
/*
* Pixel processing TV Timing 1
* HBP horizontal back porch 11 bits horizontal offset
* 0 = 1 pixel HBP, 255 = 256 pixels, so actual value - 1
*/
#define MCDE_TVTIM1A 0x0000084C
#define MCDE_TVTIM1B 0x00000A4C
/* Pixel processing TV LBALW */
/* 0 = 1 clock cycle, 255 = 256 clock cycles */
#define MCDE_TVLBALWA 0x00000850
#define MCDE_TVLBALWB 0x00000A50
#define MCDE_TVLBALW_LBW_SHIFT 0 /* HSW horizonal sync width, line blanking width 11 bits */
#define MCDE_TVLBALW_ALW_SHIFT 16 /* HFP horizontal front porch, active line width 11 bits */
/* TV blanking control register 1, channel A and B */
#define MCDE_TVBL2A 0x00000854
#define MCDE_TVBL2B 0x00000A54
#define MCDE_TVBL2_BEL2_SHIFT 0 /* Field 2 blanking end line 11 bits */
#define MCDE_TVBL2_BSL2_SHIFT 16 /* Field 2 blanking start line 11 bits */
/* Pixel processing TV background */
#define MCDE_TVBLUA 0x00000858
#define MCDE_TVBLUB 0x00000A58
#define MCDE_TVBLU_TVBLU_SHIFT 0 /* 8 bits luminance */
#define MCDE_TVBLU_TVBCB_SHIFT 8 /* 8 bits Cb chrominance */
#define MCDE_TVBLU_TVBCR_SHIFT 16 /* 8 bits Cr chrominance */
/* Pixel processing LCD timing 1 */
#define MCDE_LCDTIM1A 0x00000860
#define MCDE_LCDTIM1B 0x00000A60
/* inverted vertical sync pulse for HRTFT 0 = active low, 1 active high */
#define MCDE_LCDTIM1B_IVP BIT(19)
/* inverted vertical sync, 0 = active high (the normal), 1 = active low */
#define MCDE_LCDTIM1B_IVS BIT(20)
/* inverted horizontal sync, 0 = active high (the normal), 1 = active low */
#define MCDE_LCDTIM1B_IHS BIT(21)
/* inverted panel clock 0 = rising edge data out, 1 = falling edge data out */
#define MCDE_LCDTIM1B_IPC BIT(22)
/* invert output enable 0 = active high, 1 = active low */
#define MCDE_LCDTIM1B_IOE BIT(23)
#define MCDE_CRC 0x00000C00
#define MCDE_CRC_C1EN BIT(2)
#define MCDE_CRC_C2EN BIT(3)
#define MCDE_CRC_SYCEN0 BIT(7)
#define MCDE_CRC_SYCEN1 BIT(8)
#define MCDE_CRC_SIZE1 BIT(9)
#define MCDE_CRC_SIZE2 BIT(10)
#define MCDE_CRC_YUVCONVC1EN BIT(15)
#define MCDE_CRC_CS1EN BIT(16)
#define MCDE_CRC_CS2EN BIT(17)
#define MCDE_CRC_CS1POL BIT(19)
#define MCDE_CRC_CS2POL BIT(20)
#define MCDE_CRC_CD1POL BIT(21)
#define MCDE_CRC_CD2POL BIT(22)
#define MCDE_CRC_WR1POL BIT(23)
#define MCDE_CRC_WR2POL BIT(24)
#define MCDE_CRC_RD1POL BIT(25)
#define MCDE_CRC_RD2POL BIT(26)
#define MCDE_CRC_SYNCCTRL_SHIFT 29
#define MCDE_CRC_SYNCCTRL_MASK 0x60000000
#define MCDE_CRC_SYNCCTRL_NO_SYNC 0
#define MCDE_CRC_SYNCCTRL_DBI0 1
#define MCDE_CRC_SYNCCTRL_DBI1 2
#define MCDE_CRC_SYNCCTRL_PING_PONG 3
#define MCDE_CRC_CLAMPC1EN BIT(31)
#define MCDE_VSCRC0 0x00000C5C
#define MCDE_VSCRC1 0x00000C60
#define MCDE_VSCRC_VSPMIN_MASK 0x00000FFF
#define MCDE_VSCRC_VSPMAX_SHIFT 12
#define MCDE_VSCRC_VSPMAX_MASK 0x00FFF000
#define MCDE_VSCRC_VSPDIV_SHIFT 24
#define MCDE_VSCRC_VSPDIV_MASK 0x07000000
#define MCDE_VSCRC_VSPDIV_MCDECLK_DIV_1 0
#define MCDE_VSCRC_VSPDIV_MCDECLK_DIV_2 1
#define MCDE_VSCRC_VSPDIV_MCDECLK_DIV_4 2
#define MCDE_VSCRC_VSPDIV_MCDECLK_DIV_8 3
#define MCDE_VSCRC_VSPDIV_MCDECLK_DIV_16 4
#define MCDE_VSCRC_VSPDIV_MCDECLK_DIV_32 5
#define MCDE_VSCRC_VSPDIV_MCDECLK_DIV_64 6
#define MCDE_VSCRC_VSPDIV_MCDECLK_DIV_128 7
#define MCDE_VSCRC_VSPOL BIT(27) /* 0 active high, 1 active low */
#define MCDE_VSCRC_VSSEL BIT(28) /* 0 VSYNC0, 1 VSYNC1 */
#define MCDE_VSCRC_VSDBL BIT(29)
/* Channel config 0..3 */
#define MCDE_CHNL0CONF 0x00000600
#define MCDE_CHNL1CONF 0x00000620
#define MCDE_CHNL2CONF 0x00000640
#define MCDE_CHNL3CONF 0x00000660
#define MCDE_CHNLXCONF_PPL_SHIFT 0
#define MCDE_CHNLXCONF_PPL_MASK 0x000007FF
#define MCDE_CHNLXCONF_LPF_SHIFT 16
#define MCDE_CHNLXCONF_LPF_MASK 0x07FF0000
#define MCDE_MAX_WIDTH 2048
/* Channel status 0..3 */
#define MCDE_CHNL0STAT 0x00000604
#define MCDE_CHNL1STAT 0x00000624
#define MCDE_CHNL2STAT 0x00000644
#define MCDE_CHNL3STAT 0x00000664
#define MCDE_CHNLXSTAT_CHNLRD BIT(0)
#define MCDE_CHNLXSTAT_CHNLA BIT(1)
#define MCDE_CHNLXSTAT_CHNLBLBCKGND_EN BIT(16)
#define MCDE_CHNLXSTAT_PPLX2_V422 BIT(17)
#define MCDE_CHNLXSTAT_LPFX2_V422 BIT(18)
/* Sync settings for channel 0..3 */
#define MCDE_CHNL0SYNCHMOD 0x00000608
#define MCDE_CHNL1SYNCHMOD 0x00000628
#define MCDE_CHNL2SYNCHMOD 0x00000648
#define MCDE_CHNL3SYNCHMOD 0x00000668
#define MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT 0
#define MCDE_CHNLXSYNCHMOD_SRC_SYNCH_MASK 0x00000003
#define MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE 0
#define MCDE_CHNLXSYNCHMOD_SRC_SYNCH_NO_SYNCH 1
#define MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SOFTWARE 2
#define MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT 2
#define MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_MASK 0x0000001C
#define MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER 0
#define MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0 1
#define MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE1 2
/* Software sync triggers for channel 0..3 */
#define MCDE_CHNL0SYNCHSW 0x0000060C
#define MCDE_CHNL1SYNCHSW 0x0000062C
#define MCDE_CHNL2SYNCHSW 0x0000064C
#define MCDE_CHNL3SYNCHSW 0x0000066C
#define MCDE_CHNLXSYNCHSW_SW_TRIG BIT(0)
#define MCDE_CHNL0BCKGNDCOL 0x00000610
#define MCDE_CHNL1BCKGNDCOL 0x00000630
#define MCDE_CHNL2BCKGNDCOL 0x00000650
#define MCDE_CHNL3BCKGNDCOL 0x00000670
#define MCDE_CHNLXBCKGNDCOL_B_SHIFT 0
#define MCDE_CHNLXBCKGNDCOL_B_MASK 0x000000FF
#define MCDE_CHNLXBCKGNDCOL_G_SHIFT 8
#define MCDE_CHNLXBCKGNDCOL_G_MASK 0x0000FF00
#define MCDE_CHNLXBCKGNDCOL_R_SHIFT 16
#define MCDE_CHNLXBCKGNDCOL_R_MASK 0x00FF0000
#define MCDE_CHNL0MUXING 0x00000614
#define MCDE_CHNL1MUXING 0x00000634
#define MCDE_CHNL2MUXING 0x00000654
#define MCDE_CHNL3MUXING 0x00000674
#define MCDE_CHNLXMUXING_FIFO_ID_FIFO_A 0
#define MCDE_CHNLXMUXING_FIFO_ID_FIFO_B 1
#define MCDE_CHNLXMUXING_FIFO_ID_FIFO_C0 2
#define MCDE_CHNLXMUXING_FIFO_ID_FIFO_C1 3
/* Pixel processing control registers for channel A B, */
#define MCDE_CRA0 0x00000800
#define MCDE_CRB0 0x00000A00
#define MCDE_CRX0_FLOEN BIT(0)
#define MCDE_CRX0_POWEREN BIT(1)
#define MCDE_CRX0_BLENDEN BIT(2)
#define MCDE_CRX0_AFLICKEN BIT(3)
#define MCDE_CRX0_PALEN BIT(4)
#define MCDE_CRX0_DITHEN BIT(5)
#define MCDE_CRX0_GAMEN BIT(6)
#define MCDE_CRX0_KEYCTRL_SHIFT 7
#define MCDE_CRX0_KEYCTRL_MASK 0x00000380
#define MCDE_CRX0_KEYCTRL_OFF 0
#define MCDE_CRX0_KEYCTRL_ALPHA_RGB 1
#define MCDE_CRX0_KEYCTRL_RGB 2
#define MCDE_CRX0_KEYCTRL_FALPHA_FRGB 4
#define MCDE_CRX0_KEYCTRL_FRGB 5
#define MCDE_CRX0_BLENDCTRL BIT(10)
#define MCDE_CRX0_FLICKMODE_SHIFT 11
#define MCDE_CRX0_FLICKMODE_MASK 0x00001800
#define MCDE_CRX0_FLICKMODE_FORCE_FILTER_0 0
#define MCDE_CRX0_FLICKMODE_ADAPTIVE 1
#define MCDE_CRX0_FLICKMODE_TEST_MODE 2
#define MCDE_CRX0_FLOCKFORMAT_RGB BIT(13) /* 0 = YCVCR */
#define MCDE_CRX0_PALMODE_GAMMA BIT(14) /* 0 = palette */
#define MCDE_CRX0_OLEDEN BIT(15)
#define MCDE_CRX0_ALPHABLEND_SHIFT 16
#define MCDE_CRX0_ALPHABLEND_MASK 0x00FF0000
#define MCDE_CRX0_ROTEN BIT(24)
#define MCDE_CRA1 0x00000804
#define MCDE_CRB1 0x00000A04
#define MCDE_CRX1_PCD_SHIFT 0
#define MCDE_CRX1_PCD_MASK 0x000003FF
#define MCDE_CRX1_PCD_BITS 10
#define MCDE_CRX1_CLKSEL_SHIFT 10
#define MCDE_CRX1_CLKSEL_MASK 0x00001C00
#define MCDE_CRX1_CLKSEL_CLKPLL72 0
#define MCDE_CRX1_CLKSEL_CLKPLL27 2
#define MCDE_CRX1_CLKSEL_TV1CLK 3
#define MCDE_CRX1_CLKSEL_TV2CLK 4
#define MCDE_CRX1_CLKSEL_MCDECLK 5
#define MCDE_CRX1_CDWIN_SHIFT 13
#define MCDE_CRX1_CDWIN_MASK 0x0001E000
#define MCDE_CRX1_CDWIN_8BPP_C1 0
#define MCDE_CRX1_CDWIN_12BPP_C1 1
#define MCDE_CRX1_CDWIN_12BPP_C2 2
#define MCDE_CRX1_CDWIN_16BPP_C1 3
#define MCDE_CRX1_CDWIN_16BPP_C2 4
#define MCDE_CRX1_CDWIN_16BPP_C3 5
#define MCDE_CRX1_CDWIN_18BPP_C1 6
#define MCDE_CRX1_CDWIN_18BPP_C2 7
#define MCDE_CRX1_CDWIN_24BPP 8
#define MCDE_CRX1_OUTBPP_SHIFT 25
#define MCDE_CRX1_OUTBPP_MASK 0x1E000000
#define MCDE_CRX1_OUTBPP_MONO1 0
#define MCDE_CRX1_OUTBPP_MONO2 1
#define MCDE_CRX1_OUTBPP_MONO4 2
#define MCDE_CRX1_OUTBPP_MONO8 3
#define MCDE_CRX1_OUTBPP_8BPP 4
#define MCDE_CRX1_OUTBPP_12BPP 5
#define MCDE_CRX1_OUTBPP_15BPP 6
#define MCDE_CRX1_OUTBPP_16BPP 7
#define MCDE_CRX1_OUTBPP_18BPP 8
#define MCDE_CRX1_OUTBPP_24BPP 9
#define MCDE_CRX1_BCD BIT(29)
#define MCDE_CRA1_CLKTYPE_TVXCLKSEL1 BIT(30) /* 0 = TVXCLKSEL1 */
#define MCDE_COLKEYA 0x00000808
#define MCDE_COLKEYB 0x00000A08
#define MCDE_FCOLKEYA 0x0000080C
#define MCDE_FCOLKEYB 0x00000A0C
#define MCDE_RGBCONV1A 0x00000810
#define MCDE_RGBCONV1B 0x00000A10
#define MCDE_RGBCONV2A 0x00000814
#define MCDE_RGBCONV2B 0x00000A14
#define MCDE_RGBCONV3A 0x00000818
#define MCDE_RGBCONV3B 0x00000A18
#define MCDE_RGBCONV4A 0x0000081C
#define MCDE_RGBCONV4B 0x00000A1C
#define MCDE_RGBCONV5A 0x00000820
#define MCDE_RGBCONV5B 0x00000A20
#define MCDE_RGBCONV6A 0x00000824
#define MCDE_RGBCONV6B 0x00000A24
/* Rotation */
#define MCDE_ROTACONF 0x0000087C
#define MCDE_ROTBCONF 0x00000A7C
/* Synchronization event configuration */
#define MCDE_SYNCHCONFA 0x00000880
#define MCDE_SYNCHCONFB 0x00000A80
#define MCDE_SYNCHCONF_HWREQVEVENT_SHIFT 0
#define MCDE_SYNCHCONF_HWREQVEVENT_VSYNC (0 << 0)
#define MCDE_SYNCHCONF_HWREQVEVENT_BACK_PORCH (1 << 0)
#define MCDE_SYNCHCONF_HWREQVEVENT_ACTIVE_VIDEO (2 << 0)
#define MCDE_SYNCHCONF_HWREQVEVENT_FRONT_PORCH (3 << 0)
#define MCDE_SYNCHCONF_HWREQVCNT_SHIFT 2 /* 14 bits */
#define MCDE_SYNCHCONF_SWINTVEVENT_VSYNC (0 << 16)
#define MCDE_SYNCHCONF_SWINTVEVENT_BACK_PORCH (1 << 16)
#define MCDE_SYNCHCONF_SWINTVEVENT_ACTIVE_VIDEO (2 << 16)
#define MCDE_SYNCHCONF_SWINTVEVENT_FRONT_PORCH (3 << 16)
#define MCDE_SYNCHCONF_SWINTVCNT_SHIFT 18 /* 14 bits */
/* Channel A+B control registers */
#define MCDE_CTRLA 0x00000884
#define MCDE_CTRLB 0x00000A84
#define MCDE_CTRLX_FIFOWTRMRK_SHIFT 0
#define MCDE_CTRLX_FIFOWTRMRK_MASK 0x000003FF
#define MCDE_CTRLX_FIFOEMPTY BIT(12)
#define MCDE_CTRLX_FIFOFULL BIT(13)
#define MCDE_CTRLX_FORMID_SHIFT 16
#define MCDE_CTRLX_FORMID_MASK 0x00070000
#define MCDE_CTRLX_FORMID_DSI0VID 0
#define MCDE_CTRLX_FORMID_DSI0CMD 1
#define MCDE_CTRLX_FORMID_DSI1VID 2
#define MCDE_CTRLX_FORMID_DSI1CMD 3
#define MCDE_CTRLX_FORMID_DSI2VID 4
#define MCDE_CTRLX_FORMID_DSI2CMD 5
#define MCDE_CTRLX_FORMID_DPIA 0
#define MCDE_CTRLX_FORMID_DPIB 1
#define MCDE_CTRLX_FORMTYPE_SHIFT 20
#define MCDE_CTRLX_FORMTYPE_MASK 0x00700000
#define MCDE_CTRLX_FORMTYPE_DPITV 0
#define MCDE_CTRLX_FORMTYPE_DBI 1
#define MCDE_CTRLX_FORMTYPE_DSI 2
#define MCDE_DSIVID0CONF0 0x00000E00
#define MCDE_DSICMD0CONF0 0x00000E20
#define MCDE_DSIVID1CONF0 0x00000E40
#define MCDE_DSICMD1CONF0 0x00000E60
#define MCDE_DSIVID2CONF0 0x00000E80
#define MCDE_DSICMD2CONF0 0x00000EA0
#define MCDE_DSICONF0_BLANKING_SHIFT 0
#define MCDE_DSICONF0_BLANKING_MASK 0x000000FF
#define MCDE_DSICONF0_VID_MODE_CMD 0
#define MCDE_DSICONF0_VID_MODE_VID BIT(12)
#define MCDE_DSICONF0_CMD8 BIT(13)
#define MCDE_DSICONF0_BIT_SWAP BIT(16)
#define MCDE_DSICONF0_BYTE_SWAP BIT(17)
#define MCDE_DSICONF0_DCSVID_NOTGEN BIT(18)
#define MCDE_DSICONF0_PACKING_SHIFT 20
#define MCDE_DSICONF0_PACKING_MASK 0x00700000
#define MCDE_DSICONF0_PACKING_RGB565 0
#define MCDE_DSICONF0_PACKING_RGB666 1
#define MCDE_DSICONF0_PACKING_RGB888 2
#define MCDE_DSICONF0_PACKING_BGR888 3
#define MCDE_DSICONF0_PACKING_HDTV 4
#define MCDE_DSIVID0FRAME 0x00000E04
#define MCDE_DSICMD0FRAME 0x00000E24
#define MCDE_DSIVID1FRAME 0x00000E44
#define MCDE_DSICMD1FRAME 0x00000E64
#define MCDE_DSIVID2FRAME 0x00000E84
#define MCDE_DSICMD2FRAME 0x00000EA4
#define MCDE_DSIVID0PKT 0x00000E08
#define MCDE_DSICMD0PKT 0x00000E28
#define MCDE_DSIVID1PKT 0x00000E48
#define MCDE_DSICMD1PKT 0x00000E68
#define MCDE_DSIVID2PKT 0x00000E88
#define MCDE_DSICMD2PKT 0x00000EA8
#define MCDE_DSIVID0SYNC 0x00000E0C
#define MCDE_DSICMD0SYNC 0x00000E2C
#define MCDE_DSIVID1SYNC 0x00000E4C
#define MCDE_DSICMD1SYNC 0x00000E6C
#define MCDE_DSIVID2SYNC 0x00000E8C
#define MCDE_DSICMD2SYNC 0x00000EAC
#define MCDE_DSIVID0CMDW 0x00000E10
#define MCDE_DSICMD0CMDW 0x00000E30
#define MCDE_DSIVID1CMDW 0x00000E50
#define MCDE_DSICMD1CMDW 0x00000E70
#define MCDE_DSIVID2CMDW 0x00000E90
#define MCDE_DSICMD2CMDW 0x00000EB0
#define MCDE_DSIVIDXCMDW_CMDW_CONTINUE_SHIFT 0
#define MCDE_DSIVIDXCMDW_CMDW_CONTINUE_MASK 0x0000FFFF
#define MCDE_DSIVIDXCMDW_CMDW_START_SHIFT 16
#define MCDE_DSIVIDXCMDW_CMDW_START_MASK 0xFFFF0000
#define MCDE_DSIVID0DELAY0 0x00000E14
#define MCDE_DSICMD0DELAY0 0x00000E34
#define MCDE_DSIVID1DELAY0 0x00000E54
#define MCDE_DSICMD1DELAY0 0x00000E74
#define MCDE_DSIVID2DELAY0 0x00000E94
#define MCDE_DSICMD2DELAY0 0x00000EB4
#define MCDE_DSIVID0DELAY1 0x00000E18
#define MCDE_DSICMD0DELAY1 0x00000E38
#define MCDE_DSIVID1DELAY1 0x00000E58
#define MCDE_DSICMD1DELAY1 0x00000E78
#define MCDE_DSIVID2DELAY1 0x00000E98
#define MCDE_DSICMD2DELAY1 0x00000EB8
#endif /* __DRM_MCDE_DISPLAY_REGS */
+118
View File
@@ -0,0 +1,118 @@
/* 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,
/* DPI video with the formatter itsels as sync source */
MCDE_DPI_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;
bool dpi_output;
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;
/* Handles to the clock dividers for FIFO A and B */
struct clk *fifoa_clk;
struct clk *fifob_clk;
/* Locks the MCDE FIFO control register A and B */
spinlock_t fifo_crx1_lock;
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);
int mcde_init_clock_divider(struct mcde *mcde);
#endif /* _MCDE_DRM_H_ */
+521
View File
@@ -0,0 +1,521 @@
// 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
*/
/**
* DOC: ST-Ericsson MCDE Driver
*
* The MCDE (short for multi-channel display engine) is a graphics
* controller found in the Ux500 chipsets, such as NovaThor U8500.
* It was initially conceptualized by ST Microelectronics for the
* successor of the Nomadik line, STn8500 but productified in the
* ST-Ericsson U8500 where is was used for mass-market deployments
* in Android phones from Samsung and Sony Ericsson.
*
* It can do 1080p30 on SDTV CCIR656, DPI-2, DBI-2 or DSI for
* panels with or without frame buffering and can convert most
* input formats including most variants of RGB and YUV.
*
* The hardware has four display pipes, and the layout is a little
* bit like this::
*
* Memory -> Overlay -> Channel -> FIFO -> 8 formatters -> DSI/DPI
* External 0..5 0..3 A,B, 6 x DSI bridge
* source 0..9 C0,C1 2 x DPI
*
* FIFOs A and B are for LCD and HDMI while FIFO CO/C1 are for
* panels with embedded buffer.
* 6 of the formatters are for DSI, 3 pairs for VID/CMD respectively.
* 2 of the formatters are for DPI.
*
* Behind the formatters are the DSI or DPI ports that route to
* the external pins of the chip. As there are 3 DSI ports and one
* DPI port, it is possible to configure up to 4 display pipelines
* (effectively using channels 0..3) for concurrent use.
*
* In the current DRM/KMS setup, we use one external source, one overlay,
* one FIFO and one formatter which we connect to the simple DMA framebuffer
* helpers. We then provide a bridge to the DSI port, and on the DSI port
* bridge we connect hang a panel bridge or other bridge. This may be subject
* to change as we exploit more of the hardware capabilities.
*
* TODO:
*
* - Enabled damaged rectangles using drm_plane_enable_fb_damage_clips()
* so we can selectively just transmit the damaged area to a
* command-only display.
* - Enable mixing of more planes, possibly at the cost of moving away
* from using the simple framebuffer pipeline.
* - Enable output to bridges such as the AV8100 HDMI encoder from
* the DSI bridge.
*/
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/dma-buf.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <drm/clients/drm_client_setup.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_managed.h>
#include <drm/drm_of.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_panel.h>
#include <drm/drm_vblank.h>
#include "mcde_drm.h"
#define DRIVER_DESC "DRM module for MCDE"
#define MCDE_PID 0x000001FC
#define MCDE_PID_METALFIX_VERSION_SHIFT 0
#define MCDE_PID_METALFIX_VERSION_MASK 0x000000FF
#define MCDE_PID_DEVELOPMENT_VERSION_SHIFT 8
#define MCDE_PID_DEVELOPMENT_VERSION_MASK 0x0000FF00
#define MCDE_PID_MINOR_VERSION_SHIFT 16
#define MCDE_PID_MINOR_VERSION_MASK 0x00FF0000
#define MCDE_PID_MAJOR_VERSION_SHIFT 24
#define MCDE_PID_MAJOR_VERSION_MASK 0xFF000000
static const struct drm_mode_config_funcs mcde_mode_config_funcs = {
.fb_create = drm_gem_fb_create,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
static const struct drm_mode_config_helper_funcs mcde_mode_config_helpers = {
/*
* Using this function is necessary to commit atomic updates
* that need the CRTC to be enabled before a commit, as is
* the case with e.g. DSI displays.
*/
.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
};
static irqreturn_t mcde_irq(int irq, void *data)
{
struct mcde *mcde = data;
u32 val;
val = readl(mcde->regs + MCDE_MISERR);
mcde_display_irq(mcde);
if (val)
dev_info(mcde->dev, "some error IRQ\n");
writel(val, mcde->regs + MCDE_RISERR);
return IRQ_HANDLED;
}
static int mcde_modeset_init(struct drm_device *drm)
{
struct drm_mode_config *mode_config;
struct mcde *mcde = to_mcde(drm);
int ret;
/*
* If no other bridge was found, check if we have a DPI panel or
* any other bridge connected directly to the MCDE DPI output.
* If a DSI bridge is found, DSI will take precedence.
*
* TODO: more elaborate bridge selection if we have more than one
* thing attached to the system.
*/
if (!mcde->bridge) {
struct drm_panel *panel;
struct drm_bridge *bridge;
ret = drm_of_find_panel_or_bridge(drm->dev->of_node,
0, 0, &panel, &bridge);
if (ret) {
dev_err(drm->dev,
"Could not locate any output bridge or panel\n");
return ret;
}
if (panel) {
bridge = drm_panel_bridge_add_typed(panel,
DRM_MODE_CONNECTOR_DPI);
if (IS_ERR(bridge)) {
dev_err(drm->dev,
"Could not connect panel bridge\n");
return PTR_ERR(bridge);
}
}
mcde->dpi_output = true;
mcde->bridge = bridge;
mcde->flow_mode = MCDE_DPI_FORMATTER_FLOW;
}
mode_config = &drm->mode_config;
mode_config->funcs = &mcde_mode_config_funcs;
mode_config->helper_private = &mcde_mode_config_helpers;
/* This hardware can do 1080p */
mode_config->min_width = 1;
mode_config->max_width = 1920;
mode_config->min_height = 1;
mode_config->max_height = 1080;
ret = drm_vblank_init(drm, 1);
if (ret) {
dev_err(drm->dev, "failed to init vblank\n");
return ret;
}
ret = mcde_display_init(drm);
if (ret) {
dev_err(drm->dev, "failed to init display\n");
return ret;
}
/* Attach the bridge. */
ret = drm_simple_display_pipe_attach_bridge(&mcde->pipe,
mcde->bridge);
if (ret) {
dev_err(drm->dev, "failed to attach display output bridge\n");
return ret;
}
drm_mode_config_reset(drm);
drm_kms_helper_poll_init(drm);
return 0;
}
DEFINE_DRM_GEM_DMA_FOPS(drm_fops);
static const struct drm_driver mcde_drm_driver = {
.driver_features =
DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
.ioctls = NULL,
.fops = &drm_fops,
.name = "mcde",
.desc = DRIVER_DESC,
.major = 1,
.minor = 0,
.patchlevel = 0,
DRM_GEM_DMA_DRIVER_OPS,
DRM_FBDEV_DMA_DRIVER_OPS,
};
static int mcde_drm_bind(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
int ret;
ret = drmm_mode_config_init(drm);
if (ret)
return ret;
ret = component_bind_all(drm->dev, drm);
if (ret) {
dev_err(dev, "can't bind component devices\n");
return ret;
}
ret = mcde_modeset_init(drm);
if (ret)
goto unbind;
ret = drm_dev_register(drm, 0);
if (ret < 0)
goto unbind;
drm_client_setup(drm, NULL);
return 0;
unbind:
component_unbind_all(drm->dev, drm);
return ret;
}
static void mcde_drm_unbind(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
drm_dev_unregister(drm);
drm_atomic_helper_shutdown(drm);
component_unbind_all(drm->dev, drm);
}
static const struct component_master_ops mcde_drm_comp_ops = {
.bind = mcde_drm_bind,
.unbind = mcde_drm_unbind,
};
static struct platform_driver *const mcde_component_drivers[] = {
&mcde_dsi_driver,
};
static int mcde_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct drm_device *drm;
struct mcde *mcde;
struct component_match *match = NULL;
u32 pid;
int irq;
int ret;
int i;
mcde = devm_drm_dev_alloc(dev, &mcde_drm_driver, struct mcde, drm);
if (IS_ERR(mcde))
return PTR_ERR(mcde);
drm = &mcde->drm;
mcde->dev = dev;
platform_set_drvdata(pdev, drm);
/* First obtain and turn on the main power */
mcde->epod = devm_regulator_get(dev, "epod");
if (IS_ERR(mcde->epod)) {
ret = PTR_ERR(mcde->epod);
dev_err(dev, "can't get EPOD regulator\n");
return ret;
}
ret = regulator_enable(mcde->epod);
if (ret) {
dev_err(dev, "can't enable EPOD regulator\n");
return ret;
}
mcde->vana = devm_regulator_get(dev, "vana");
if (IS_ERR(mcde->vana)) {
ret = PTR_ERR(mcde->vana);
dev_err(dev, "can't get VANA regulator\n");
goto regulator_epod_off;
}
ret = regulator_enable(mcde->vana);
if (ret) {
dev_err(dev, "can't enable VANA regulator\n");
goto regulator_epod_off;
}
/*
* The vendor code uses ESRAM (onchip RAM) and need to activate
* the v-esram34 regulator, but we don't use that yet
*/
/* Clock the silicon so we can access the registers */
mcde->mcde_clk = devm_clk_get(dev, "mcde");
if (IS_ERR(mcde->mcde_clk)) {
dev_err(dev, "unable to get MCDE main clock\n");
ret = PTR_ERR(mcde->mcde_clk);
goto regulator_off;
}
ret = clk_prepare_enable(mcde->mcde_clk);
if (ret) {
dev_err(dev, "failed to enable MCDE main clock\n");
goto regulator_off;
}
dev_info(dev, "MCDE clk rate %lu Hz\n", clk_get_rate(mcde->mcde_clk));
mcde->lcd_clk = devm_clk_get(dev, "lcd");
if (IS_ERR(mcde->lcd_clk)) {
dev_err(dev, "unable to get LCD clock\n");
ret = PTR_ERR(mcde->lcd_clk);
goto clk_disable;
}
mcde->hdmi_clk = devm_clk_get(dev, "hdmi");
if (IS_ERR(mcde->hdmi_clk)) {
dev_err(dev, "unable to get HDMI clock\n");
ret = PTR_ERR(mcde->hdmi_clk);
goto clk_disable;
}
mcde->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mcde->regs)) {
dev_err(dev, "no MCDE regs\n");
ret = -EINVAL;
goto clk_disable;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
goto clk_disable;
}
ret = devm_request_irq(dev, irq, mcde_irq, 0, "mcde", mcde);
if (ret) {
dev_err(dev, "failed to request irq %d\n", ret);
goto clk_disable;
}
/*
* Check hardware revision, we only support U8500v2 version
* as this was the only version used for mass market deployment,
* but surely you can add more versions if you have them and
* need them.
*/
pid = readl(mcde->regs + MCDE_PID);
dev_info(dev, "found MCDE HW revision %d.%d (dev %d, metal fix %d)\n",
(pid & MCDE_PID_MAJOR_VERSION_MASK)
>> MCDE_PID_MAJOR_VERSION_SHIFT,
(pid & MCDE_PID_MINOR_VERSION_MASK)
>> MCDE_PID_MINOR_VERSION_SHIFT,
(pid & MCDE_PID_DEVELOPMENT_VERSION_MASK)
>> MCDE_PID_DEVELOPMENT_VERSION_SHIFT,
(pid & MCDE_PID_METALFIX_VERSION_MASK)
>> MCDE_PID_METALFIX_VERSION_SHIFT);
if (pid != 0x03000800) {
dev_err(dev, "unsupported hardware revision\n");
ret = -ENODEV;
goto clk_disable;
}
/* Disable and clear any pending interrupts */
mcde_display_disable_irqs(mcde);
writel(0, mcde->regs + MCDE_IMSCERR);
writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR);
/* Spawn child devices for the DSI ports */
devm_of_platform_populate(dev);
/* Create something that will match the subdrivers when we bind */
for (i = 0; i < ARRAY_SIZE(mcde_component_drivers); i++) {
struct device_driver *drv = &mcde_component_drivers[i]->driver;
struct device *p = NULL, *d;
while ((d = platform_find_device_by_driver(p, drv))) {
put_device(p);
component_match_add(dev, &match, component_compare_dev, d);
p = d;
}
put_device(p);
}
if (!match) {
dev_err(dev, "no matching components\n");
ret = -ENODEV;
goto clk_disable;
}
if (IS_ERR(match)) {
dev_err(dev, "could not create component match\n");
ret = PTR_ERR(match);
goto clk_disable;
}
/*
* Perform an invasive reset of the MCDE and all blocks by
* cutting the power to the subsystem, then bring it back up
* later when we enable the display as a result of
* component_master_add_with_match().
*/
ret = regulator_disable(mcde->epod);
if (ret) {
dev_err(dev, "can't disable EPOD regulator\n");
return ret;
}
/* Wait 50 ms so we are sure we cut the power */
usleep_range(50000, 70000);
ret = component_master_add_with_match(&pdev->dev, &mcde_drm_comp_ops,
match);
if (ret) {
dev_err(dev, "failed to add component master\n");
/*
* The EPOD regulator is already disabled at this point so some
* special errorpath code is needed
*/
clk_disable_unprepare(mcde->mcde_clk);
regulator_disable(mcde->vana);
return ret;
}
return 0;
clk_disable:
clk_disable_unprepare(mcde->mcde_clk);
regulator_off:
regulator_disable(mcde->vana);
regulator_epod_off:
regulator_disable(mcde->epod);
return ret;
}
static void mcde_remove(struct platform_device *pdev)
{
struct drm_device *drm = platform_get_drvdata(pdev);
struct mcde *mcde = to_mcde(drm);
component_master_del(&pdev->dev, &mcde_drm_comp_ops);
clk_disable_unprepare(mcde->mcde_clk);
regulator_disable(mcde->vana);
regulator_disable(mcde->epod);
}
static void mcde_shutdown(struct platform_device *pdev)
{
struct drm_device *drm = platform_get_drvdata(pdev);
if (drm->registered)
drm_atomic_helper_shutdown(drm);
}
static const struct of_device_id mcde_of_match[] = {
{
.compatible = "ste,mcde",
},
{},
};
MODULE_DEVICE_TABLE(of, mcde_of_match);
static struct platform_driver mcde_driver = {
.driver = {
.name = "mcde",
.of_match_table = mcde_of_match,
},
.probe = mcde_probe,
.remove = mcde_remove,
.shutdown = mcde_shutdown,
};
static struct platform_driver *const component_drivers[] = {
&mcde_dsi_driver,
};
static int __init mcde_drm_register(void)
{
int ret;
if (drm_firmware_drivers_only())
return -ENODEV;
ret = platform_register_drivers(component_drivers,
ARRAY_SIZE(component_drivers));
if (ret)
return ret;
return platform_driver_register(&mcde_driver);
}
static void __exit mcde_drm_unregister(void)
{
platform_unregister_drivers(component_drivers,
ARRAY_SIZE(component_drivers));
platform_driver_unregister(&mcde_driver);
}
module_init(mcde_drm_register);
module_exit(mcde_drm_unregister);
MODULE_ALIAS("platform:mcde-drm");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
MODULE_LICENSE("GPL");
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,385 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __DRM_MCDE_DSI_REGS
#define __DRM_MCDE_DSI_REGS
#define DSI_MCTL_INTEGRATION_MODE 0x00000000
#define DSI_MCTL_MAIN_DATA_CTL 0x00000004
#define DSI_MCTL_MAIN_DATA_CTL_LINK_EN BIT(0)
#define DSI_MCTL_MAIN_DATA_CTL_IF1_MODE BIT(1)
#define DSI_MCTL_MAIN_DATA_CTL_VID_EN BIT(2)
#define DSI_MCTL_MAIN_DATA_CTL_TVG_SEL BIT(3)
#define DSI_MCTL_MAIN_DATA_CTL_TBG_SEL BIT(4)
#define DSI_MCTL_MAIN_DATA_CTL_IF1_TE_EN BIT(5)
#define DSI_MCTL_MAIN_DATA_CTL_IF2_TE_EN BIT(6)
#define DSI_MCTL_MAIN_DATA_CTL_REG_TE_EN BIT(7)
#define DSI_MCTL_MAIN_DATA_CTL_READ_EN BIT(8)
#define DSI_MCTL_MAIN_DATA_CTL_BTA_EN BIT(9)
#define DSI_MCTL_MAIN_DATA_CTL_DISP_GEN_ECC BIT(10)
#define DSI_MCTL_MAIN_DATA_CTL_DISP_GEN_CHECKSUM BIT(11)
#define DSI_MCTL_MAIN_DATA_CTL_HOST_EOT_GEN BIT(12)
#define DSI_MCTL_MAIN_DATA_CTL_DISP_EOT_GEN BIT(13)
#define DSI_MCTL_MAIN_DATA_CTL_DLX_REMAP_EN BIT(14)
#define DSI_MCTL_MAIN_DATA_CTL_TE_POLLING_EN BIT(15)
#define DSI_MCTL_MAIN_PHY_CTL 0x00000008
#define DSI_MCTL_MAIN_PHY_CTL_LANE2_EN BIT(0)
#define DSI_MCTL_MAIN_PHY_CTL_FORCE_STOP_MODE BIT(1)
#define DSI_MCTL_MAIN_PHY_CTL_CLK_CONTINUOUS BIT(2)
#define DSI_MCTL_MAIN_PHY_CTL_CLK_ULPM_EN BIT(3)
#define DSI_MCTL_MAIN_PHY_CTL_DAT1_ULPM_EN BIT(4)
#define DSI_MCTL_MAIN_PHY_CTL_DAT2_ULPM_EN BIT(5)
#define DSI_MCTL_MAIN_PHY_CTL_WAIT_BURST_TIME_SHIFT 6
#define DSI_MCTL_MAIN_PHY_CTL_WAIT_BURST_TIME_MASK 0x000003C0
#define DSI_MCTL_MAIN_PHY_CTL_CLOCK_FORCE_STOP_MODE BIT(10)
#define DSI_MCTL_PLL_CTL 0x0000000C
#define DSI_MCTL_LANE_STS 0x00000010
#define DSI_MCTL_DPHY_TIMEOUT 0x00000014
#define DSI_MCTL_DPHY_TIMEOUT_CLK_DIV_SHIFT 0
#define DSI_MCTL_DPHY_TIMEOUT_CLK_DIV_MASK 0x0000000F
#define DSI_MCTL_DPHY_TIMEOUT_HSTX_TO_VAL_SHIFT 4
#define DSI_MCTL_DPHY_TIMEOUT_HSTX_TO_VAL_MASK 0x0003FFF0
#define DSI_MCTL_DPHY_TIMEOUT_LPRX_TO_VAL_SHIFT 18
#define DSI_MCTL_DPHY_TIMEOUT_LPRX_TO_VAL_MASK 0xFFFC0000
#define DSI_MCTL_ULPOUT_TIME 0x00000018
#define DSI_MCTL_ULPOUT_TIME_CKLANE_ULPOUT_TIME_SHIFT 0
#define DSI_MCTL_ULPOUT_TIME_CKLANE_ULPOUT_TIME_MASK 0x000001FF
#define DSI_MCTL_ULPOUT_TIME_DATA_ULPOUT_TIME_SHIFT 9
#define DSI_MCTL_ULPOUT_TIME_DATA_ULPOUT_TIME_MASK 0x0003FE00
#define DSI_MCTL_DPHY_STATIC 0x0000001C
#define DSI_MCTL_DPHY_STATIC_SWAP_PINS_CLK BIT(0)
#define DSI_MCTL_DPHY_STATIC_HS_INVERT_CLK BIT(1)
#define DSI_MCTL_DPHY_STATIC_SWAP_PINS_DAT1 BIT(2)
#define DSI_MCTL_DPHY_STATIC_HS_INVERT_DAT1 BIT(3)
#define DSI_MCTL_DPHY_STATIC_SWAP_PINS_DAT2 BIT(4)
#define DSI_MCTL_DPHY_STATIC_HS_INVERT_DAT2 BIT(5)
#define DSI_MCTL_DPHY_STATIC_UI_X4_SHIFT 6
#define DSI_MCTL_DPHY_STATIC_UI_X4_MASK 0x00000FC0
#define DSI_MCTL_MAIN_EN 0x00000020
#define DSI_MCTL_MAIN_EN_PLL_START BIT(0)
#define DSI_MCTL_MAIN_EN_CKLANE_EN BIT(3)
#define DSI_MCTL_MAIN_EN_DAT1_EN BIT(4)
#define DSI_MCTL_MAIN_EN_DAT2_EN BIT(5)
#define DSI_MCTL_MAIN_EN_CLKLANE_ULPM_REQ BIT(6)
#define DSI_MCTL_MAIN_EN_DAT1_ULPM_REQ BIT(7)
#define DSI_MCTL_MAIN_EN_DAT2_ULPM_REQ BIT(8)
#define DSI_MCTL_MAIN_EN_IF1_EN BIT(9)
#define DSI_MCTL_MAIN_EN_IF2_EN BIT(10)
#define DSI_MCTL_MAIN_STS 0x00000024
#define DSI_MCTL_MAIN_STS_PLL_LOCK BIT(0)
#define DSI_MCTL_MAIN_STS_CLKLANE_READY BIT(1)
#define DSI_MCTL_MAIN_STS_DAT1_READY BIT(2)
#define DSI_MCTL_MAIN_STS_DAT2_READY BIT(3)
#define DSI_MCTL_MAIN_STS_HSTX_TO_ERR BIT(4)
#define DSI_MCTL_MAIN_STS_LPRX_TO_ERR BIT(5)
#define DSI_MCTL_MAIN_STS_CRS_UNTERM_PCK BIT(6)
#define DSI_MCTL_MAIN_STS_VRS_UNTERM_PCK BIT(7)
#define DSI_MCTL_DPHY_ERR 0x00000028
#define DSI_INT_VID_RDDATA 0x00000030
#define DSI_INT_VID_GNT 0x00000034
#define DSI_INT_CMD_RDDATA 0x00000038
#define DSI_INT_CMD_GNT 0x0000003C
#define DSI_INT_INTERRUPT_CTL 0x00000040
#define DSI_CMD_MODE_CTL 0x00000050
#define DSI_CMD_MODE_CTL_IF1_ID_SHIFT 0
#define DSI_CMD_MODE_CTL_IF1_ID_MASK 0x00000003
#define DSI_CMD_MODE_CTL_IF2_ID_SHIFT 2
#define DSI_CMD_MODE_CTL_IF2_ID_MASK 0x0000000C
#define DSI_CMD_MODE_CTL_IF1_LP_EN BIT(4)
#define DSI_CMD_MODE_CTL_IF2_LP_EN BIT(5)
#define DSI_CMD_MODE_CTL_ARB_MODE BIT(6)
#define DSI_CMD_MODE_CTL_ARB_PRI BIT(7)
#define DSI_CMD_MODE_CTL_FIL_VALUE_SHIFT 8
#define DSI_CMD_MODE_CTL_FIL_VALUE_MASK 0x0000FF00
#define DSI_CMD_MODE_CTL_TE_TIMEOUT_SHIFT 16
#define DSI_CMD_MODE_CTL_TE_TIMEOUT_MASK 0x03FF0000
#define DSI_CMD_MODE_STS 0x00000054
#define DSI_CMD_MODE_STS_ERR_NO_TE BIT(0)
#define DSI_CMD_MODE_STS_ERR_TE_MISS BIT(1)
#define DSI_CMD_MODE_STS_ERR_SDI1_UNDERRUN BIT(2)
#define DSI_CMD_MODE_STS_ERR_SDI2_UNDERRUN BIT(3)
#define DSI_CMD_MODE_STS_ERR_UNWANTED_RD BIT(4)
#define DSI_CMD_MODE_STS_CSM_RUNNING BIT(5)
#define DSI_DIRECT_CMD_SEND 0x00000060
#define DSI_DIRECT_CMD_MAIN_SETTINGS 0x00000064
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_SHIFT 0
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_MASK 0x00000007
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_WRITE 0
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_READ 1
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_TE_REQ 4
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_TRIG_REQ 5
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_BTA_REQ 6
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_LONGNOTSHORT BIT(3)
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_SHIFT 8
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_MASK 0x00003F00
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_ID_SHIFT 14
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_SIZE_SHIFT 16
#define DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_LP_EN BIT(21)
#define DSI_DIRECT_CMD_MAIN_SETTINGS_TRIGGER_VAL_SHIFT 24
#define DSI_DIRECT_CMD_MAIN_SETTINGS_TRIGGER_VAL_MASK 0x0F000000
#define DSI_DIRECT_CMD_STS 0x00000068
#define DSI_DIRECT_CMD_STS_CMD_TRANSMISSION BIT(0)
#define DSI_DIRECT_CMD_STS_WRITE_COMPLETED BIT(1)
#define DSI_DIRECT_CMD_STS_TRIGGER_COMPLETED BIT(2)
#define DSI_DIRECT_CMD_STS_READ_COMPLETED BIT(3)
#define DSI_DIRECT_CMD_STS_ACKNOWLEDGE_RECEIVED_SHIFT BIT(4)
#define DSI_DIRECT_CMD_STS_ACKNOWLEDGE_WITH_ERR_RECEIVED BIT(5)
#define DSI_DIRECT_CMD_STS_TRIGGER_RECEIVED BIT(6)
#define DSI_DIRECT_CMD_STS_TE_RECEIVED BIT(7)
#define DSI_DIRECT_CMD_STS_BTA_COMPLETED BIT(8)
#define DSI_DIRECT_CMD_STS_BTA_FINISHED BIT(9)
#define DSI_DIRECT_CMD_STS_READ_COMPLETED_WITH_ERR BIT(10)
#define DSI_DIRECT_CMD_STS_TRIGGER_VAL_MASK 0x00007800
#define DSI_DIRECT_CMD_STS_TRIGGER_VAL_SHIFT 11
#define DSI_DIRECT_CMD_STS_ACK_VAL_SHIFT 16
#define DSI_DIRECT_CMD_STS_ACK_VAL_MASK 0xFFFF0000
#define DSI_DIRECT_CMD_RD_INIT 0x0000006C
#define DSI_DIRECT_CMD_RD_INIT_RESET_SHIFT 0
#define DSI_DIRECT_CMD_RD_INIT_RESET_MASK 0xFFFFFFFF
#define DSI_DIRECT_CMD_WRDAT0 0x00000070
#define DSI_DIRECT_CMD_WRDAT1 0x00000074
#define DSI_DIRECT_CMD_WRDAT2 0x00000078
#define DSI_DIRECT_CMD_WRDAT3 0x0000007C
#define DSI_DIRECT_CMD_RDDAT 0x00000080
#define DSI_DIRECT_CMD_RD_PROPERTY 0x00000084
#define DSI_DIRECT_CMD_RD_PROPERTY_RD_SIZE_SHIFT 0
#define DSI_DIRECT_CMD_RD_PROPERTY_RD_SIZE_MASK 0x0000FFFF
#define DSI_DIRECT_CMD_RD_PROPERTY_RD_ID_SHIFT 16
#define DSI_DIRECT_CMD_RD_PROPERTY_RD_ID_MASK 0x00030000
#define DSI_DIRECT_CMD_RD_PROPERTY_RD_DCSNOTGENERIC_SHIFT 18
#define DSI_DIRECT_CMD_RD_PROPERTY_RD_DCSNOTGENERIC_MASK 0x00040000
#define DSI_DIRECT_CMD_RD_STS 0x00000088
#define DSI_VID_MAIN_CTL 0x00000090
#define DSI_VID_MAIN_CTL_START_MODE_SHIFT 0
#define DSI_VID_MAIN_CTL_START_MODE_MASK 0x00000003
#define DSI_VID_MAIN_CTL_STOP_MODE_SHIFT 2
#define DSI_VID_MAIN_CTL_STOP_MODE_MASK 0x0000000C
#define DSI_VID_MAIN_CTL_VID_ID_SHIFT 4
#define DSI_VID_MAIN_CTL_VID_ID_MASK 0x00000030
#define DSI_VID_MAIN_CTL_HEADER_SHIFT 6
#define DSI_VID_MAIN_CTL_HEADER_MASK 0x00000FC0
#define DSI_VID_MAIN_CTL_VID_PIXEL_MODE_16BITS 0
#define DSI_VID_MAIN_CTL_VID_PIXEL_MODE_18BITS BIT(12)
#define DSI_VID_MAIN_CTL_VID_PIXEL_MODE_18BITS_LOOSE BIT(13)
#define DSI_VID_MAIN_CTL_VID_PIXEL_MODE_24BITS (BIT(12) | BIT(13))
#define DSI_VID_MAIN_CTL_BURST_MODE BIT(14)
#define DSI_VID_MAIN_CTL_SYNC_PULSE_ACTIVE BIT(15)
#define DSI_VID_MAIN_CTL_SYNC_PULSE_HORIZONTAL BIT(16)
#define DSI_VID_MAIN_CTL_REG_BLKLINE_MODE_NULL 0
#define DSI_VID_MAIN_CTL_REG_BLKLINE_MODE_BLANKING BIT(17)
#define DSI_VID_MAIN_CTL_REG_BLKLINE_MODE_LP_0 BIT(18)
#define DSI_VID_MAIN_CTL_REG_BLKLINE_MODE_LP_1 (BIT(17) | BIT(18))
#define DSI_VID_MAIN_CTL_REG_BLKEOL_MODE_NULL 0
#define DSI_VID_MAIN_CTL_REG_BLKEOL_MODE_BLANKING BIT(19)
#define DSI_VID_MAIN_CTL_REG_BLKEOL_MODE_LP_0 BIT(20)
#define DSI_VID_MAIN_CTL_REG_BLKEOL_MODE_LP_1 (BIT(19) | BIT(20))
#define DSI_VID_MAIN_CTL_RECOVERY_MODE_SHIFT 21
#define DSI_VID_MAIN_CTL_RECOVERY_MODE_MASK 0x00600000
#define DSI_VID_VSIZE 0x00000094
#define DSI_VID_VSIZE_VSA_LENGTH_SHIFT 0
#define DSI_VID_VSIZE_VSA_LENGTH_MASK 0x0000003F
#define DSI_VID_VSIZE_VBP_LENGTH_SHIFT 6
#define DSI_VID_VSIZE_VBP_LENGTH_MASK 0x00000FC0
#define DSI_VID_VSIZE_VFP_LENGTH_SHIFT 12
#define DSI_VID_VSIZE_VFP_LENGTH_MASK 0x000FF000
#define DSI_VID_VSIZE_VACT_LENGTH_SHIFT 20
#define DSI_VID_VSIZE_VACT_LENGTH_MASK 0x7FF00000
#define DSI_VID_HSIZE1 0x00000098
#define DSI_VID_HSIZE1_HSA_LENGTH_SHIFT 0
#define DSI_VID_HSIZE1_HSA_LENGTH_MASK 0x000003FF
#define DSI_VID_HSIZE1_HBP_LENGTH_SHIFT 10
#define DSI_VID_HSIZE1_HBP_LENGTH_MASK 0x000FFC00
#define DSI_VID_HSIZE1_HFP_LENGTH_SHIFT 20
#define DSI_VID_HSIZE1_HFP_LENGTH_MASK 0x7FF00000
#define DSI_VID_HSIZE2 0x0000009C
#define DSI_VID_HSIZE2_RGB_SIZE_SHIFT 0
#define DSI_VID_HSIZE2_RGB_SIZE_MASK 0x00001FFF
#define DSI_VID_BLKSIZE1 0x000000A0
#define DSI_VID_BLKSIZE1_BLKLINE_EVENT_PCK_SHIFT 0
#define DSI_VID_BLKSIZE1_BLKLINE_EVENT_PCK_MASK 0x00001FFF
#define DSI_VID_BLKSIZE1_BLKEOL_PCK_SHIFT 13
#define DSI_VID_BLKSIZE1_BLKEOL_PCK_MASK 0x03FFE000
#define DSI_VID_BLKSIZE2 0x000000A4
#define DSI_VID_BLKSIZE2_BLKLINE_PULSE_PCK_SHIFT 0
#define DSI_VID_BLKSIZE2_BLKLINE_PULSE_PCK_MASK 0x00001FFF
#define DSI_VID_PCK_TIME 0x000000A8
#define DSI_VID_PCK_TIME_BLKEOL_DURATION_SHIFT 0
#define DSI_VID_PCK_TIME_BLKEOL_DURATION_MASK 0x00000FFF
#define DSI_VID_DPHY_TIME 0x000000AC
#define DSI_VID_DPHY_TIME_REG_LINE_DURATION_SHIFT 0
#define DSI_VID_DPHY_TIME_REG_LINE_DURATION_MASK 0x00001FFF
#define DSI_VID_DPHY_TIME_REG_WAKEUP_TIME_SHIFT 13
#define DSI_VID_DPHY_TIME_REG_WAKEUP_TIME_MASK 0x00FFE000
#define DSI_VID_MODE_STS 0x000000BC
#define DSI_VID_MODE_STS_VSG_RUNNING BIT(0)
#define DSI_VID_MODE_STS_ERR_MISSING_DATA BIT(1)
#define DSI_VID_MODE_STS_ERR_MISSING_HSYNC BIT(2)
#define DSI_VID_MODE_STS_ERR_MISSING_VSYNC BIT(3)
#define DSI_VID_MODE_STS_REG_ERR_SMALL_LENGTH BIT(4)
#define DSI_VID_MODE_STS_REG_ERR_SMALL_HEIGHT BIT(5)
#define DSI_VID_MODE_STS_ERR_BURSTWRITE BIT(6)
#define DSI_VID_MODE_STS_ERR_LINEWRITE BIT(7)
#define DSI_VID_MODE_STS_ERR_LONGREAD BIT(8)
#define DSI_VID_MODE_STS_ERR_VRS_WRONG_LENGTH BIT(9)
#define DSI_VID_MODE_STS_VSG_RECOVERY BIT(10)
#define DSI_VID_VCA_SETTING1 0x000000C0
#define DSI_VID_VCA_SETTING1_MAX_BURST_LIMIT_SHIFT 0
#define DSI_VID_VCA_SETTING1_MAX_BURST_LIMIT_MASK 0x0000FFFF
#define DSI_VID_VCA_SETTING1_BURST_LP BIT(16)
#define DSI_VID_VCA_SETTING2 0x000000C4
#define DSI_VID_VCA_SETTING2_EXACT_BURST_LIMIT_SHIFT 0
#define DSI_VID_VCA_SETTING2_EXACT_BURST_LIMIT_MASK 0x0000FFFF
#define DSI_VID_VCA_SETTING2_MAX_LINE_LIMIT_SHIFT 16
#define DSI_VID_VCA_SETTING2_MAX_LINE_LIMIT_MASK 0xFFFF0000
#define DSI_CMD_MODE_STS_CTL 0x000000F4
#define DSI_CMD_MODE_STS_CTL_ERR_NO_TE_EN BIT(0)
#define DSI_CMD_MODE_STS_CTL_ERR_TE_MISS_EN BIT(1)
#define DSI_CMD_MODE_STS_CTL_ERR_SDI1_UNDERRUN_EN BIT(2)
#define DSI_CMD_MODE_STS_CTL_ERR_SDI2_UNDERRUN_EN BIT(3)
#define DSI_CMD_MODE_STS_CTL_ERR_UNWANTED_RD_EN BIT(4)
#define DSI_CMD_MODE_STS_CTL_CSM_RUNNING_EN BIT(5)
#define DSI_CMD_MODE_STS_CTL_ERR_NO_TE_EDGE BIT(16)
#define DSI_CMD_MODE_STS_CTL_ERR_TE_MISS_EDGE BIT(17)
#define DSI_CMD_MODE_STS_CTL_ERR_SDI1_UNDERRUN_EDGE BIT(18)
#define DSI_CMD_MODE_STS_CTL_ERR_SDI2_UNDERRUN_EDGE BIT(19)
#define DSI_CMD_MODE_STS_CTL_ERR_UNWANTED_RD_EDGE BIT(20)
#define DSI_CMD_MODE_STS_CTL_CSM_RUNNING_EDGE BIT(21)
#define DSI_DIRECT_CMD_STS_CTL 0x000000F8
#define DSI_DIRECT_CMD_STS_CTL_CMD_TRANSMISSION_EN BIT(0)
#define DSI_DIRECT_CMD_STS_CTL_WRITE_COMPLETED_EN BIT(1)
#define DSI_DIRECT_CMD_STS_CTL_TRIGGER_COMPLETED_EN BIT(2)
#define DSI_DIRECT_CMD_STS_CTL_READ_COMPLETED_EN BIT(3)
#define DSI_DIRECT_CMD_STS_CTL_ACKNOWLEDGE_RECEIVED_EN BIT(4)
#define DSI_DIRECT_CMD_STS_CTL_ACKNOWLEDGE_WITH_ERR_EN BIT(5)
#define DSI_DIRECT_CMD_STS_CTL_TRIGGER_RECEIVED_EN BIT(6)
#define DSI_DIRECT_CMD_STS_CTL_TE_RECEIVED_EN BIT(7)
#define DSI_DIRECT_CMD_STS_CTL_BTA_COMPLETED_EN BIT(8)
#define DSI_DIRECT_CMD_STS_CTL_BTA_FINISHED_EN BIT(9)
#define DSI_DIRECT_CMD_STS_CTL_READ_COMPLETED_WITH_ERR_EN BIT(10)
#define DSI_DIRECT_CMD_STS_CTL_CMD_TRANSMISSION_EDGE BIT(16)
#define DSI_DIRECT_CMD_STS_CTL_WRITE_COMPLETED_EDGE BIT(17)
#define DSI_DIRECT_CMD_STS_CTL_TRIGGER_COMPLETED_EDGE BIT(18)
#define DSI_DIRECT_CMD_STS_CTL_READ_COMPLETED_EDGE BIT(19)
#define DSI_DIRECT_CMD_STS_CTL_ACKNOWLEDGE_RECEIVED_EDGE BIT(20)
#define DSI_DIRECT_CMD_STS_CTL_ACKNOWLEDGE_WITH_ERR_EDGE BIT(21)
#define DSI_DIRECT_CMD_STS_CTL_TRIGGER_RECEIVED_EDGE BIT(22)
#define DSI_DIRECT_CMD_STS_CTL_TE_RECEIVED_EDGE BIT(23)
#define DSI_DIRECT_CMD_STS_CTL_BTA_COMPLETED_EDGE BIT(24)
#define DSI_DIRECT_CMD_STS_CTL_BTA_FINISHED_EDGE BIT(25)
#define DSI_DIRECT_CMD_STS_CTL_READ_COMPLETED_WITH_ERR_EDGE BIT(26)
#define DSI_VID_MODE_STS_CTL 0x00000100
#define DSI_VID_MODE_STS_CTL_VSG_RUNNING BIT(0)
#define DSI_VID_MODE_STS_CTL_ERR_MISSING_DATA BIT(1)
#define DSI_VID_MODE_STS_CTL_ERR_MISSING_HSYNC BIT(2)
#define DSI_VID_MODE_STS_CTL_ERR_MISSING_VSYNC BIT(3)
#define DSI_VID_MODE_STS_CTL_REG_ERR_SMALL_LENGTH BIT(4)
#define DSI_VID_MODE_STS_CTL_REG_ERR_SMALL_HEIGHT BIT(5)
#define DSI_VID_MODE_STS_CTL_ERR_BURSTWRITE BIT(6)
#define DSI_VID_MODE_STS_CTL_ERR_LONGWRITE BIT(7)
#define DSI_VID_MODE_STS_CTL_ERR_LONGREAD BIT(8)
#define DSI_VID_MODE_STS_CTL_ERR_VRS_WRONG_LENGTH BIT(9)
#define DSI_VID_MODE_STS_CTL_VSG_RUNNING_EDGE BIT(16)
#define DSI_VID_MODE_STS_CTL_ERR_MISSING_DATA_EDGE BIT(17)
#define DSI_VID_MODE_STS_CTL_ERR_MISSING_HSYNC_EDGE BIT(18)
#define DSI_VID_MODE_STS_CTL_ERR_MISSING_VSYNC_EDGE BIT(19)
#define DSI_VID_MODE_STS_CTL_REG_ERR_SMALL_LENGTH_EDGE BIT(20)
#define DSI_VID_MODE_STS_CTL_REG_ERR_SMALL_HEIGHT_EDGE BIT(21)
#define DSI_VID_MODE_STS_CTL_ERR_BURSTWRITE_EDGE BIT(22)
#define DSI_VID_MODE_STS_CTL_ERR_LONGWRITE_EDGE BIT(23)
#define DSI_VID_MODE_STS_CTL_ERR_LONGREAD_EDGE BIT(24)
#define DSI_VID_MODE_STS_CTL_ERR_VRS_WRONG_LENGTH_EDGE BIT(25)
#define DSI_VID_MODE_STS_CTL_VSG_RECOVERY_EDGE BIT(26)
#define DSI_TG_STS_CTL 0x00000104
#define DSI_MCTL_DHPY_ERR_CTL 0x00000108
#define DSI_MCTL_MAIN_STS_CLR 0x00000110
#define DSI_CMD_MODE_STS_CLR 0x00000114
#define DSI_CMD_MODE_STS_CLR_ERR_NO_TE_CLR BIT(0)
#define DSI_CMD_MODE_STS_CLR_ERR_TE_MISS_CLR BIT(1)
#define DSI_CMD_MODE_STS_CLR_ERR_SDI1_UNDERRUN_CLR BIT(2)
#define DSI_CMD_MODE_STS_CLR_ERR_SDI2_UNDERRUN_CLR BIT(3)
#define DSI_CMD_MODE_STS_CLR_ERR_UNWANTED_RD_CLR BIT(4)
#define DSI_CMD_MODE_STS_CLR_CSM_RUNNING_CLR BIT(5)
#define DSI_DIRECT_CMD_STS_CLR 0x00000118
#define DSI_DIRECT_CMD_STS_CLR_CMD_TRANSMISSION_CLR BIT(0)
#define DSI_DIRECT_CMD_STS_CLR_WRITE_COMPLETED_CLR BIT(1)
#define DSI_DIRECT_CMD_STS_CLR_TRIGGER_COMPLETED_CLR BIT(2)
#define DSI_DIRECT_CMD_STS_CLR_READ_COMPLETED_CLR BIT(3)
#define DSI_DIRECT_CMD_STS_CLR_ACKNOWLEDGE_RECEIVED_CLR BIT(4)
#define DSI_DIRECT_CMD_STS_CLR_ACKNOWLEDGE_WITH_ERR_RECEIVED_CLR BIT(5)
#define DSI_DIRECT_CMD_STS_CLR_TRIGGER_RECEIVED_CLR BIT(6)
#define DSI_DIRECT_CMD_STS_CLR_TE_RECEIVED_CLR BIT(7)
#define DSI_DIRECT_CMD_STS_CLR_BTA_COMPLETED_CLR BIT(8)
#define DSI_DIRECT_CMD_STS_CLR_BTA_FINISHED_CLR BIT(9)
#define DSI_DIRECT_CMD_STS_CLR_READ_COMPLETED_WITH_ERR_CLR BIT(10)
#define DSI_DIRECT_CMD_RD_STS_CLR 0x0000011C
#define DSI_VID_MODE_STS_CLR 0x00000120
#define DSI_TG_STS_CLR 0x00000124
#define DSI_MCTL_DPHY_ERR_CLR 0x00000128
#define DSI_MCTL_MAIN_STS_FLAG 0x00000130
#define DSI_CMD_MODE_STS_FLAG 0x00000134
#define DSI_DIRECT_CMD_STS_FLAG 0x00000138
#define DSI_DIRECT_CMD_RD_STS_FLAG 0x0000013C
#define DSI_VID_MODE_STS_FLAG 0x00000140
#define DSI_TG_STS_FLAG 0x00000144
#define DSI_DPHY_LANES_TRIM 0x00000150
#define DSI_DPHY_LANES_TRIM_DPHY_SKEW_DAT1_SHIFT 0
#define DSI_DPHY_LANES_TRIM_DPHY_SKEW_DAT1_MASK 0x00000003
#define DSI_DPHY_LANES_TRIM_DPHY_CD_OFF_DAT1 BIT(2)
#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_UP_DAT1 BIT(3)
#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_DOWN_DAT1 BIT(4)
#define DSI_DPHY_LANES_TRIM_DPHY_TEST_RESERVED_1_DAT1 BIT(5)
#define DSI_DPHY_LANES_TRIM_DPHY_SKEW_CLK_SHIFT 6
#define DSI_DPHY_LANES_TRIM_DPHY_SKEW_CLK_MASK 0x000000C0
#define DSI_DPHY_LANES_TRIM_DPHY_LP_RX_VIL_CLK_SHIFT 8
#define DSI_DPHY_LANES_TRIM_DPHY_LP_RX_VIL_CLK_MASK 0x00000300
#define DSI_DPHY_LANES_TRIM_DPHY_LP_TX_SLEWRATE_CLK_SHIFT 10
#define DSI_DPHY_LANES_TRIM_DPHY_LP_TX_SLEWRATE_CLK_MASK 0x00000C00
#define DSI_DPHY_LANES_TRIM_DPHY_SPECS_90_81B_0_81 0
#define DSI_DPHY_LANES_TRIM_DPHY_SPECS_90_81B_0_90 BIT(12)
#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_UP_CLK BIT(13)
#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_DOWN_CLK BIT(14)
#define DSI_DPHY_LANES_TRIM_DPHY_TEST_RESERVED_1_CLK BIT(15)
#define DSI_DPHY_LANES_TRIM_DPHY_SKEW_DAT2 BIT(16)
#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_UP_DAT2 BIT(18)
#define DSI_DPHY_LANES_TRIM_DPHY_HSTX_SLEWRATE_DOWN_DAT2 BIT(19)
#define DSI_DPHY_LANES_TRIM_DPHY_TEST_RESERVED_1_DAT2 BIT(20)
#define DSI_ID_REG 0x00000FF0
#endif /* __DRM_MCDE_DSI_REGS */