457 lines
12 KiB
C
457 lines
12 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
|
|
* Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
|
|
*/
|
|
|
|
#ifndef __OMAP_DRM_DSS_DSI_H
|
|
#define __OMAP_DRM_DSS_DSI_H
|
|
|
|
#include <drm/drm_mipi_dsi.h>
|
|
|
|
struct dsi_reg {
|
|
u16 module;
|
|
u16 idx;
|
|
};
|
|
|
|
#define DSI_REG(mod, idx) ((const struct dsi_reg) { mod, idx })
|
|
|
|
/* DSI Protocol Engine */
|
|
|
|
#define DSI_PROTO 0
|
|
#define DSI_PROTO_SZ 0x200
|
|
|
|
#define DSI_REVISION DSI_REG(DSI_PROTO, 0x0000)
|
|
#define DSI_SYSCONFIG DSI_REG(DSI_PROTO, 0x0010)
|
|
#define DSI_SYSSTATUS DSI_REG(DSI_PROTO, 0x0014)
|
|
#define DSI_IRQSTATUS DSI_REG(DSI_PROTO, 0x0018)
|
|
#define DSI_IRQENABLE DSI_REG(DSI_PROTO, 0x001C)
|
|
#define DSI_CTRL DSI_REG(DSI_PROTO, 0x0040)
|
|
#define DSI_GNQ DSI_REG(DSI_PROTO, 0x0044)
|
|
#define DSI_COMPLEXIO_CFG1 DSI_REG(DSI_PROTO, 0x0048)
|
|
#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(DSI_PROTO, 0x004C)
|
|
#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(DSI_PROTO, 0x0050)
|
|
#define DSI_CLK_CTRL DSI_REG(DSI_PROTO, 0x0054)
|
|
#define DSI_TIMING1 DSI_REG(DSI_PROTO, 0x0058)
|
|
#define DSI_TIMING2 DSI_REG(DSI_PROTO, 0x005C)
|
|
#define DSI_VM_TIMING1 DSI_REG(DSI_PROTO, 0x0060)
|
|
#define DSI_VM_TIMING2 DSI_REG(DSI_PROTO, 0x0064)
|
|
#define DSI_VM_TIMING3 DSI_REG(DSI_PROTO, 0x0068)
|
|
#define DSI_CLK_TIMING DSI_REG(DSI_PROTO, 0x006C)
|
|
#define DSI_TX_FIFO_VC_SIZE DSI_REG(DSI_PROTO, 0x0070)
|
|
#define DSI_RX_FIFO_VC_SIZE DSI_REG(DSI_PROTO, 0x0074)
|
|
#define DSI_COMPLEXIO_CFG2 DSI_REG(DSI_PROTO, 0x0078)
|
|
#define DSI_RX_FIFO_VC_FULLNESS DSI_REG(DSI_PROTO, 0x007C)
|
|
#define DSI_VM_TIMING4 DSI_REG(DSI_PROTO, 0x0080)
|
|
#define DSI_TX_FIFO_VC_EMPTINESS DSI_REG(DSI_PROTO, 0x0084)
|
|
#define DSI_VM_TIMING5 DSI_REG(DSI_PROTO, 0x0088)
|
|
#define DSI_VM_TIMING6 DSI_REG(DSI_PROTO, 0x008C)
|
|
#define DSI_VM_TIMING7 DSI_REG(DSI_PROTO, 0x0090)
|
|
#define DSI_STOPCLK_TIMING DSI_REG(DSI_PROTO, 0x0094)
|
|
#define DSI_VC_CTRL(n) DSI_REG(DSI_PROTO, 0x0100 + (n * 0x20))
|
|
#define DSI_VC_TE(n) DSI_REG(DSI_PROTO, 0x0104 + (n * 0x20))
|
|
#define DSI_VC_LONG_PACKET_HEADER(n) DSI_REG(DSI_PROTO, 0x0108 + (n * 0x20))
|
|
#define DSI_VC_LONG_PACKET_PAYLOAD(n) DSI_REG(DSI_PROTO, 0x010C + (n * 0x20))
|
|
#define DSI_VC_SHORT_PACKET_HEADER(n) DSI_REG(DSI_PROTO, 0x0110 + (n * 0x20))
|
|
#define DSI_VC_IRQSTATUS(n) DSI_REG(DSI_PROTO, 0x0118 + (n * 0x20))
|
|
#define DSI_VC_IRQENABLE(n) DSI_REG(DSI_PROTO, 0x011C + (n * 0x20))
|
|
|
|
/* DSIPHY_SCP */
|
|
|
|
#define DSI_PHY 1
|
|
#define DSI_PHY_OFFSET 0x200
|
|
#define DSI_PHY_SZ 0x40
|
|
|
|
#define DSI_DSIPHY_CFG0 DSI_REG(DSI_PHY, 0x0000)
|
|
#define DSI_DSIPHY_CFG1 DSI_REG(DSI_PHY, 0x0004)
|
|
#define DSI_DSIPHY_CFG2 DSI_REG(DSI_PHY, 0x0008)
|
|
#define DSI_DSIPHY_CFG5 DSI_REG(DSI_PHY, 0x0014)
|
|
#define DSI_DSIPHY_CFG10 DSI_REG(DSI_PHY, 0x0028)
|
|
|
|
/* DSI_PLL_CTRL_SCP */
|
|
|
|
#define DSI_PLL 2
|
|
#define DSI_PLL_OFFSET 0x300
|
|
#define DSI_PLL_SZ 0x20
|
|
|
|
#define DSI_PLL_CONTROL DSI_REG(DSI_PLL, 0x0000)
|
|
#define DSI_PLL_STATUS DSI_REG(DSI_PLL, 0x0004)
|
|
#define DSI_PLL_GO DSI_REG(DSI_PLL, 0x0008)
|
|
#define DSI_PLL_CONFIGURATION1 DSI_REG(DSI_PLL, 0x000C)
|
|
#define DSI_PLL_CONFIGURATION2 DSI_REG(DSI_PLL, 0x0010)
|
|
|
|
/* Global interrupts */
|
|
#define DSI_IRQ_VC0 (1 << 0)
|
|
#define DSI_IRQ_VC1 (1 << 1)
|
|
#define DSI_IRQ_VC2 (1 << 2)
|
|
#define DSI_IRQ_VC3 (1 << 3)
|
|
#define DSI_IRQ_WAKEUP (1 << 4)
|
|
#define DSI_IRQ_RESYNC (1 << 5)
|
|
#define DSI_IRQ_PLL_LOCK (1 << 7)
|
|
#define DSI_IRQ_PLL_UNLOCK (1 << 8)
|
|
#define DSI_IRQ_PLL_RECALL (1 << 9)
|
|
#define DSI_IRQ_COMPLEXIO_ERR (1 << 10)
|
|
#define DSI_IRQ_HS_TX_TIMEOUT (1 << 14)
|
|
#define DSI_IRQ_LP_RX_TIMEOUT (1 << 15)
|
|
#define DSI_IRQ_TE_TRIGGER (1 << 16)
|
|
#define DSI_IRQ_ACK_TRIGGER (1 << 17)
|
|
#define DSI_IRQ_SYNC_LOST (1 << 18)
|
|
#define DSI_IRQ_LDO_POWER_GOOD (1 << 19)
|
|
#define DSI_IRQ_TA_TIMEOUT (1 << 20)
|
|
#define DSI_IRQ_ERROR_MASK \
|
|
(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
|
|
DSI_IRQ_TA_TIMEOUT)
|
|
#define DSI_IRQ_CHANNEL_MASK 0xf
|
|
|
|
/* Virtual channel interrupts */
|
|
#define DSI_VC_IRQ_CS (1 << 0)
|
|
#define DSI_VC_IRQ_ECC_CORR (1 << 1)
|
|
#define DSI_VC_IRQ_PACKET_SENT (1 << 2)
|
|
#define DSI_VC_IRQ_FIFO_TX_OVF (1 << 3)
|
|
#define DSI_VC_IRQ_FIFO_RX_OVF (1 << 4)
|
|
#define DSI_VC_IRQ_BTA (1 << 5)
|
|
#define DSI_VC_IRQ_ECC_NO_CORR (1 << 6)
|
|
#define DSI_VC_IRQ_FIFO_TX_UDF (1 << 7)
|
|
#define DSI_VC_IRQ_PP_BUSY_CHANGE (1 << 8)
|
|
#define DSI_VC_IRQ_ERROR_MASK \
|
|
(DSI_VC_IRQ_CS | DSI_VC_IRQ_ECC_CORR | DSI_VC_IRQ_FIFO_TX_OVF | \
|
|
DSI_VC_IRQ_FIFO_RX_OVF | DSI_VC_IRQ_ECC_NO_CORR | \
|
|
DSI_VC_IRQ_FIFO_TX_UDF)
|
|
|
|
/* ComplexIO interrupts */
|
|
#define DSI_CIO_IRQ_ERRSYNCESC1 (1 << 0)
|
|
#define DSI_CIO_IRQ_ERRSYNCESC2 (1 << 1)
|
|
#define DSI_CIO_IRQ_ERRSYNCESC3 (1 << 2)
|
|
#define DSI_CIO_IRQ_ERRSYNCESC4 (1 << 3)
|
|
#define DSI_CIO_IRQ_ERRSYNCESC5 (1 << 4)
|
|
#define DSI_CIO_IRQ_ERRESC1 (1 << 5)
|
|
#define DSI_CIO_IRQ_ERRESC2 (1 << 6)
|
|
#define DSI_CIO_IRQ_ERRESC3 (1 << 7)
|
|
#define DSI_CIO_IRQ_ERRESC4 (1 << 8)
|
|
#define DSI_CIO_IRQ_ERRESC5 (1 << 9)
|
|
#define DSI_CIO_IRQ_ERRCONTROL1 (1 << 10)
|
|
#define DSI_CIO_IRQ_ERRCONTROL2 (1 << 11)
|
|
#define DSI_CIO_IRQ_ERRCONTROL3 (1 << 12)
|
|
#define DSI_CIO_IRQ_ERRCONTROL4 (1 << 13)
|
|
#define DSI_CIO_IRQ_ERRCONTROL5 (1 << 14)
|
|
#define DSI_CIO_IRQ_STATEULPS1 (1 << 15)
|
|
#define DSI_CIO_IRQ_STATEULPS2 (1 << 16)
|
|
#define DSI_CIO_IRQ_STATEULPS3 (1 << 17)
|
|
#define DSI_CIO_IRQ_STATEULPS4 (1 << 18)
|
|
#define DSI_CIO_IRQ_STATEULPS5 (1 << 19)
|
|
#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1 (1 << 20)
|
|
#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1 (1 << 21)
|
|
#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2 (1 << 22)
|
|
#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2 (1 << 23)
|
|
#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3 (1 << 24)
|
|
#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25)
|
|
#define DSI_CIO_IRQ_ERRCONTENTIONLP0_4 (1 << 26)
|
|
#define DSI_CIO_IRQ_ERRCONTENTIONLP1_4 (1 << 27)
|
|
#define DSI_CIO_IRQ_ERRCONTENTIONLP0_5 (1 << 28)
|
|
#define DSI_CIO_IRQ_ERRCONTENTIONLP1_5 (1 << 29)
|
|
#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30)
|
|
#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31)
|
|
#define DSI_CIO_IRQ_ERROR_MASK \
|
|
(DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \
|
|
DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRSYNCESC4 | \
|
|
DSI_CIO_IRQ_ERRSYNCESC5 | \
|
|
DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \
|
|
DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRESC4 | \
|
|
DSI_CIO_IRQ_ERRESC5 | \
|
|
DSI_CIO_IRQ_ERRCONTROL1 | DSI_CIO_IRQ_ERRCONTROL2 | \
|
|
DSI_CIO_IRQ_ERRCONTROL3 | DSI_CIO_IRQ_ERRCONTROL4 | \
|
|
DSI_CIO_IRQ_ERRCONTROL5 | \
|
|
DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \
|
|
DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \
|
|
DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3 | \
|
|
DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \
|
|
DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5)
|
|
|
|
enum omap_dss_dsi_mode {
|
|
OMAP_DSS_DSI_CMD_MODE = 0,
|
|
OMAP_DSS_DSI_VIDEO_MODE,
|
|
};
|
|
|
|
enum omap_dss_dsi_trans_mode {
|
|
/* Sync Pulses: both sync start and end packets sent */
|
|
OMAP_DSS_DSI_PULSE_MODE,
|
|
/* Sync Events: only sync start packets sent */
|
|
OMAP_DSS_DSI_EVENT_MODE,
|
|
/* Burst: only sync start packets sent, pixels are time compressed */
|
|
OMAP_DSS_DSI_BURST_MODE,
|
|
};
|
|
|
|
struct omap_dss_dsi_videomode_timings {
|
|
unsigned long hsclk;
|
|
|
|
unsigned int ndl;
|
|
unsigned int bitspp;
|
|
|
|
/* pixels */
|
|
u16 hact;
|
|
/* lines */
|
|
u16 vact;
|
|
|
|
/* DSI video mode blanking data */
|
|
/* Unit: byte clock cycles */
|
|
u16 hss;
|
|
u16 hsa;
|
|
u16 hse;
|
|
u16 hfp;
|
|
u16 hbp;
|
|
/* Unit: line clocks */
|
|
u16 vsa;
|
|
u16 vfp;
|
|
u16 vbp;
|
|
|
|
/* DSI blanking modes */
|
|
int blanking_mode;
|
|
int hsa_blanking_mode;
|
|
int hbp_blanking_mode;
|
|
int hfp_blanking_mode;
|
|
|
|
enum omap_dss_dsi_trans_mode trans_mode;
|
|
|
|
int window_sync;
|
|
};
|
|
|
|
struct omap_dss_dsi_config {
|
|
enum omap_dss_dsi_mode mode;
|
|
enum mipi_dsi_pixel_format pixel_format;
|
|
const struct videomode *vm;
|
|
|
|
unsigned long hs_clk_min, hs_clk_max;
|
|
unsigned long lp_clk_min, lp_clk_max;
|
|
|
|
enum omap_dss_dsi_trans_mode trans_mode;
|
|
};
|
|
|
|
/* DSI PLL HSDIV indices */
|
|
#define HSDIV_DISPC 0
|
|
#define HSDIV_DSI 1
|
|
|
|
#define DSI_MAX_NR_ISRS 2
|
|
#define DSI_MAX_NR_LANES 5
|
|
|
|
enum dsi_model {
|
|
DSI_MODEL_OMAP3,
|
|
DSI_MODEL_OMAP4,
|
|
DSI_MODEL_OMAP5,
|
|
};
|
|
|
|
enum dsi_lane_function {
|
|
DSI_LANE_UNUSED = 0,
|
|
DSI_LANE_CLK,
|
|
DSI_LANE_DATA1,
|
|
DSI_LANE_DATA2,
|
|
DSI_LANE_DATA3,
|
|
DSI_LANE_DATA4,
|
|
};
|
|
|
|
struct dsi_lane_config {
|
|
enum dsi_lane_function function;
|
|
u8 polarity;
|
|
};
|
|
|
|
typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
|
|
|
|
struct dsi_isr_data {
|
|
omap_dsi_isr_t isr;
|
|
void *arg;
|
|
u32 mask;
|
|
};
|
|
|
|
enum fifo_size {
|
|
DSI_FIFO_SIZE_0 = 0,
|
|
DSI_FIFO_SIZE_32 = 1,
|
|
DSI_FIFO_SIZE_64 = 2,
|
|
DSI_FIFO_SIZE_96 = 3,
|
|
DSI_FIFO_SIZE_128 = 4,
|
|
};
|
|
|
|
enum dsi_vc_source {
|
|
DSI_VC_SOURCE_L4 = 0,
|
|
DSI_VC_SOURCE_VP,
|
|
};
|
|
|
|
struct dsi_irq_stats {
|
|
unsigned long last_reset;
|
|
unsigned int irq_count;
|
|
unsigned int dsi_irqs[32];
|
|
unsigned int vc_irqs[4][32];
|
|
unsigned int cio_irqs[32];
|
|
};
|
|
|
|
struct dsi_isr_tables {
|
|
struct dsi_isr_data isr_table[DSI_MAX_NR_ISRS];
|
|
struct dsi_isr_data isr_table_vc[4][DSI_MAX_NR_ISRS];
|
|
struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
|
|
};
|
|
|
|
struct dsi_lp_clock_info {
|
|
unsigned long lp_clk;
|
|
u16 lp_clk_div;
|
|
};
|
|
|
|
struct dsi_clk_calc_ctx {
|
|
struct dsi_data *dsi;
|
|
struct dss_pll *pll;
|
|
|
|
/* inputs */
|
|
|
|
const struct omap_dss_dsi_config *config;
|
|
|
|
unsigned long req_pck_min, req_pck_nom, req_pck_max;
|
|
|
|
/* outputs */
|
|
|
|
struct dss_pll_clock_info dsi_cinfo;
|
|
struct dispc_clock_info dispc_cinfo;
|
|
struct dsi_lp_clock_info lp_cinfo;
|
|
|
|
struct videomode vm;
|
|
struct omap_dss_dsi_videomode_timings dsi_vm;
|
|
};
|
|
|
|
struct dsi_module_id_data {
|
|
u32 address;
|
|
int id;
|
|
};
|
|
|
|
enum dsi_quirks {
|
|
DSI_QUIRK_PLL_PWR_BUG = (1 << 0), /* DSI-PLL power command 0x3 is not working */
|
|
DSI_QUIRK_DCS_CMD_CONFIG_VC = (1 << 1),
|
|
DSI_QUIRK_VC_OCP_WIDTH = (1 << 2),
|
|
DSI_QUIRK_REVERSE_TXCLKESC = (1 << 3),
|
|
DSI_QUIRK_GNQ = (1 << 4),
|
|
DSI_QUIRK_PHY_DCC = (1 << 5),
|
|
};
|
|
|
|
struct dsi_of_data {
|
|
enum dsi_model model;
|
|
const struct dss_pll_hw *pll_hw;
|
|
const struct dsi_module_id_data *modules;
|
|
unsigned int max_fck_freq;
|
|
unsigned int max_pll_lpdiv;
|
|
enum dsi_quirks quirks;
|
|
};
|
|
|
|
struct dsi_data {
|
|
struct device *dev;
|
|
void __iomem *proto_base;
|
|
void __iomem *phy_base;
|
|
void __iomem *pll_base;
|
|
|
|
const struct dsi_of_data *data;
|
|
int module_id;
|
|
|
|
int irq;
|
|
|
|
bool is_enabled;
|
|
|
|
struct clk *dss_clk;
|
|
struct regmap *syscon;
|
|
struct dss_device *dss;
|
|
|
|
struct mipi_dsi_host host;
|
|
|
|
struct dispc_clock_info user_dispc_cinfo;
|
|
struct dss_pll_clock_info user_dsi_cinfo;
|
|
|
|
struct dsi_lp_clock_info user_lp_cinfo;
|
|
struct dsi_lp_clock_info current_lp_cinfo;
|
|
|
|
struct dss_pll pll;
|
|
|
|
bool vdds_dsi_enabled;
|
|
struct regulator *vdds_dsi_reg;
|
|
|
|
struct mipi_dsi_device *dsidev;
|
|
|
|
struct {
|
|
enum dsi_vc_source source;
|
|
enum fifo_size tx_fifo_size;
|
|
enum fifo_size rx_fifo_size;
|
|
} vc[4];
|
|
|
|
struct mutex lock;
|
|
struct semaphore bus_lock;
|
|
|
|
spinlock_t irq_lock;
|
|
struct dsi_isr_tables isr_tables;
|
|
/* space for a copy used by the interrupt handler */
|
|
struct dsi_isr_tables isr_tables_copy;
|
|
|
|
int update_vc;
|
|
#ifdef DSI_PERF_MEASURE
|
|
unsigned int update_bytes;
|
|
#endif
|
|
|
|
/* external TE GPIO */
|
|
struct gpio_desc *te_gpio;
|
|
int te_irq;
|
|
struct delayed_work te_timeout_work;
|
|
atomic_t do_ext_te_update;
|
|
|
|
bool te_enabled;
|
|
bool iface_enabled;
|
|
bool video_enabled;
|
|
|
|
struct delayed_work framedone_timeout_work;
|
|
|
|
#ifdef DSI_CATCH_MISSING_TE
|
|
struct timer_list te_timer;
|
|
#endif
|
|
|
|
unsigned long cache_req_pck;
|
|
unsigned long cache_clk_freq;
|
|
struct dss_pll_clock_info cache_cinfo;
|
|
|
|
u32 errors;
|
|
spinlock_t errors_lock;
|
|
#ifdef DSI_PERF_MEASURE
|
|
ktime_t perf_setup_time;
|
|
ktime_t perf_start_time;
|
|
#endif
|
|
int debug_read;
|
|
int debug_write;
|
|
struct {
|
|
struct dss_debugfs_entry *irqs;
|
|
struct dss_debugfs_entry *regs;
|
|
struct dss_debugfs_entry *clks;
|
|
} debugfs;
|
|
|
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
|
spinlock_t irq_stats_lock;
|
|
struct dsi_irq_stats irq_stats;
|
|
#endif
|
|
|
|
unsigned int num_lanes_supported;
|
|
unsigned int line_buffer_size;
|
|
|
|
struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
|
|
unsigned int num_lanes_used;
|
|
|
|
unsigned int scp_clk_refcount;
|
|
|
|
struct omap_dss_dsi_config config;
|
|
|
|
struct dss_lcd_mgr_config mgr_config;
|
|
struct videomode vm;
|
|
enum mipi_dsi_pixel_format pix_fmt;
|
|
enum omap_dss_dsi_mode mode;
|
|
struct omap_dss_dsi_videomode_timings vm_timings;
|
|
|
|
struct omap_dss_device output;
|
|
struct drm_bridge bridge;
|
|
|
|
struct delayed_work dsi_disable_work;
|
|
};
|
|
|
|
struct dsi_packet_sent_handler_data {
|
|
struct dsi_data *dsi;
|
|
struct completion *completion;
|
|
};
|
|
|
|
#endif /* __OMAP_DRM_DSS_DSI_H */
|