// SPDX-License-Identifier: GPL-2.0
/*
* Copyright: 2017 Cadence Design Systems, Inc.
*
* Author: Boris Brezillon <boris.brezillon@bootlin.com>
*/
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_drv.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>
#include <video/mipi_display.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/phy/phy.h>
#include <linux/phy/phy-mipi-dphy.h>
#define IP_CONF 0x0
#define SP_HS_FIFO_DEPTH(x) (((x) & GENMASK(30, 26)) >> 26)
#define SP_LP_FIFO_DEPTH(x) (((x) & GENMASK(25, 21)) >> 21)
#define VRS_FIFO_DEPTH(x) (((x) & GENMASK(20, 16)) >> 16)
#define DIRCMD_FIFO_DEPTH(x) (((x) & GENMASK(15, 13)) >> 13)
#define SDI_IFACE_32 BIT(12)
#define INTERNAL_DATAPATH_32 (0 << 10)
#define INTERNAL_DATAPATH_16 (1 << 10)
#define INTERNAL_DATAPATH_8 (3 << 10)
#define INTERNAL_DATAPATH_SIZE ((x) & GENMASK(11, 10))
#define NUM_IFACE(x) ((((x) & GENMASK(9, 8)) >> 8) + 1)
#define MAX_LANE_NB(x) (((x) & GENMASK(7, 6)) >> 6)
#define RX_FIFO_DEPTH(x) ((x) & GENMASK(5, 0))
#define MCTL_MAIN_DATA_CTL 0x4
#define TE_MIPI_POLLING_EN BIT(25)
#define TE_HW_POLLING_EN BIT(24)
#define DISP_EOT_GEN BIT(18)
#define HOST_EOT_GEN BIT(17)
#define DISP_GEN_CHECKSUM BIT(16)
#define DISP_GEN_ECC BIT(15)
#define BTA_EN BIT(14)
#define READ_EN BIT(13)
#define REG_TE_EN BIT(12)
#define IF_TE_EN(x) BIT(8 + (x))
#define TVG_SEL BIT(6)
#define VID_EN BIT(5)
#define IF_VID_SELECT(x) ((x) << 2)
#define IF_VID_SELECT_MASK GENMASK(3, 2)
#define IF_VID_MODE BIT(1)
#define LINK_EN BIT(0)
#define MCTL_MAIN_PHY_CTL 0x8
#define HS_INVERT_DAT(x) BIT(19 + ((x) * 2))
#define SWAP_PINS_DAT(x) BIT(18 + ((x) * 2))
#define HS_INVERT_CLK BIT(17)
#define SWAP_PINS_CLK BIT(16)
#define HS_SKEWCAL_EN BIT(15)
#define WAIT_BURST_TIME(x) ((x) << 10)
#define DATA_ULPM_EN(x) BIT(6 + (x))
#define CLK_ULPM_EN BIT(5)
#define CLK_CONTINUOUS BIT(4)
#define DATA_LANE_EN(x) BIT((x) - 1)
#define MCTL_MAIN_EN 0xc
#define DATA_FORCE_STOP BIT(17)
#define CLK_FORCE_STOP BIT(16)
#define IF_EN(x) BIT(13 + (x))
#define DATA_LANE_ULPM_REQ(l) BIT(9 + (l))
#define CLK_LANE_ULPM_REQ BIT(8)
#define DATA_LANE_START(x) BIT(4 + (x))
#define CLK_LANE_EN BIT(3)
#define PLL_START BIT(0)
#define MCTL_DPHY_CFG0 0x10
#define DPHY_C_RSTB BIT(20)
#define DPHY_D_RSTB(x) GENMASK(15 + (x), 16)
#define DPHY_PLL_PDN BIT(10)
#define DPHY_CMN_PDN BIT(9)
#define DPHY_C_PDN BIT(8)
#define DPHY_D_PDN(x) GENMASK(3 + (x), 4)
#define DPHY_ALL_D_PDN GENMASK(7, 4)
#define DPHY_PLL_PSO BIT(1)
#define DPHY_CMN_PSO BIT(0)
#define MCTL_DPHY_TIMEOUT1 0x14
#define HSTX_TIMEOUT(x) ((x) << 4)
#define HSTX_TIMEOUT_MAX GENMASK(17, 0)
#define CLK_DIV(x) (x)
#define CLK_DIV_MAX GENMASK(3, 0)
#define MCTL_DPHY_TIMEOUT2 0x18
#define LPRX_TIMEOUT(x) (x)
#define MCTL_ULPOUT_TIME 0x1c
#define DATA_LANE_ULPOUT_TIME(x) ((x) << 9)
#define CLK_LANE_ULPOUT_TIME(x) (x)
#define MCTL_3DVIDEO_CTL 0x20
#define VID_VSYNC_3D_EN BIT(7)
#define VID_VSYNC_3D_LR BIT(5)
#define VID_VSYNC_3D_SECOND_EN BIT(4)
#define VID_VSYNC_3DFORMAT_LINE (0 << 2)
#define VID_VSYNC_3DFORMAT_FRAME (1 << 2)
#define VID_VSYNC_3DFORMAT_PIXEL (2 << 2)
#define VID_VSYNC_3DMODE_OFF 0
#define VID_VSYNC_3DMODE_PORTRAIT 1
#define VID_VSYNC_3DMODE_LANDSCAPE 2
#define MCTL_MAIN_STS 0x24
#define MCTL_MAIN_STS_CTL 0x130
#define MCTL_MAIN_STS_CLR 0x150
#define MCTL_MAIN_STS_FLAG 0x170
#define HS_SKEWCAL_DONE BIT(11)
#define IF_UNTERM_PKT_ERR(x) BIT(8 + (x))
#define LPRX_TIMEOUT_ERR BIT(7)
#define HSTX_TIMEOUT_ERR BIT(6)
#define DATA_LANE_RDY(l) BIT(2 + (l))
#define CLK_LANE_RDY BIT(1)
#define PLL_LOCKED BIT(0)
#define MCTL_DPHY_ERR 0x28
#define MCTL_DPHY_ERR_CTL1 0x148
#define MCTL_DPHY_ERR_CLR 0x168
#define MCTL_DPHY_ERR_FLAG 0x188
#define ERR_CONT_LP(x, l) BIT(18 + ((x) * 4) + (l))
#define ERR_CONTROL(l) BIT(14 + (l))
#define ERR_SYNESC(l) BIT(10 + (l))
#define ERR_ESC(l) BIT(6 + (l))
#define MCTL_DPHY_ERR_CTL2 0x14c
#define ERR_CONT_LP_EDGE(x, l) BIT(12 + ((x) * 4) + (l))
#define ERR_CONTROL_EDGE(l) BIT(8 + (l))
#define ERR_SYN_ESC_EDGE(l) BIT(4 + (l))
#define ERR_ESC_EDGE(l) BIT(0 + (l))
#define MCTL_LANE_STS 0x2c
#define PPI_C_TX_READY_HS BIT(18)
#define DPHY_PLL_LOCK BIT(17)
#define PPI_D_RX_ULPS_ESC(x) (((x) & GENMASK(15, 12)) >> 12)
#define LANE_STATE_START 0
#define LANE_STATE_IDLE 1
#define LANE_STATE_WRITE 2
#define LANE_STATE_ULPM 3
#define LANE_STATE_READ 4
#define DATA_LANE_STATE(l, val) \
(((val) >> (2 + 2 * (l) + ((l) ? 1 : 0))) & GENMASK((l) ? 1 : 2, 0))
#define CLK_LANE_STATE_HS 2
#define CLK_LANE_STATE(val) ((val) & GENMASK(1, 0))
#define DSC_MODE_CTL 0x30
#define DSC_MODE_EN BIT(0)
#define DSC_CMD_SEND 0x34
#define DSC_SEND_PPS BIT(0)
#define DSC_EXECUTE_QUEUE BIT(1)
#define DSC_PPS_WRDAT 0x38
#define DSC_MODE_STS 0x3c
#define DSC_PPS_DONE BIT(1)
#define DSC_EXEC_DONE BIT(2)
#define CMD_MODE_CTL 0x70
#define IF_LP_EN(x) BIT(9 + (x))
#define IF_VCHAN_ID(x, c) ((c) << ((x) * 2))
#define CMD_MODE_CTL2 0x74
#define TE_TIMEOUT(x) ((x) << 11)
#define FILL_VALUE(x) ((x) << 3)
#define ARB_IF_WITH_HIGHEST_PRIORITY(x) ((x) << 1)
#define ARB_ROUND_ROBIN_MODE BIT(0)
#define CMD_MODE_STS 0x78
#define CMD_MODE_STS_CTL 0x134
#define CMD_MODE_STS_CLR 0x154
#define CMD_MODE_STS_FLAG 0x174
#define ERR_IF_UNDERRUN(x) BIT(4 + (x))
#define ERR_UNWANTED_READ BIT(3)
#define ERR_TE_MISS BIT(2)
#define ERR_NO_TE BIT(1)
#define CSM_RUNNING BIT(0)
#define DIRECT_CMD_SEND 0x80
#define DIRECT_CMD_MAIN_SETTINGS 0x84
#define TRIGGER_VAL(x) ((x) << 25)
#define CMD_LP_EN BIT(24)