1b7019ac5SIlia Mirkin /* SPDX-License-Identifier: MIT */
2017e6e29SBen Skeggs #ifndef __NV04_DISPLAY_H__
3017e6e29SBen Skeggs #define __NV04_DISPLAY_H__
44dc28134SBen Skeggs #include <subdev/bios.h>
551a3d342SBen Skeggs #include <subdev/bios/pll.h>
651a3d342SBen Skeggs
777145f1cSBen Skeggs #include "nouveau_display.h"
877145f1cSBen Skeggs
9801bc858SBen Skeggs #include <nvif/event.h>
10801bc858SBen Skeggs
1109838c4eSLyude Paul struct nouveau_encoder;
1209838c4eSLyude Paul
13017e6e29SBen Skeggs enum nv04_fp_display_regs {
14017e6e29SBen Skeggs FP_DISPLAY_END,
15017e6e29SBen Skeggs FP_TOTAL,
16017e6e29SBen Skeggs FP_CRTC,
17017e6e29SBen Skeggs FP_SYNC_START,
18017e6e29SBen Skeggs FP_SYNC_END,
19017e6e29SBen Skeggs FP_VALID_START,
20017e6e29SBen Skeggs FP_VALID_END
21017e6e29SBen Skeggs };
22017e6e29SBen Skeggs
23017e6e29SBen Skeggs struct nv04_crtc_reg {
24017e6e29SBen Skeggs unsigned char MiscOutReg;
25017e6e29SBen Skeggs uint8_t CRTC[0xa0];
26017e6e29SBen Skeggs uint8_t CR58[0x10];
27017e6e29SBen Skeggs uint8_t Sequencer[5];
28017e6e29SBen Skeggs uint8_t Graphics[9];
29017e6e29SBen Skeggs uint8_t Attribute[21];
30017e6e29SBen Skeggs unsigned char DAC[768];
31017e6e29SBen Skeggs
32017e6e29SBen Skeggs /* PCRTC regs */
33017e6e29SBen Skeggs uint32_t fb_start;
34017e6e29SBen Skeggs uint32_t crtc_cfg;
35017e6e29SBen Skeggs uint32_t cursor_cfg;
36017e6e29SBen Skeggs uint32_t gpio_ext;
37017e6e29SBen Skeggs uint32_t crtc_830;
38017e6e29SBen Skeggs uint32_t crtc_834;
39017e6e29SBen Skeggs uint32_t crtc_850;
40017e6e29SBen Skeggs uint32_t crtc_eng_ctrl;
41017e6e29SBen Skeggs
42017e6e29SBen Skeggs /* PRAMDAC regs */
43017e6e29SBen Skeggs uint32_t nv10_cursync;
44be83cd4eSBen Skeggs struct nvkm_pll_vals pllvals;
45017e6e29SBen Skeggs uint32_t ramdac_gen_ctrl;
46017e6e29SBen Skeggs uint32_t ramdac_630;
47017e6e29SBen Skeggs uint32_t ramdac_634;
48017e6e29SBen Skeggs uint32_t tv_setup;
49017e6e29SBen Skeggs uint32_t tv_vtotal;
50017e6e29SBen Skeggs uint32_t tv_vskew;
51017e6e29SBen Skeggs uint32_t tv_vsync_delay;
52017e6e29SBen Skeggs uint32_t tv_htotal;
53017e6e29SBen Skeggs uint32_t tv_hskew;
54017e6e29SBen Skeggs uint32_t tv_hsync_delay;
55017e6e29SBen Skeggs uint32_t tv_hsync_delay2;
56017e6e29SBen Skeggs uint32_t fp_horiz_regs[7];
57017e6e29SBen Skeggs uint32_t fp_vert_regs[7];
58017e6e29SBen Skeggs uint32_t dither;
59017e6e29SBen Skeggs uint32_t fp_control;
60017e6e29SBen Skeggs uint32_t dither_regs[6];
61017e6e29SBen Skeggs uint32_t fp_debug_0;
62017e6e29SBen Skeggs uint32_t fp_debug_1;
63017e6e29SBen Skeggs uint32_t fp_debug_2;
64017e6e29SBen Skeggs uint32_t fp_margin_color;
65017e6e29SBen Skeggs uint32_t ramdac_8c0;
66017e6e29SBen Skeggs uint32_t ramdac_a20;
67017e6e29SBen Skeggs uint32_t ramdac_a24;
68017e6e29SBen Skeggs uint32_t ramdac_a34;
69017e6e29SBen Skeggs uint32_t ctv_regs[38];
70017e6e29SBen Skeggs };
71017e6e29SBen Skeggs
72017e6e29SBen Skeggs struct nv04_output_reg {
73017e6e29SBen Skeggs uint32_t output;
74017e6e29SBen Skeggs int head;
75017e6e29SBen Skeggs };
76017e6e29SBen Skeggs
77017e6e29SBen Skeggs struct nv04_mode_state {
78017e6e29SBen Skeggs struct nv04_crtc_reg crtc_reg[2];
79017e6e29SBen Skeggs uint32_t pllsel;
80017e6e29SBen Skeggs uint32_t sel_clk;
81017e6e29SBen Skeggs };
82017e6e29SBen Skeggs
83017e6e29SBen Skeggs struct nv04_display {
84017e6e29SBen Skeggs struct nv04_mode_state mode_reg;
85017e6e29SBen Skeggs struct nv04_mode_state saved_reg;
86017e6e29SBen Skeggs uint32_t saved_vga_font[4][16384];
87017e6e29SBen Skeggs uint32_t dac_users[4];
8878ae0ad4SBen Skeggs struct nouveau_bo *image[2];
89801bc858SBen Skeggs struct nvif_event flip;
90801bc858SBen Skeggs struct nouveau_drm *drm;
91017e6e29SBen Skeggs };
92017e6e29SBen Skeggs
9377145f1cSBen Skeggs static inline struct nv04_display *
nv04_display(struct drm_device * dev)9477145f1cSBen Skeggs nv04_display(struct drm_device *dev)
9577145f1cSBen Skeggs {
9677145f1cSBen Skeggs return nouveau_display(dev)->priv;
9777145f1cSBen Skeggs }
9877145f1cSBen Skeggs
99017e6e29SBen Skeggs /* nv04_display.c */
100017e6e29SBen Skeggs int nv04_display_create(struct drm_device *);
10109838c4eSLyude Paul struct nouveau_connector *
10209838c4eSLyude Paul nv04_encoder_get_connector(struct nouveau_encoder *nv_encoder);
103017e6e29SBen Skeggs
104017e6e29SBen Skeggs /* nv04_crtc.c */
105017e6e29SBen Skeggs int nv04_crtc_create(struct drm_device *, int index);
106017e6e29SBen Skeggs
107017e6e29SBen Skeggs /* nv04_dac.c */
108017e6e29SBen Skeggs int nv04_dac_create(struct drm_connector *, struct dcb_output *);
109017e6e29SBen Skeggs uint32_t nv17_dac_sample_load(struct drm_encoder *encoder);
110017e6e29SBen Skeggs int nv04_dac_output_offset(struct drm_encoder *encoder);
111017e6e29SBen Skeggs void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
112017e6e29SBen Skeggs bool nv04_dac_in_use(struct drm_encoder *encoder);
113017e6e29SBen Skeggs
114017e6e29SBen Skeggs /* nv04_dfp.c */
115017e6e29SBen Skeggs int nv04_dfp_create(struct drm_connector *, struct dcb_output *);
116017e6e29SBen Skeggs int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_output *dcbent);
117017e6e29SBen Skeggs void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_output *dcbent,
118017e6e29SBen Skeggs int head, bool dl);
119017e6e29SBen Skeggs void nv04_dfp_disable(struct drm_device *dev, int head);
120017e6e29SBen Skeggs void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode);
121017e6e29SBen Skeggs
122017e6e29SBen Skeggs /* nv04_tv.c */
123017e6e29SBen Skeggs int nv04_tv_identify(struct drm_device *dev, int i2c_index);
124017e6e29SBen Skeggs int nv04_tv_create(struct drm_connector *, struct dcb_output *);
125017e6e29SBen Skeggs
126017e6e29SBen Skeggs /* nv17_tv.c */
127017e6e29SBen Skeggs int nv17_tv_create(struct drm_connector *, struct dcb_output *);
128017e6e29SBen Skeggs
129515de6b2SIlia Mirkin /* overlay.c */
130515de6b2SIlia Mirkin void nouveau_overlay_init(struct drm_device *dev);
131515de6b2SIlia Mirkin
13277145f1cSBen Skeggs static inline bool
nv_two_heads(struct drm_device * dev)13377145f1cSBen Skeggs nv_two_heads(struct drm_device *dev)
13477145f1cSBen Skeggs {
13577145f1cSBen Skeggs struct nouveau_drm *drm = nouveau_drm(dev);
1364c0d42f7SThomas Zimmermann const int impl = to_pci_dev(dev->dev)->device & 0x0ff0;
13777145f1cSBen Skeggs
1381167c6bcSBen Skeggs if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_CELSIUS && impl != 0x0100 &&
13977145f1cSBen Skeggs impl != 0x0150 && impl != 0x01a0 && impl != 0x0200)
14077145f1cSBen Skeggs return true;
14177145f1cSBen Skeggs
14277145f1cSBen Skeggs return false;
14377145f1cSBen Skeggs }
14477145f1cSBen Skeggs
14577145f1cSBen Skeggs static inline bool
nv_gf4_disp_arch(struct drm_device * dev)14677145f1cSBen Skeggs nv_gf4_disp_arch(struct drm_device *dev)
14777145f1cSBen Skeggs {
1484c0d42f7SThomas Zimmermann return nv_two_heads(dev) && (to_pci_dev(dev->dev)->device & 0x0ff0) != 0x0110;
14977145f1cSBen Skeggs }
15077145f1cSBen Skeggs
15177145f1cSBen Skeggs static inline bool
nv_two_reg_pll(struct drm_device * dev)15277145f1cSBen Skeggs nv_two_reg_pll(struct drm_device *dev)
15377145f1cSBen Skeggs {
15477145f1cSBen Skeggs struct nouveau_drm *drm = nouveau_drm(dev);
1554c0d42f7SThomas Zimmermann const int impl = to_pci_dev(dev->dev)->device & 0x0ff0;
15677145f1cSBen Skeggs
1571167c6bcSBen Skeggs if (impl == 0x0310 || impl == 0x0340 || drm->client.device.info.family >= NV_DEVICE_INFO_V0_CURIE)
15877145f1cSBen Skeggs return true;
15977145f1cSBen Skeggs return false;
16077145f1cSBen Skeggs }
16177145f1cSBen Skeggs
16277145f1cSBen Skeggs static inline bool
nv_match_device(struct drm_device * dev,unsigned device,unsigned sub_vendor,unsigned sub_device)16377145f1cSBen Skeggs nv_match_device(struct drm_device *dev, unsigned device,
16477145f1cSBen Skeggs unsigned sub_vendor, unsigned sub_device)
16577145f1cSBen Skeggs {
1664c0d42f7SThomas Zimmermann struct pci_dev *pdev = to_pci_dev(dev->dev);
1674c0d42f7SThomas Zimmermann
1684c0d42f7SThomas Zimmermann return pdev->device == device &&
1694c0d42f7SThomas Zimmermann pdev->subsystem_vendor == sub_vendor &&
1704c0d42f7SThomas Zimmermann pdev->subsystem_device == sub_device;
17177145f1cSBen Skeggs }
17277145f1cSBen Skeggs
17377145f1cSBen Skeggs #include <subdev/bios/init.h>
17477145f1cSBen Skeggs
17577145f1cSBen Skeggs static inline void
nouveau_bios_run_init_table(struct drm_device * dev,u16 table,struct dcb_output * outp,int crtc)17677145f1cSBen Skeggs nouveau_bios_run_init_table(struct drm_device *dev, u16 table,
17777145f1cSBen Skeggs struct dcb_output *outp, int crtc)
17877145f1cSBen Skeggs {
1796901f1d6SBen Skeggs nvbios_init(&nvxx_bios(nouveau_drm(dev))->subdev, table,
180639d72e2SBen Skeggs init.outp = outp;
181639d72e2SBen Skeggs init.head = crtc;
182639d72e2SBen Skeggs );
18377145f1cSBen Skeggs }
18477145f1cSBen Skeggs
185801bc858SBen Skeggs int nv04_flip_complete(struct nvif_event *, void *, u32);
186017e6e29SBen Skeggs #endif
187