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