linux/drivers/gpu/drm/loongson/lsdc_regs.h

/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright (C) 2023 Loongson Technology Corporation Limited
 */

#ifndef __LSDC_REGS_H__
#define __LSDC_REGS_H__

#include <linux/bitops.h>
#include <linux/types.h>

/*
 * PIXEL PLL Reference clock
 */
#define LSDC_PLL_REF_CLK_KHZ

/*
 * Those PLL registers are relative to LSxxxxx_CFG_REG_BASE. xxxxx = 7A1000,
 * 7A2000, 2K2000, 2K1000 etc.
 */

/* LS7A1000 */

#define LS7A1000_PIXPLL0_REG
#define LS7A1000_PIXPLL1_REG

/* The DC, GPU, Graphic Memory Controller share the single gfxpll */
#define LS7A1000_PLL_GFX_REG

#define LS7A1000_CONF_REG_BASE

/* LS7A2000 */

#define LS7A2000_PIXPLL0_REG
#define LS7A2000_PIXPLL1_REG

/* The DC, GPU, Graphic Memory Controller share the single gfxpll */
#define LS7A2000_PLL_GFX_REG

#define LS7A2000_CONF_REG_BASE

/* For LSDC_CRTCx_CFG_REG */
#define CFG_PIX_FMT_MASK

enum lsdc_pixel_format {};

/*
 * Each crtc has two set fb address registers usable, FB_REG_IN_USING bit of
 * LSDC_CRTCx_CFG_REG indicate which fb address register is in using by the
 * CRTC currently. CFG_PAGE_FLIP is used to trigger the switch, the switching
 * will be finished at the very next vblank. Trigger it again if you want to
 * switch back.
 *
 * If FB0_ADDR_REG is in using, we write the address to FB0_ADDR_REG,
 * if FB1_ADDR_REG is in using, we write the address to FB1_ADDR_REG.
 */
#define CFG_PAGE_FLIP
#define CFG_OUTPUT_ENABLE
#define CFG_HW_CLONE
/* Indicate witch fb addr reg is in using, currently. read only */
#define FB_REG_IN_USING
#define CFG_GAMMA_EN

/* The DC get soft reset if this bit changed from "1" to "0", active low */
#define CFG_RESET_N
/* If this bit is set, it say that the CRTC stop working anymore, anchored. */
#define CRTC_ANCHORED

/*
 * The DMA step of the DC in LS7A2000/LS2K2000 is configurable,
 * setting those bits on ls7a1000 platform make no effect.
 */
#define CFG_DMA_STEP_MASK
#define CFG_DMA_STEP_SHIFT
enum lsdc_dma_steps {};

#define CFG_VALID_BITS_MASK

/* For LSDC_CRTCx_HSYNC_REG */
#define HSYNC_INV
#define HSYNC_EN
#define HSYNC_END_MASK
#define HSYNC_END_SHIFT
#define HSYNC_START_MASK
#define HSYNC_START_SHIFT

/* For LSDC_CRTCx_VSYNC_REG */
#define VSYNC_INV
#define VSYNC_EN
#define VSYNC_END_MASK
#define VSYNC_END_SHIFT
#define VSYNC_START_MASK
#define VSYNC_START_SHIFT

/*********** CRTC0 ***********/
#define LSDC_CRTC0_CFG_REG
#define LSDC_CRTC0_FB0_ADDR_LO_REG
#define LSDC_CRTC0_FB0_ADDR_HI_REG
#define LSDC_CRTC0_STRIDE_REG
#define LSDC_CRTC0_FB_ORIGIN_REG
#define LSDC_CRTC0_HDISPLAY_REG
#define LSDC_CRTC0_HSYNC_REG
#define LSDC_CRTC0_VDISPLAY_REG
#define LSDC_CRTC0_VSYNC_REG
#define LSDC_CRTC0_GAMMA_INDEX_REG
#define LSDC_CRTC0_GAMMA_DATA_REG
#define LSDC_CRTC0_FB1_ADDR_LO_REG
#define LSDC_CRTC0_FB1_ADDR_HI_REG

