/* 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