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