18c2ecf20Sopenharmony_ci#ifndef __LOONGSON_DRV_H__ 28c2ecf20Sopenharmony_ci#define __LOONGSON_DRV_H__ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <linux/i2c.h> 58c2ecf20Sopenharmony_ci#include <linux/i2c-algo-bit.h> 68c2ecf20Sopenharmony_ci#include <linux/module.h> 78c2ecf20Sopenharmony_ci#include <linux/types.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <drm/drm_drv.h> 108c2ecf20Sopenharmony_ci#include <drm/drm_encoder.h> 118c2ecf20Sopenharmony_ci#include <drm/drm_fb_helper.h> 128c2ecf20Sopenharmony_ci#include <drm/drm_gem.h> 138c2ecf20Sopenharmony_ci#include <drm/drm_irq.h> 148c2ecf20Sopenharmony_ci#include <drm/drm_vblank.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include <loongson.h> 178c2ecf20Sopenharmony_ci#include "loongson_i2c.h" 188c2ecf20Sopenharmony_ci#include "loongson_vbios.h" 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define to_loongson_crtc(x) container_of(x, struct loongson_crtc, base) 218c2ecf20Sopenharmony_ci#define to_loongson_encoder(x) container_of(x, struct loongson_encoder, base) 228c2ecf20Sopenharmony_ci#define to_loongson_connector(x) container_of(x, struct loongson_connector, base) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define LOONGSON_MAX_FB_HEIGHT 4096 258c2ecf20Sopenharmony_ci#define LOONGSON_MAX_FB_WIDTH 4096 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define CUR_WIDTH_SIZE 32 288c2ecf20Sopenharmony_ci#define CUR_HEIGHT_SIZE 32 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define LO_OFF 0 318c2ecf20Sopenharmony_ci#define HI_OFF 8 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define LS7A_PIX0_PLL (void *)TO_UNCACHE(LS7A_CHIPCFG_REG_BASE + 0x04b0) 348c2ecf20Sopenharmony_ci#define LS7A_PIX1_PLL (void *)TO_UNCACHE(LS7A_CHIPCFG_REG_BASE + 0x04c0) 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define CURIOSET_CORLOR 0x4607 378c2ecf20Sopenharmony_ci#define CURIOSET_POSITION 0x4608 388c2ecf20Sopenharmony_ci#define CURIOLOAD_ARGB 0x4609 398c2ecf20Sopenharmony_ci#define CURIOLOAD_IMAGE 0x460A 408c2ecf20Sopenharmony_ci#define CURIOHIDE_SHOW 0x460B 418c2ecf20Sopenharmony_ci#define FBEDID_GET 0X860C 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define CRTC_REG_OFFSET 0x10 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define CFG_FMT GENMASK(2,0) 468c2ecf20Sopenharmony_ci#define CFG_FBSWITCH BIT(7) 478c2ecf20Sopenharmony_ci#define CFG_ENABLE BIT(8) 488c2ecf20Sopenharmony_ci#define CFG_PANELSWITCH BIT(9) 498c2ecf20Sopenharmony_ci#define CFG_FBNUM_BIT 11 508c2ecf20Sopenharmony_ci#define CFG_FBNUM BIT(11) 518c2ecf20Sopenharmony_ci#define CFG_GAMMAR BIT(12) 528c2ecf20Sopenharmony_ci#define CFG_RESET BIT(20) 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci#define FB_CFG_DVO_REG (0x1240) 558c2ecf20Sopenharmony_ci#define FB_ADDR0_DVO_REG (0x1260) 568c2ecf20Sopenharmony_ci#define FB_ADDR1_DVO_REG (0x1580) 578c2ecf20Sopenharmony_ci#define FB_STRI_DVO_REG (0x1280) 588c2ecf20Sopenharmony_ci#define FB_DITCFG_DVO_REG (0x1360) 598c2ecf20Sopenharmony_ci#define FB_DITTAB_LO_DVO_REG (0x1380) 608c2ecf20Sopenharmony_ci#define FB_DITTAB_HI_DVO_REG (0x13a0) 618c2ecf20Sopenharmony_ci#define FB_PANCFG_DVO_REG (0x13c0) 628c2ecf20Sopenharmony_ci#define FB_PANTIM_DVO_REG (0x13e0) 638c2ecf20Sopenharmony_ci#define FB_HDISPLAY_DVO_REG (0x1400) 648c2ecf20Sopenharmony_ci#define FB_HSYNC_DVO_REG (0x1420) 658c2ecf20Sopenharmony_ci#define FB_VDISPLAY_DVO_REG (0x1480) 668c2ecf20Sopenharmony_ci#define FB_VSYNC_DVO_REG (0x14a0) 678c2ecf20Sopenharmony_ci#define FB_GAMINDEX_DVO_REG (0x14e0) 688c2ecf20Sopenharmony_ci#define FB_GAMDATA_DVO_REG (0x1500) 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci#define HDMI_ZONEIDLE_REG (0x1700) 718c2ecf20Sopenharmony_ci#define HDMI_CTRL_REG (0x1720) 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci#define HDMI_AUDIO_BUF_REG (0x1740) 748c2ecf20Sopenharmony_ci#define HDMI_AUDIO_NCFG_REG (0x1760) 758c2ecf20Sopenharmony_ci#define HDMI_AUDIO_CTSCFG_REG (0x1780) 768c2ecf20Sopenharmony_ci#define HDMI_AUDIO_CTSCALCFG_REG (0x17a0) 778c2ecf20Sopenharmony_ci#define HDMI_AUDIO_INFOFRAME_REG (0x17c0) 788c2ecf20Sopenharmony_ci#define HDMI_AUDIO_SAMPLE_REG (0x17e0) 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#define HDMI_PHY_CTRL_REG (0x1800) 818c2ecf20Sopenharmony_ci#define HDMI_PHY_PLLCFG_REG (0x1820) 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define FB_CUR_CFG_REG (0x1520) 848c2ecf20Sopenharmony_ci#define FB_CUR_ADDR_REG (0x1530) 858c2ecf20Sopenharmony_ci#define FB_CUR_LOC_ADDR_REG (0x1540) 868c2ecf20Sopenharmony_ci#define FB_CUR_BACK_REG (0x1550) 878c2ecf20Sopenharmony_ci#define FB_CUR_FORE_REG (0x1560) 888c2ecf20Sopenharmony_ci#define FB_INT_REG (0x1570) 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci#define INT_DVO1_VSYNC 0 918c2ecf20Sopenharmony_ci#define INT_DVO1_HSYNC 1 928c2ecf20Sopenharmony_ci#define INT_DVO0_VSYNC 2 938c2ecf20Sopenharmony_ci#define INT_DVO0_HSYNC 3 948c2ecf20Sopenharmony_ci#define INT_CURSOR_FB_END 4 958c2ecf20Sopenharmony_ci#define INT_DVO1_FB_END 5 968c2ecf20Sopenharmony_ci#define INT_DVO0_FB_END 6 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci#define MAX_CRTC 2 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cienum loongson_chip { 1018c2ecf20Sopenharmony_ci dc_7a1000, 1028c2ecf20Sopenharmony_ci dc_7a2000 1038c2ecf20Sopenharmony_ci}; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistruct pix_pll { 1068c2ecf20Sopenharmony_ci unsigned int l2_div; 1078c2ecf20Sopenharmony_ci unsigned int l1_loopc; 1088c2ecf20Sopenharmony_ci unsigned int l1_frefc; 1098c2ecf20Sopenharmony_ci}; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cistruct config_reg { 1128c2ecf20Sopenharmony_ci u8 dev_addr; 1138c2ecf20Sopenharmony_ci u8 reg; 1148c2ecf20Sopenharmony_ci u8 value; 1158c2ecf20Sopenharmony_ci} __packed; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cistruct cfg_encoder { 1188c2ecf20Sopenharmony_ci u8 reg_num; 1198c2ecf20Sopenharmony_ci u32 hdisplay; 1208c2ecf20Sopenharmony_ci u32 vdisplay; 1218c2ecf20Sopenharmony_ci struct config_reg config_regs[256]; 1228c2ecf20Sopenharmony_ci}; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistruct loongson_crtc { 1258c2ecf20Sopenharmony_ci struct drm_crtc base; 1268c2ecf20Sopenharmony_ci unsigned int crtc_id; 1278c2ecf20Sopenharmony_ci uint32_t cfg_reg; 1288c2ecf20Sopenharmony_ci struct drm_plane *primary; /* Primary panel belongs to this crtc */ 1298c2ecf20Sopenharmony_ci struct drm_pending_vblank_event *event; 1308c2ecf20Sopenharmony_ci struct loongson_drm_device *ldev; 1318c2ecf20Sopenharmony_ci}; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistruct loongson_encoder { 1348c2ecf20Sopenharmony_ci struct drm_encoder base; 1358c2ecf20Sopenharmony_ci u32 type; 1368c2ecf20Sopenharmony_ci u32 i2c_id; 1378c2ecf20Sopenharmony_ci int encoder_id; 1388c2ecf20Sopenharmony_ci struct loongson_i2c *i2c; 1398c2ecf20Sopenharmony_ci struct loongson_crtc *lcrtc; /* Binding crtc, not actual one */ 1408c2ecf20Sopenharmony_ci}; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistruct loongson_connector { 1438c2ecf20Sopenharmony_ci struct drm_connector base; 1448c2ecf20Sopenharmony_ci u16 id; 1458c2ecf20Sopenharmony_ci u32 type; 1468c2ecf20Sopenharmony_ci u16 i2c_id; 1478c2ecf20Sopenharmony_ci u16 hotplug; 1488c2ecf20Sopenharmony_ci u16 edid_method; 1498c2ecf20Sopenharmony_ci u8 *vbios_edid; 1508c2ecf20Sopenharmony_ci struct loongson_i2c *i2c; 1518c2ecf20Sopenharmony_ci struct loongson_drm_device *ldev; 1528c2ecf20Sopenharmony_ci}; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistruct loongson_mode_info { 1558c2ecf20Sopenharmony_ci bool mode_config_initialized; 1568c2ecf20Sopenharmony_ci struct loongson_crtc *crtc; 1578c2ecf20Sopenharmony_ci struct loongson_encoder *encoder; 1588c2ecf20Sopenharmony_ci struct loongson_connector *connector; 1598c2ecf20Sopenharmony_ci}; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistruct loongson_drm_device { 1628c2ecf20Sopenharmony_ci struct drm_device *dev; 1638c2ecf20Sopenharmony_ci struct drm_atomic_state *state; 1648c2ecf20Sopenharmony_ci struct pci_dev *gpu_pdev; /* LS7A gpu device info */ 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci resource_size_t mmio_base; 1678c2ecf20Sopenharmony_ci resource_size_t mmio_size; 1688c2ecf20Sopenharmony_ci void __iomem *mmio; 1698c2ecf20Sopenharmony_ci uint32_t int_reg; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci struct drm_display_mode mode; 1728c2ecf20Sopenharmony_ci struct loongson_mode_info mode_info[2]; 1738c2ecf20Sopenharmony_ci struct drm_gem_cma_object *cursor; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci int num_crtc; 1768c2ecf20Sopenharmony_ci struct loongson_crtc lcrtc[MAX_CRTC]; 1778c2ecf20Sopenharmony_ci struct loongson_i2c i2c_bus[DC_I2C_BUS_MAX]; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci void *vbios; 1808c2ecf20Sopenharmony_ci struct list_head desc_list; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci bool inited; 1838c2ecf20Sopenharmony_ci bool suspended; 1848c2ecf20Sopenharmony_ci bool cursor_showed; 1858c2ecf20Sopenharmony_ci int cursor_crtc_id; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci int connector_active0; 1888c2ecf20Sopenharmony_ci int connector_active1; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci enum loongson_chip chip; 1918c2ecf20Sopenharmony_ci}; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ciextern spinlock_t loongson_reglock; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci/* FIXME: LS7A2000's switch_panel is not available, just return false. */ 1968c2ecf20Sopenharmony_cistatic inline bool clone_mode(struct loongson_drm_device *ldev) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci return false; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci if (ldev->num_crtc < 2) 2018c2ecf20Sopenharmony_ci return true; 2028c2ecf20Sopenharmony_ci if (ldev->mode_info[0].connector->base.status != connector_status_connected) 2038c2ecf20Sopenharmony_ci return true; 2048c2ecf20Sopenharmony_ci if (ldev->mode_info[1].connector->base.status != connector_status_connected) 2058c2ecf20Sopenharmony_ci return true; 2068c2ecf20Sopenharmony_ci if (ldev->lcrtc[0].base.x || ldev->lcrtc[0].base.y) 2078c2ecf20Sopenharmony_ci return false; 2088c2ecf20Sopenharmony_ci if (ldev->lcrtc[1].base.x || ldev->lcrtc[1].base.y) 2098c2ecf20Sopenharmony_ci return false; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci return true; 2128c2ecf20Sopenharmony_ci} 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ciint loongson_irq_enable_vblank(struct drm_device *dev,unsigned int crtc_id); 2158c2ecf20Sopenharmony_civoid loongson_irq_disable_vblank(struct drm_device *dev,unsigned int crtc_id); 2168c2ecf20Sopenharmony_ciirqreturn_t loongson_irq_handler(int irq,void *arg); 2178c2ecf20Sopenharmony_civoid loongson_irq_preinstall(struct drm_device *dev); 2188c2ecf20Sopenharmony_ciint loongson_irq_postinstall(struct drm_device *dev); 2198c2ecf20Sopenharmony_civoid loongson_irq_uninstall(struct drm_device *dev); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ciu32 crtc_read(struct loongson_crtc *lcrtc, u32 offset); 2228c2ecf20Sopenharmony_civoid crtc_write(struct loongson_crtc *lcrtc, u32 offset, u32 val); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ciint loongson_gpio_init(struct loongson_drm_device *ldev); 2258c2ecf20Sopenharmony_ciint loongson_crtc_init(struct loongson_drm_device *ldev); 2268c2ecf20Sopenharmony_cistruct drm_encoder *loongson_encoder_init(struct drm_device *dev, unsigned int index); 2278c2ecf20Sopenharmony_cistruct drm_connector *loongson_connector_init(struct drm_device *dev, unsigned int index); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ciint loongson_fbdev_init(struct loongson_drm_device *ldev); 2308c2ecf20Sopenharmony_civoid loongson_fbdev_fini(struct loongson_drm_device *ldev); 2318c2ecf20Sopenharmony_civoid loongson_fbdev_restore_mode(struct loongson_drm_device *ldev); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ciint loongson_drm_drm_suspend(struct drm_device *dev, bool suspend, 2348c2ecf20Sopenharmony_ci bool fbcon, bool freeze); 2358c2ecf20Sopenharmony_ciint loongson_drm_drm_resume(struct drm_device *dev, bool resume, bool fbcon); 2368c2ecf20Sopenharmony_ci /* loongson_cursor.c */ 2378c2ecf20Sopenharmony_ciint loongson_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv, 2388c2ecf20Sopenharmony_ci uint32_t handle, uint32_t width, uint32_t height, int32_t hot_x, int32_t hot_y); 2398c2ecf20Sopenharmony_ciint loongson_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci#endif 242