diff options
Diffstat (limited to 'drivers/gpu/drm/imx/dcss/dcss-dev.h')
-rw-r--r-- | drivers/gpu/drm/imx/dcss/dcss-dev.h | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.h b/drivers/gpu/drm/imx/dcss/dcss-dev.h new file mode 100644 index 000000000000..591a4b7a474e --- /dev/null +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.h @@ -0,0 +1,359 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 NXP. + */ + +#ifndef __DCSS_PRV_H__ +#define __DCSS_PRV_H__ + +#include <drm/drm_atomic.h> +#include <drm/drm_fourcc.h> +#include <linux/io.h> +#include <video/videomode.h> + +#define SET 0x04 +#define CLR 0x08 +#define TGL 0x0C + +#define dcss_writel(v, c) writel((v), (c)) +#define dcss_readl(c) readl(c) +#define dcss_set(v, c) writel((v), (c) + SET) +#define dcss_clr(v, c) writel((v), (c) + CLR) +#define dcss_toggle(v, c) writel((v), (c) + TGL) + +static inline void dcss_update(u32 v, u32 m, void __iomem *c) +{ + writel((readl(c) & ~(m)) | (v), (c)); +} + +#define DCSS_DBG_REG(reg) {.name = #reg, .ofs = reg} + +enum { + DCSS_IMX8MQ = 0, +}; + +struct dcss_type_data { + const char *name; + u32 blkctl_ofs; + u32 ctxld_ofs; + u32 rdsrc_ofs; + u32 wrscl_ofs; + u32 dtg_ofs; + u32 scaler_ofs; + u32 ss_ofs; + u32 dpr_ofs; + u32 dtrc_ofs; + u32 dec400d_ofs; + u32 hdr10_ofs; +}; + +struct dcss_debug_reg { + char *name; + u32 ofs; +}; + +enum dcss_ctxld_ctx_type { + CTX_DB, + CTX_SB_HP, /* high-priority */ + CTX_SB_LP, /* low-priority */ +}; + +struct dcss_dev { + struct device *dev; + const struct dcss_type_data *devtype; + struct device_node *of_port; + + u32 start_addr; + + struct dcss_blkctl *blkctl; + struct dcss_ctxld *ctxld; + struct dcss_dpr *dpr; + struct dcss_dtg *dtg; + struct dcss_ss *ss; + struct dcss_hdr10 *hdr10; + struct dcss_scaler *scaler; + struct dcss_dtrc *dtrc; + struct dcss_dec400d *dec400d; + struct dcss_wrscl *wrscl; + struct dcss_rdsrc *rdsrc; + + struct clk *apb_clk; + struct clk *axi_clk; + struct clk *pix_clk; + struct clk *rtrm_clk; + struct clk *dtrc_clk; + struct clk *pll_src_clk; + struct clk *pll_phy_ref_clk; + + void (*dcss_disable_callback)(void *data); + + bool clks_on; + bool bus_freq_on; + bool hdmi_output; +}; + +enum dcss_color_space { + DCSS_COLORSPACE_RGB, + DCSS_COLORSPACE_YUV, + DCSS_COLORSPACE_UNKNOWN, +}; + +struct dcss_dev *dcss_drv_dev_to_dcss(struct device *dev); +struct drm_device *dcss_drv_dev_to_drm(struct device *dev); +struct dcss_dev *dcss_dev_create(struct device *dev, bool mipi_output); +void dcss_dev_destroy(struct dcss_dev *dcss); +int dcss_dev_runtime_suspend(struct device *dev); +int dcss_dev_runtime_resume(struct device *dev); +int dcss_dev_suspend(struct device *dev); +int dcss_dev_resume(struct device *dev); + +/* BLKCTL */ +int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base); +void dcss_blkctl_cfg(struct dcss_blkctl *blkctl); +void dcss_blkctl_exit(struct dcss_blkctl *blkctl); + +/* CTXLD */ +int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base); +void dcss_ctxld_exit(struct dcss_ctxld *ctxld); +void dcss_ctxld_write(struct dcss_ctxld *ctxld, u32 ctx_id, + u32 val, u32 reg_idx); +int dcss_ctxld_resume(struct dcss_ctxld *dcss_ctxld); +int dcss_ctxld_suspend(struct dcss_ctxld *dcss_ctxld); +void dcss_ctxld_write_irqsafe(struct dcss_ctxld *ctlxd, u32 ctx_id, u32 val, + u32 reg_ofs); +void dcss_ctxld_kick(struct dcss_ctxld *ctxld); +bool dcss_ctxld_is_flushed(struct dcss_ctxld *ctxld); +int dcss_ctxld_enable(struct dcss_ctxld *ctxld); +void dcss_ctxld_register_dtg_disable_cb(struct dcss_ctxld *ctxld, + void (*cb)(void *), + void *data); +void dcss_ctxld_register_dtrc_cb(struct dcss_ctxld *ctxld, + bool (*cb)(void *), + void *data); + +/* DPR */ +enum dcss_tile_type { + TILE_LINEAR = 0, + TILE_GPU_STANDARD, + TILE_GPU_SUPER, + TILE_VPU_YUV420, + TILE_VPU_VP9, +}; + +enum dcss_pix_size { + PIX_SIZE_8, + PIX_SIZE_16, + PIX_SIZE_32, +}; + +int dcss_dpr_init(struct dcss_dev *dcss, unsigned long dpr_base); +void dcss_dpr_exit(struct dcss_dpr *dpr); +void dcss_dpr_write_sysctrl(struct dcss_dpr *dpr); +void dcss_dpr_set_res(struct dcss_dpr *dpr, int ch_num, u32 xres, u32 yres); +void dcss_dpr_addr_set(struct dcss_dpr *dpr, int ch_num, u32 luma_base_addr, + u32 chroma_base_addr, u16 pitch); +void dcss_dpr_enable(struct dcss_dpr *dpr, int ch_num, bool en); +void dcss_dpr_format_set(struct dcss_dpr *dpr, int ch_num, + const struct drm_format_info *format, u64 modifier); +void dcss_dpr_set_rotation(struct dcss_dpr *dpr, int ch_num, u32 rotation); + +/* DTG */ +int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base); +void dcss_dtg_exit(struct dcss_dtg *dtg); +bool dcss_dtg_vblank_irq_valid(struct dcss_dtg *dtg); +void dcss_dtg_vblank_irq_enable(struct dcss_dtg *dtg, bool en); +void dcss_dtg_vblank_irq_clear(struct dcss_dtg *dtg); +void dcss_dtg_sync_set(struct dcss_dtg *dtg, struct videomode *vm); +void dcss_dtg_css_set(struct dcss_dtg *dtg, bool out_is_yuv); +void dcss_dtg_enable(struct dcss_dtg *dtg, bool en, + struct completion *dis_completion); +bool dcss_dtg_is_enabled(struct dcss_dtg *dtg); +void dcss_dtg_ctxld_kick_irq_enable(struct dcss_dtg *dtg, bool en); +bool dcss_dtg_global_alpha_changed(struct dcss_dtg *dtg, int ch_num, int alpha); +void dcss_dtg_plane_alpha_set(struct dcss_dtg *dtg, int ch_num, + const struct drm_format_info *format, int alpha); +void dcss_dtg_plane_pos_set(struct dcss_dtg *dtg, int ch_num, + int px, int py, int pw, int ph); +void dcss_dtg_ch_enable(struct dcss_dtg *dtg, int ch_num, bool en); + +/* SUBSAM */ +int dcss_ss_init(struct dcss_dev *dcss, unsigned long subsam_base); +void dcss_ss_exit(struct dcss_ss *ss); +void dcss_ss_enable(struct dcss_ss *ss); +void dcss_ss_disable(struct dcss_ss *ss); +void dcss_ss_subsam_set(struct dcss_ss *ss, bool output_is_yuv); +void dcss_ss_sync_set(struct dcss_ss *ss, struct videomode *vm, + bool phsync, bool pvsync); + +/* SCALER */ +int dcss_scaler_init(struct dcss_dev *dcss, unsigned long scaler_base); +void dcss_scaler_exit(struct dcss_scaler *scl); +void dcss_scaler_setup(struct dcss_scaler *scl, int ch_num, + const struct drm_format_info *format, + int src_xres, int src_yres, int dst_xres, int dst_yres, + u32 vrefresh_hz); +void dcss_scaler_ch_enable(struct dcss_scaler *scl, int ch_num, bool en); +int dcss_scaler_get_min_max_ratios(struct dcss_scaler *scl, int ch_num, + int *min, int *max); +void dcss_scaler_write_sclctrl(struct dcss_scaler *scl); + +/* DEC400D */ + +#define VIV_VIDMEM_METADATA_MAGIC fourcc_code('v', 'i', 'v', 'm') + +/* Compressed format now was defined same as dec400d, should be general. */ +typedef enum _VIV_COMPRESS_FMT +{ + _VIV_CFMT_ARGB8 = 0, + _VIV_CFMT_XRGB8, + _VIV_CFMT_AYUV, + _VIV_CFMT_UYVY, + _VIV_CFMT_YUY2, + _VIV_CFMT_YUV_ONLY, + _VIV_CFMT_UV_MIX, + _VIV_CFMT_ARGB4, + _VIV_CFMT_XRGB4, + _VIV_CFMT_A1R5G5B5, + _VIV_CFMT_X1R5G5B5, + _VIV_CFMT_R5G6B5, + _VIV_CFMT_Z24S8, + _VIV_CFMT_Z24, + _VIV_CFMT_Z16, + _VIV_CFMT_A2R10G10B10, + _VIV_CFMT_BAYER, + _VIV_CFMT_SIGNED_BAYER, + _VIV_CFMT_VAA16, + _VIV_CFMT_S8, + + _VIV_CFMT_MAX, +} _VIV_COMPRESS_FMT; + +/* Metadata for cross-device fd share with additional (ts) info. */ +typedef struct _VIV_VIDMEM_METADATA +{ + uint32_t magic; + + int32_t ts_fd; + void * ts_dma_buf; + + uint32_t fc_enabled; + uint32_t fc_value; + uint32_t fc_value_upper; + + uint32_t compressed; + uint32_t compress_format; +} _VIV_VIDMEM_METADATA; + +int dcss_dec400d_init(struct dcss_dev *dcss, unsigned long dec400d_base); +void dcss_dec400d_exit(struct dcss_dec400d *dec400d); +void dcss_dec400d_bypass(struct dcss_dec400d *dec400d); +void dcss_dec400d_shadow_trig(struct dcss_dec400d *dec400d); +void dcss_dec400d_enable(struct dcss_dec400d *dec400d); +void dcss_dec400d_fast_clear_config(struct dcss_dec400d *dec400d, + u32 fc_value, + bool enable); +void dcss_dec400d_read_config(struct dcss_dec400d *dec400d, + u32 read_id, + bool compress_en, + u32 compress_format); +void dcss_dec400d_addr_set(struct dcss_dec400d *dec400d, u32 baddr, u32 caddr); + +/* HDR10 */ +enum dcss_hdr10_nonlinearity { + NL_REC2084, + NL_REC709, + NL_BT1886, + NL_2100HLG, + NL_SRGB, +}; + +enum dcss_hdr10_pixel_range { + PR_LIMITED, + PR_FULL, +}; + +enum dcss_hdr10_gamut { + G_REC2020, + G_REC709, + G_REC601_NTSC, + G_REC601_PAL, + G_ADOBE_ARGB, +}; + +struct dcss_hdr10_pipe_cfg { + bool is_yuv; + enum dcss_hdr10_nonlinearity nl; + enum dcss_hdr10_pixel_range pr; + enum dcss_hdr10_gamut g; +}; + +int dcss_hdr10_init(struct dcss_dev *dcss, unsigned long hdr10_base); +void dcss_hdr10_exit(struct dcss_hdr10 *hdr10); +void dcss_hdr10_setup(struct dcss_hdr10 *hdr10, int ch_num, + struct dcss_hdr10_pipe_cfg *ipipe_cfg, + struct dcss_hdr10_pipe_cfg *opipe_cfg); + +/* enums common to both WRSCL and RDSRC */ +enum dcss_wrscl_rdsrc_psize { + PSIZE_64, + PSIZE_128, + PSIZE_256, + PSIZE_512, + PSIZE_1024, + PSIZE_2048, + PSIZE_4096, +}; + +enum dcss_wrscl_rdsrc_tsize { + TSIZE_64, + TSIZE_128, + TSIZE_256, + TSIZE_512, +}; + +enum dcss_wrscl_rdsrc_fifo_size { + FIFO_512, + FIFO_1024, + FIFO_2048, + FIFO_4096, +}; + +enum dcss_wrscl_rdsrc_bpp { + BPP_38, /* 38 bit unpacked components */ + BPP_32_UPCONVERT, + BPP_32_10BIT_OUTPUT, + BPP_20, /* 10-bit YUV422 */ + BPP_16, /* 8-bit YUV422 */ +}; + +/* WRSCL */ +int dcss_wrscl_init(struct dcss_dev *dcss, unsigned long wrscl_base); +void dcss_wrscl_exit(struct dcss_wrscl *wrscl); +u32 dcss_wrscl_setup(struct dcss_wrscl *wrscl, u32 pix_format, u32 pix_clk_hz, + u32 dst_xres, u32 dst_yres); +void dcss_wrscl_enable(struct dcss_wrscl *wrscl); +void dcss_wrscl_disable(struct dcss_wrscl *wrscl); + +/* RDSRC */ +int dcss_rdsrc_init(struct dcss_dev *dcss, unsigned long rdsrc_base); +void dcss_rdsrc_exit(struct dcss_rdsrc *rdsrc); +void dcss_rdsrc_setup(struct dcss_rdsrc *rdsrc, u32 pix_format, u32 dst_xres, + u32 dst_yres, u32 base_addr); +void dcss_rdsrc_enable(struct dcss_rdsrc *rdsrc); +void dcss_rdsrc_disable(struct dcss_rdsrc *rdsrc); + +/* DTRC */ +int dcss_dtrc_init(struct dcss_dev *dcss, unsigned long dtrc_base); +void dcss_dtrc_exit(struct dcss_dtrc *dtrc); +void dcss_dtrc_bypass(struct dcss_dtrc *dtrc, int ch_num); +void dcss_dtrc_set_format_mod(struct dcss_dtrc *dtrc, int ch_num, u64 modifier); +void dcss_dtrc_addr_set(struct dcss_dtrc *dtrc, int ch_num, + u32 p1_ba, u32 p2_ba, uint64_t dec_table_ofs); +bool dcss_dtrc_ch_running(struct dcss_dtrc *dtrc, int ch_num); +bool dcss_dtrc_is_running(struct dcss_dtrc *dtrc); +void dcss_dtrc_enable(struct dcss_dtrc *dtrc, int ch_num, bool enable); +void dcss_dtrc_set_res(struct dcss_dtrc *dtrc, int ch_num, + struct drm_plane_state *state, u32 *dtrc_w, u32 *dtrc_h); +void dcss_dtrc_switch_banks(struct dcss_dtrc *dtrc); + +#endif /* __DCSS_PRV_H__ */ |