/*********** CRTC1 ***********/
#define LSDC_CRTC1_CFG_REG
#define LSDC_CRTC1_FB0_ADDR_LO_REG
#define LSDC_CRTC1_FB0_ADDR_HI_REG
#define LSDC_CRTC1_STRIDE_REG
#define LSDC_CRTC1_FB_ORIGIN_REG
#define LSDC_CRTC1_HDISPLAY_REG
#define LSDC_CRTC1_HSYNC_REG
#define LSDC_CRTC1_VDISPLAY_REG
#define LSDC_CRTC1_VSYNC_REG
#define LSDC_CRTC1_GAMMA_INDEX_REG
#define LSDC_CRTC1_GAMMA_DATA_REG
#define LSDC_CRTC1_FB1_ADDR_LO_REG
#define LSDC_CRTC1_FB1_ADDR_HI_REG

/* For LSDC_CRTCx_DVO_CONF_REG */
#define PHY_CLOCK_POL
#define PHY_CLOCK_EN
#define PHY_DE_POL
#define PHY_DATA_EN

/*********** DVO0 ***********/
#define LSDC_CRTC0_DVO_CONF_REG

/*********** DVO1 ***********/
#define LSDC_CRTC1_DVO_CONF_REG

/*
 * All of the DC variants has the hardware which record the scan position
 * of the CRTC, [31:16] : current X position, [15:0] : current Y position
 */
#define LSDC_CRTC0_SCAN_POS_REG
#define LSDC_CRTC1_SCAN_POS_REG

/*
 * LS7A2000 has Sync Deviation register.
 */
#define SYNC_DEVIATION_EN
#define SYNC_DEVIATION_NUM
#define LSDC_CRTC0_SYNC_DEVIATION_REG
#define LSDC_CRTC1_SYNC_DEVIATION_REG

/*
 * In gross, LSDC_CRTC1_XXX_REG - LSDC_CRTC0_XXX_REG = 0x10, but not all of
 * the registers obey this rule, LSDC_CURSORx_XXX_REG just don't honor this.
 * This is the root cause we can't untangle the code by manpulating offset
 * of the register access simply. Our hardware engineers are lack experiance
 * when they design this...
 */
#define CRTC_PIPE_OFFSET

/*
 * There is only one hardware cursor unit in LS7A1000 and LS2K1000, let
 * CFG_HW_CLONE_EN bit be "1" could eliminate this embarrassment, we made
 * it on custom clone mode application. While LS7A2000 has two hardware
 * cursor unit which is good enough.
 */
#define CURSOR_FORMAT_MASK
#define CURSOR_FORMAT_SHIFT
enum lsdc_cursor_format {};

/*
 * LS7A1000 and LS2K1000 only support 32x32, LS2K2000 and LS7A2000 support
 * 64x64, but it seems that setting this bit make no harms on LS7A1000, it
 * just don't take effects.
 */
#define CURSOR_SIZE_SHIFT
enum lsdc_cursor_size {};

#define CURSOR_LOCATION_SHIFT
enum lsdc_cursor_location {};

#define LSDC_CURSOR0_CFG_REG
#define LSDC_CURSOR0_ADDR_LO_REG
#define LSDC_CURSOR0_ADDR_HI_REG
#define LSDC_CURSOR0_POSITION_REG
#define LSDC_CURSOR0_BG_COLOR_REG
#define LSDC_CURSOR0_FG_COLOR_REG

#define LSDC_CURSOR1_CFG_REG
#define LSDC_CURSOR1_ADDR_LO_REG
#define LSDC_CURSOR1_ADDR_HI_REG
#define LSDC_CURSOR1_POSITION_REG
#define LSDC_CURSOR1_BG_COLOR_REG
#define LSDC_CURSOR1_FG_COLOR_REG

