162306a36Sopenharmony_ci/* SPDX-License-Identifier: MIT */
262306a36Sopenharmony_ci#ifndef __NV04_DISPLAY_H__
362306a36Sopenharmony_ci#define __NV04_DISPLAY_H__
462306a36Sopenharmony_ci#include <subdev/bios.h>
562306a36Sopenharmony_ci#include <subdev/bios/pll.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include "nouveau_display.h"
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <nvif/event.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistruct nouveau_encoder;
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cienum nv04_fp_display_regs {
1462306a36Sopenharmony_ci	FP_DISPLAY_END,
1562306a36Sopenharmony_ci	FP_TOTAL,
1662306a36Sopenharmony_ci	FP_CRTC,
1762306a36Sopenharmony_ci	FP_SYNC_START,
1862306a36Sopenharmony_ci	FP_SYNC_END,
1962306a36Sopenharmony_ci	FP_VALID_START,
2062306a36Sopenharmony_ci	FP_VALID_END
2162306a36Sopenharmony_ci};
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistruct nv04_crtc_reg {
2462306a36Sopenharmony_ci	unsigned char MiscOutReg;
2562306a36Sopenharmony_ci	uint8_t CRTC[0xa0];
2662306a36Sopenharmony_ci	uint8_t CR58[0x10];
2762306a36Sopenharmony_ci	uint8_t Sequencer[5];
2862306a36Sopenharmony_ci	uint8_t Graphics[9];
2962306a36Sopenharmony_ci	uint8_t Attribute[21];
3062306a36Sopenharmony_ci	unsigned char DAC[768];
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	/* PCRTC regs */
3362306a36Sopenharmony_ci	uint32_t fb_start;
3462306a36Sopenharmony_ci	uint32_t crtc_cfg;
3562306a36Sopenharmony_ci	uint32_t cursor_cfg;
3662306a36Sopenharmony_ci	uint32_t gpio_ext;
3762306a36Sopenharmony_ci	uint32_t crtc_830;
3862306a36Sopenharmony_ci	uint32_t crtc_834;
3962306a36Sopenharmony_ci	uint32_t crtc_850;
4062306a36Sopenharmony_ci	uint32_t crtc_eng_ctrl;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	/* PRAMDAC regs */
4362306a36Sopenharmony_ci	uint32_t nv10_cursync;
4462306a36Sopenharmony_ci	struct nvkm_pll_vals pllvals;
4562306a36Sopenharmony_ci	uint32_t ramdac_gen_ctrl;
4662306a36Sopenharmony_ci	uint32_t ramdac_630;
4762306a36Sopenharmony_ci	uint32_t ramdac_634;
4862306a36Sopenharmony_ci	uint32_t tv_setup;
4962306a36Sopenharmony_ci	uint32_t tv_vtotal;
5062306a36Sopenharmony_ci	uint32_t tv_vskew;
5162306a36Sopenharmony_ci	uint32_t tv_vsync_delay;
5262306a36Sopenharmony_ci	uint32_t tv_htotal;
5362306a36Sopenharmony_ci	uint32_t tv_hskew;
5462306a36Sopenharmony_ci	uint32_t tv_hsync_delay;
5562306a36Sopenharmony_ci	uint32_t tv_hsync_delay2;
5662306a36Sopenharmony_ci	uint32_t fp_horiz_regs[7];
5762306a36Sopenharmony_ci	uint32_t fp_vert_regs[7];
5862306a36Sopenharmony_ci	uint32_t dither;
5962306a36Sopenharmony_ci	uint32_t fp_control;
6062306a36Sopenharmony_ci	uint32_t dither_regs[6];
6162306a36Sopenharmony_ci	uint32_t fp_debug_0;
6262306a36Sopenharmony_ci	uint32_t fp_debug_1;
6362306a36Sopenharmony_ci	uint32_t fp_debug_2;
6462306a36Sopenharmony_ci	uint32_t fp_margin_color;
6562306a36Sopenharmony_ci	uint32_t ramdac_8c0;
6662306a36Sopenharmony_ci	uint32_t ramdac_a20;
6762306a36Sopenharmony_ci	uint32_t ramdac_a24;
6862306a36Sopenharmony_ci	uint32_t ramdac_a34;
6962306a36Sopenharmony_ci	uint32_t ctv_regs[38];
7062306a36Sopenharmony_ci};
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_cistruct nv04_output_reg {
7362306a36Sopenharmony_ci	uint32_t output;
7462306a36Sopenharmony_ci	int head;
7562306a36Sopenharmony_ci};
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistruct nv04_mode_state {
7862306a36Sopenharmony_ci	struct nv04_crtc_reg crtc_reg[2];
7962306a36Sopenharmony_ci	uint32_t pllsel;
8062306a36Sopenharmony_ci	uint32_t sel_clk;
8162306a36Sopenharmony_ci};
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cistruct nv04_display {
8462306a36Sopenharmony_ci	struct nv04_mode_state mode_reg;
8562306a36Sopenharmony_ci	struct nv04_mode_state saved_reg;
8662306a36Sopenharmony_ci	uint32_t saved_vga_font[4][16384];
8762306a36Sopenharmony_ci	uint32_t dac_users[4];
8862306a36Sopenharmony_ci	struct nouveau_bo *image[2];
8962306a36Sopenharmony_ci	struct nvif_event flip;
9062306a36Sopenharmony_ci	struct nouveau_drm *drm;
9162306a36Sopenharmony_ci};
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic inline struct nv04_display *
9462306a36Sopenharmony_cinv04_display(struct drm_device *dev)
9562306a36Sopenharmony_ci{
9662306a36Sopenharmony_ci	return nouveau_display(dev)->priv;
9762306a36Sopenharmony_ci}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci/* nv04_display.c */
10062306a36Sopenharmony_ciint nv04_display_create(struct drm_device *);
10162306a36Sopenharmony_cistruct nouveau_connector *
10262306a36Sopenharmony_cinv04_encoder_get_connector(struct nouveau_encoder *nv_encoder);
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/* nv04_crtc.c */
10562306a36Sopenharmony_ciint nv04_crtc_create(struct drm_device *, int index);
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci/* nv04_dac.c */
10862306a36Sopenharmony_ciint nv04_dac_create(struct drm_connector *, struct dcb_output *);
10962306a36Sopenharmony_ciuint32_t nv17_dac_sample_load(struct drm_encoder *encoder);
11062306a36Sopenharmony_ciint nv04_dac_output_offset(struct drm_encoder *encoder);
11162306a36Sopenharmony_civoid nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
11262306a36Sopenharmony_cibool nv04_dac_in_use(struct drm_encoder *encoder);
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci/* nv04_dfp.c */
11562306a36Sopenharmony_ciint nv04_dfp_create(struct drm_connector *, struct dcb_output *);
11662306a36Sopenharmony_ciint nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_output *dcbent);
11762306a36Sopenharmony_civoid nv04_dfp_bind_head(struct drm_device *dev, struct dcb_output *dcbent,
11862306a36Sopenharmony_ci			       int head, bool dl);
11962306a36Sopenharmony_civoid nv04_dfp_disable(struct drm_device *dev, int head);
12062306a36Sopenharmony_civoid nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode);
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci/* nv04_tv.c */
12362306a36Sopenharmony_ciint nv04_tv_identify(struct drm_device *dev, int i2c_index);
12462306a36Sopenharmony_ciint nv04_tv_create(struct drm_connector *, struct dcb_output *);
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci/* nv17_tv.c */
12762306a36Sopenharmony_ciint nv17_tv_create(struct drm_connector *, struct dcb_output *);
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci/* overlay.c */
13062306a36Sopenharmony_civoid nouveau_overlay_init(struct drm_device *dev);
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cistatic inline bool
13362306a36Sopenharmony_cinv_two_heads(struct drm_device *dev)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci	struct nouveau_drm *drm = nouveau_drm(dev);
13662306a36Sopenharmony_ci	const int impl = to_pci_dev(dev->dev)->device & 0x0ff0;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_CELSIUS && impl != 0x0100 &&
13962306a36Sopenharmony_ci	    impl != 0x0150 && impl != 0x01a0 && impl != 0x0200)
14062306a36Sopenharmony_ci		return true;
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	return false;
14362306a36Sopenharmony_ci}
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_cistatic inline bool
14662306a36Sopenharmony_cinv_gf4_disp_arch(struct drm_device *dev)
14762306a36Sopenharmony_ci{
14862306a36Sopenharmony_ci	return nv_two_heads(dev) && (to_pci_dev(dev->dev)->device & 0x0ff0) != 0x0110;
14962306a36Sopenharmony_ci}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cistatic inline bool
15262306a36Sopenharmony_cinv_two_reg_pll(struct drm_device *dev)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	struct nouveau_drm *drm = nouveau_drm(dev);
15562306a36Sopenharmony_ci	const int impl = to_pci_dev(dev->dev)->device & 0x0ff0;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	if (impl == 0x0310 || impl == 0x0340 || drm->client.device.info.family >= NV_DEVICE_INFO_V0_CURIE)
15862306a36Sopenharmony_ci		return true;
15962306a36Sopenharmony_ci	return false;
16062306a36Sopenharmony_ci}
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cistatic inline bool
16362306a36Sopenharmony_cinv_match_device(struct drm_device *dev, unsigned device,
16462306a36Sopenharmony_ci		unsigned sub_vendor, unsigned sub_device)
16562306a36Sopenharmony_ci{
16662306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(dev->dev);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	return pdev->device == device &&
16962306a36Sopenharmony_ci		pdev->subsystem_vendor == sub_vendor &&
17062306a36Sopenharmony_ci		pdev->subsystem_device == sub_device;
17162306a36Sopenharmony_ci}
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci#include <subdev/bios/init.h>
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_cistatic inline void
17662306a36Sopenharmony_cinouveau_bios_run_init_table(struct drm_device *dev, u16 table,
17762306a36Sopenharmony_ci			    struct dcb_output *outp, int crtc)
17862306a36Sopenharmony_ci{
17962306a36Sopenharmony_ci	nvbios_init(&nvxx_bios(&nouveau_drm(dev)->client.device)->subdev, table,
18062306a36Sopenharmony_ci		init.outp = outp;
18162306a36Sopenharmony_ci		init.head = crtc;
18262306a36Sopenharmony_ci	);
18362306a36Sopenharmony_ci}
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ciint nv04_flip_complete(struct nvif_event *, void *, u32);
18662306a36Sopenharmony_ci#endif
187