1 | /* SPDX-License-Identifier: MIT */ |
2 | #ifndef __NV04_DISPLAY_H__ |
3 | #define __NV04_DISPLAY_H__ |
4 | #include <subdev/bios.h> |
5 | #include <subdev/bios/pll.h> |
6 | |
7 | #include "nouveau_display.h" |
8 | |
9 | #include <nvif/event.h> |
10 | |
11 | struct nouveau_encoder; |
12 | |
13 | enum nv04_fp_display_regs { |
14 | FP_DISPLAY_END, |
15 | FP_TOTAL, |
16 | FP_CRTC, |
17 | FP_SYNC_START, |
18 | FP_SYNC_END, |
19 | FP_VALID_START, |
20 | FP_VALID_END |
21 | }; |
22 | |
23 | struct nv04_crtc_reg { |
24 | unsigned char MiscOutReg; |
25 | uint8_t CRTC[0xa0]; |
26 | uint8_t CR58[0x10]; |
27 | uint8_t Sequencer[5]; |
28 | uint8_t Graphics[9]; |
29 | uint8_t Attribute[21]; |
30 | unsigned char DAC[768]; |
31 | |
32 | /* PCRTC regs */ |
33 | uint32_t fb_start; |
34 | uint32_t crtc_cfg; |
35 | uint32_t cursor_cfg; |
36 | uint32_t gpio_ext; |
37 | uint32_t crtc_830; |
38 | uint32_t crtc_834; |
39 | uint32_t crtc_850; |
40 | uint32_t crtc_eng_ctrl; |
41 | |
42 | /* PRAMDAC regs */ |
43 | uint32_t nv10_cursync; |
44 | struct nvkm_pll_vals pllvals; |
45 | uint32_t ramdac_gen_ctrl; |
46 | uint32_t ramdac_630; |
47 | uint32_t ramdac_634; |
48 | uint32_t tv_setup; |
49 | uint32_t tv_vtotal; |
50 | uint32_t tv_vskew; |
51 | uint32_t tv_vsync_delay; |
52 | uint32_t tv_htotal; |
53 | uint32_t tv_hskew; |
54 | uint32_t tv_hsync_delay; |
55 | uint32_t tv_hsync_delay2; |
56 | uint32_t fp_horiz_regs[7]; |
57 | uint32_t fp_vert_regs[7]; |
58 | uint32_t dither; |
59 | uint32_t fp_control; |
60 | uint32_t dither_regs[6]; |
61 | uint32_t fp_debug_0; |
62 | uint32_t fp_debug_1; |
63 | uint32_t fp_debug_2; |
64 | uint32_t fp_margin_color; |
65 | uint32_t ramdac_8c0; |
66 | uint32_t ramdac_a20; |
67 | uint32_t ramdac_a24; |
68 | uint32_t ramdac_a34; |
69 | uint32_t ctv_regs[38]; |
70 | }; |
71 | |
72 | struct nv04_output_reg { |
73 | uint32_t output; |
74 | int head; |
75 | }; |
76 | |
77 | struct nv04_mode_state { |
78 | struct nv04_crtc_reg crtc_reg[2]; |
79 | uint32_t pllsel; |
80 | uint32_t sel_clk; |
81 | }; |
82 | |
83 | struct nv04_display { |
84 | struct nv04_mode_state mode_reg; |
85 | struct nv04_mode_state saved_reg; |
86 | uint32_t saved_vga_font[4][16384]; |
87 | uint32_t dac_users[4]; |
88 | struct nouveau_bo *image[2]; |
89 | struct nvif_event flip; |
90 | struct nouveau_drm *drm; |
91 | }; |
92 | |
93 | static inline struct nv04_display * |
94 | nv04_display(struct drm_device *dev) |
95 | { |
96 | return nouveau_display(dev)->priv; |
97 | } |
98 | |
99 | /* nv04_display.c */ |
100 | int nv04_display_create(struct drm_device *); |
101 | struct nouveau_connector * |
102 | nv04_encoder_get_connector(struct nouveau_encoder *nv_encoder); |
103 | |
104 | /* nv04_crtc.c */ |
105 | int nv04_crtc_create(struct drm_device *, int index); |
106 | |
107 | /* nv04_dac.c */ |
108 | int nv04_dac_create(struct drm_connector *, struct dcb_output *); |
109 | uint32_t nv17_dac_sample_load(struct drm_encoder *encoder); |
110 | int nv04_dac_output_offset(struct drm_encoder *encoder); |
111 | void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); |
112 | bool nv04_dac_in_use(struct drm_encoder *encoder); |
113 | |
114 | /* nv04_dfp.c */ |
115 | int nv04_dfp_create(struct drm_connector *, struct dcb_output *); |
116 | int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_output *dcbent); |
117 | void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_output *dcbent, |
118 | int head, bool dl); |
119 | void nv04_dfp_disable(struct drm_device *dev, int head); |
120 | void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode); |
121 | |
122 | /* nv04_tv.c */ |
123 | int nv04_tv_identify(struct drm_device *dev, int i2c_index); |
124 | int nv04_tv_create(struct drm_connector *, struct dcb_output *); |
125 | |
126 | /* nv17_tv.c */ |
127 | int nv17_tv_create(struct drm_connector *, struct dcb_output *); |
128 | |
129 | /* overlay.c */ |
130 | void nouveau_overlay_init(struct drm_device *dev); |
131 | |
132 | static inline bool |
133 | nv_two_heads(struct drm_device *dev) |
134 | { |
135 | struct nouveau_drm *drm = nouveau_drm(dev); |
136 | const int impl = to_pci_dev(dev->dev)->device & 0x0ff0; |
137 | |
138 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_CELSIUS && impl != 0x0100 && |
139 | impl != 0x0150 && impl != 0x01a0 && impl != 0x0200) |
140 | return true; |
141 | |
142 | return false; |
143 | } |
144 | |
145 | static inline bool |
146 | nv_gf4_disp_arch(struct drm_device *dev) |
147 | { |
148 | return nv_two_heads(dev) && (to_pci_dev(dev->dev)->device & 0x0ff0) != 0x0110; |
149 | } |
150 | |
151 | static inline bool |
152 | nv_two_reg_pll(struct drm_device *dev) |
153 | { |
154 | struct nouveau_drm *drm = nouveau_drm(dev); |
155 | const int impl = to_pci_dev(dev->dev)->device & 0x0ff0; |
156 | |
157 | if (impl == 0x0310 || impl == 0x0340 || drm->client.device.info.family >= NV_DEVICE_INFO_V0_CURIE) |
158 | return true; |
159 | return false; |
160 | } |
161 | |
162 | static inline bool |
163 | nv_match_device(struct drm_device *dev, unsigned device, |
164 | unsigned sub_vendor, unsigned sub_device) |
165 | { |
166 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
167 | |
168 | return pdev->device == device && |
169 | pdev->subsystem_vendor == sub_vendor && |
170 | pdev->subsystem_device == sub_device; |
171 | } |
172 | |
173 | #include <subdev/bios/init.h> |
174 | |
175 | static inline void |
176 | nouveau_bios_run_init_table(struct drm_device *dev, u16 table, |
177 | struct dcb_output *outp, int crtc) |
178 | { |
179 | nvbios_init(&nvxx_bios(&nouveau_drm(dev)->client.device)->subdev, table, |
180 | init.outp = outp; |
181 | init.head = crtc; |
182 | ); |
183 | } |
184 | |
185 | int nv04_flip_complete(struct nvif_event *, void *, u32); |
186 | #endif |
187 | |