/*
 * DC Interrupt Control Register, 32bit, Address Offset: 1570
 *
 * Bits 15:0 inidicate the interrupt status
 * Bits 31:16 control enable interrupts corresponding to bit 15:0 or not
 * Write 1 to enable, write 0 to disable
 *
 * RF: Read Finished
 * IDBU: Internal Data Buffer Underflow
 * IDBFU: Internal Data Buffer Fatal Underflow
 * CBRF: Cursor Buffer Read Finished Flag, no use.
 * FBRF0: CRTC-0 reading from its framebuffer finished.
 * FBRF1: CRTC-1 reading from its framebuffer finished.
 *
 * +-------+--------------------------+-------+--------+--------+-------+
 * | 31:27 |         26:16            | 15:11 |   10   |   9    |   8   |
 * +-------+--------------------------+-------+--------+--------+-------+
 * |  N/A  | Interrupt Enable Control |  N/A  | IDBFU0 | IDBFU1 | IDBU0 |
 * +-------+--------------------------+-------+--------+--------+-------+
 *
 * +-------+-------+-------+------+--------+--------+--------+--------+
 * |   7   |   6   |   5   |  4   |   3    |   2    |   1    |   0    |
 * +-------+-------+-------+------+--------+--------+--------+--------+
 * | IDBU1 | FBRF0 | FBRF1 | CRRF | HSYNC0 | VSYNC0 | HSYNC1 | VSYNC1 |
 * +-------+-------+-------+------+--------+--------+--------+--------+
 *
 * unfortunately, CRTC0's interrupt is mess with CRTC1's interrupt in one
 * register again.
 */

#define LSDC_INT_REG

#define INT_CRTC0_VSYNC
#define INT_CRTC0_HSYNC
#define INT_CRTC0_RF
#define INT_CRTC0_IDBU
#define INT_CRTC0_IDBFU

#define INT_CRTC1_VSYNC
#define INT_CRTC1_HSYNC
#define INT_CRTC1_RF
#define INT_CRTC1_IDBU
#define INT_CRTC1_IDBFU

#define INT_CRTC0_VSYNC_EN
#define INT_CRTC0_HSYNC_EN
#define INT_CRTC0_RF_EN
#define INT_CRTC0_IDBU_EN
#define INT_CRTC0_IDBFU_EN

#define INT_CRTC1_VSYNC_EN
#define INT_CRTC1_HSYNC_EN
#define INT_CRTC1_RF_EN
#define INT_CRTC1_IDBU_EN
#define INT_CRTC1_IDBFU_EN

#define INT_STATUS_MASK

/*
 * LS7A1000/LS7A2000 have 4 gpios which are used to emulated I2C.
 * They are under control of the LS7A_DC_GPIO_DAT_REG and LS7A_DC_GPIO_DIR_REG
 * register, Those GPIOs has no relationship whth the GPIO hardware on the
 * bridge chip itself. Those offsets are relative to DC register base address
 *
 * LS2k1000 don't have those registers, they use hardware i2c or general GPIO
 * emulated i2c from linux i2c subsystem.
 *
 * GPIO data register, address offset: 0x1650
 *   +---------------+-----------+-----------+
 *   | 7 | 6 | 5 | 4 |  3  |  2  |  1  |  0  |
 *   +---------------+-----------+-----------+
 *   |               |    DVO1   |    DVO0   |
 *   +      N/A      +-----------+-----------+
 *   |               | SCL | SDA | SCL | SDA |
 *   +---------------+-----------+-----------+
 */
#define LS7A_DC_GPIO_DAT_REG

/*
 *  GPIO Input/Output direction control register, address offset: 0x1660
 */
#define LS7A_DC_GPIO_DIR_REG

/*
 *  LS7A2000 has two built-in HDMI Encoder and one VGA encoder
 */

/*
 * Number of continuous packets may be present
 * in HDMI hblank and vblank zone, should >= 48
 */
#define LSDC_HDMI0_ZONE_REG
#define LSDC_HDMI1_ZONE_REG

#define HDMI_H_ZONE_IDLE_SHIFT
#define HDMI_V_ZONE_IDLE_SHIFT

/* HDMI Iterface Control Reg */
#define HDMI_INTERFACE_EN
#define HDMI_PACKET_EN
#define HDMI_AUDIO_EN
/*
 * Preamble:
 * Immediately preceding each video data period or data island period is the
 * preamble. This is a sequence of eight identical control characters that
 * indicate whether the upcoming data period is a video data period or is a
 * data island. The values of CTL0, CTL1, CTL2, and CTL3 indicate the type of
 * data period that follows.
 */
#define HDMI_VIDEO_PREAMBLE_MASK
#define HDMI_VIDEO_PREAMBLE_SHIFT
/* 1: hw i2c, 0: gpio emu i2c, shouldn't put in LSDC_HDMIx_INTF_CTRL_REG */
#define HW_I2C_EN
#define HDMI_CTL_PERIOD_MODE
#define LSDC_HDMI0_INTF_CTRL_REG
#define LSDC_HDMI1_INTF_CTRL_REG

#define HDMI_PHY_EN
#define HDMI_PHY_RESET_N
#define HDMI_PHY_TERM_L_EN
#define HDMI_PHY_TERM_H_EN
#define HDMI_PHY_TERM_DET_EN
#define HDMI_PHY_TERM_STATUS
#define LSDC_HDMI0_PHY_CTRL_REG
#define LSDC_HDMI1_PHY_CTRL_REG

/* High level duration need > 1us */
#define HDMI_PLL_ENABLE
#define HDMI_PLL_LOCKED
/* Bypass the software configured values, using default source from somewhere */
#define HDMI_PLL_BYPASS

#define HDMI_PLL_IDF_SHIFT
#define HDMI_PLL_IDF_MASK
#define HDMI_PLL_LF_SHIFT
#define HDMI_PLL_LF_MASK
#define HDMI_PLL_ODF_SHIFT
#define HDMI_PLL_ODF_MASK
#define LSDC_HDMI0_PHY_PLL_REG
#define LSDC_HDMI1_PHY_PLL_REG

/* LS7A2000/LS2K2000 has hpd status reg, while the two hdmi's status
 * located at the one register again.
 */
#define LSDC_HDMI_HPD_STATUS_REG
#define HDMI0_HPD_FLAG
#define HDMI1_HPD_FLAG

#define LSDC_HDMI0_PHY_CAL_REG
#define LSDC_HDMI1_PHY_CAL_REG

/* AVI InfoFrame */
#define LSDC_HDMI0_AVI_CONTENT0
#define LSDC_HDMI1_AVI_CONTENT0
#define LSDC_HDMI0_AVI_CONTENT1
#define LSDC_HDMI1_AVI_CONTENT1
#define LSDC_HDMI0_AVI_CONTENT2
#define LSDC_HDMI1_AVI_CONTENT2
#define LSDC_HDMI0_AVI_CONTENT3
#define LSDC_HDMI1_AVI_CONTENT3

/* 1: enable avi infoframe packet, 0: disable avi infoframe packet */
#define AVI_PKT_ENABLE
/* 1: send one every two frame, 0: send one each frame */
#define AVI_PKT_SEND_FREQ
/*
 * 1: write 1 to flush avi reg content0 ~ content3 to the packet to be send,
 * The hardware will clear this bit automatically.
 */
#define AVI_PKT_UPDATE

#define LSDC_HDMI0_AVI_INFO_CRTL_REG
#define LSDC_HDMI1_AVI_INFO_CRTL_REG

/*
 * LS7A2000 has the hardware which count the number of vblank generated
 */
#define LSDC_CRTC0_VSYNC_COUNTER_REG
#define LSDC_CRTC1_VSYNC_COUNTER_REG

/*
 * LS7A2000 has the audio hardware associate with the HDMI encoder.
 */
#define LSDC_HDMI0_AUDIO_PLL_LO_REG
#define LSDC_HDMI1_AUDIO_PLL_LO_REG

#define LSDC_HDMI0_AUDIO_PLL_HI_REG
#define LSDC_HDMI1_AUDIO_PLL_HI_REG

#endif