0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #ifndef __NOUVEAU_HW_H__
0024 #define __NOUVEAU_HW_H__
0025
0026 #include "disp.h"
0027 #include "nvreg.h"
0028
0029 #include <subdev/bios/pll.h>
0030
0031 #define MASK(field) ( \
0032 (0xffffffff >> (31 - ((1 ? field) - (0 ? field)))) << (0 ? field))
0033
0034 #define XLATE(src, srclowbit, outfield) ( \
0035 (((src) >> (srclowbit)) << (0 ? outfield)) & MASK(outfield))
0036
0037 void NVWriteVgaSeq(struct drm_device *, int head, uint8_t index, uint8_t value);
0038 uint8_t NVReadVgaSeq(struct drm_device *, int head, uint8_t index);
0039 void NVWriteVgaGr(struct drm_device *, int head, uint8_t index, uint8_t value);
0040 uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index);
0041 void NVSetOwner(struct drm_device *, int owner);
0042 void NVBlankScreen(struct drm_device *, int head, bool blank);
0043 int nouveau_hw_get_pllvals(struct drm_device *, enum nvbios_pll_type plltype,
0044 struct nvkm_pll_vals *pllvals);
0045 int nouveau_hw_pllvals_to_clk(struct nvkm_pll_vals *pllvals);
0046 int nouveau_hw_get_clock(struct drm_device *, enum nvbios_pll_type plltype);
0047 void nouveau_hw_save_vga_fonts(struct drm_device *, bool save);
0048 void nouveau_hw_save_state(struct drm_device *, int head,
0049 struct nv04_mode_state *state);
0050 void nouveau_hw_load_state(struct drm_device *, int head,
0051 struct nv04_mode_state *state);
0052 void nouveau_hw_load_state_palette(struct drm_device *, int head,
0053 struct nv04_mode_state *state);
0054
0055
0056 extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp,
0057 int *burst, int *lwm);
0058
0059 static inline uint32_t NVReadCRTC(struct drm_device *dev,
0060 int head, uint32_t reg)
0061 {
0062 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0063 uint32_t val;
0064 if (head)
0065 reg += NV_PCRTC0_SIZE;
0066 val = nvif_rd32(device, reg);
0067 return val;
0068 }
0069
0070 static inline void NVWriteCRTC(struct drm_device *dev,
0071 int head, uint32_t reg, uint32_t val)
0072 {
0073 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0074 if (head)
0075 reg += NV_PCRTC0_SIZE;
0076 nvif_wr32(device, reg, val);
0077 }
0078
0079 static inline uint32_t NVReadRAMDAC(struct drm_device *dev,
0080 int head, uint32_t reg)
0081 {
0082 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0083 uint32_t val;
0084 if (head)
0085 reg += NV_PRAMDAC0_SIZE;
0086 val = nvif_rd32(device, reg);
0087 return val;
0088 }
0089
0090 static inline void NVWriteRAMDAC(struct drm_device *dev,
0091 int head, uint32_t reg, uint32_t val)
0092 {
0093 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0094 if (head)
0095 reg += NV_PRAMDAC0_SIZE;
0096 nvif_wr32(device, reg, val);
0097 }
0098
0099 static inline uint8_t nv_read_tmds(struct drm_device *dev,
0100 int or, int dl, uint8_t address)
0101 {
0102 int ramdac = (or & DCB_OUTPUT_C) >> 2;
0103
0104 NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8,
0105 NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address);
0106 return NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8);
0107 }
0108
0109 static inline void nv_write_tmds(struct drm_device *dev,
0110 int or, int dl, uint8_t address,
0111 uint8_t data)
0112 {
0113 int ramdac = (or & DCB_OUTPUT_C) >> 2;
0114
0115 NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data);
0116 NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address);
0117 }
0118
0119 static inline void NVWriteVgaCrtc(struct drm_device *dev,
0120 int head, uint8_t index, uint8_t value)
0121 {
0122 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0123 nvif_wr08(device, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
0124 nvif_wr08(device, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value);
0125 }
0126
0127 static inline uint8_t NVReadVgaCrtc(struct drm_device *dev,
0128 int head, uint8_t index)
0129 {
0130 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0131 uint8_t val;
0132 nvif_wr08(device, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
0133 val = nvif_rd08(device, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE);
0134 return val;
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 static inline void
0152 NVWriteVgaCrtc5758(struct drm_device *dev, int head, uint8_t index, uint8_t value)
0153 {
0154 NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index);
0155 NVWriteVgaCrtc(dev, head, NV_CIO_CRE_58, value);
0156 }
0157
0158 static inline uint8_t NVReadVgaCrtc5758(struct drm_device *dev, int head, uint8_t index)
0159 {
0160 NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index);
0161 return NVReadVgaCrtc(dev, head, NV_CIO_CRE_58);
0162 }
0163
0164 static inline uint8_t NVReadPRMVIO(struct drm_device *dev,
0165 int head, uint32_t reg)
0166 {
0167 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0168 struct nouveau_drm *drm = nouveau_drm(dev);
0169 uint8_t val;
0170
0171
0172
0173 if (head && drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE)
0174 reg += NV_PRMVIO_SIZE;
0175
0176 val = nvif_rd08(device, reg);
0177 return val;
0178 }
0179
0180 static inline void NVWritePRMVIO(struct drm_device *dev,
0181 int head, uint32_t reg, uint8_t value)
0182 {
0183 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0184 struct nouveau_drm *drm = nouveau_drm(dev);
0185
0186
0187
0188 if (head && drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE)
0189 reg += NV_PRMVIO_SIZE;
0190
0191 nvif_wr08(device, reg, value);
0192 }
0193
0194 static inline void NVSetEnablePalette(struct drm_device *dev, int head, bool enable)
0195 {
0196 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0197 nvif_rd08(device, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
0198 nvif_wr08(device, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20);
0199 }
0200
0201 static inline bool NVGetEnablePalette(struct drm_device *dev, int head)
0202 {
0203 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0204 nvif_rd08(device, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
0205 return !(nvif_rd08(device, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20);
0206 }
0207
0208 static inline void NVWriteVgaAttr(struct drm_device *dev,
0209 int head, uint8_t index, uint8_t value)
0210 {
0211 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0212 if (NVGetEnablePalette(dev, head))
0213 index &= ~0x20;
0214 else
0215 index |= 0x20;
0216
0217 nvif_rd08(device, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
0218 nvif_wr08(device, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
0219 nvif_wr08(device, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value);
0220 }
0221
0222 static inline uint8_t NVReadVgaAttr(struct drm_device *dev,
0223 int head, uint8_t index)
0224 {
0225 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0226 uint8_t val;
0227 if (NVGetEnablePalette(dev, head))
0228 index &= ~0x20;
0229 else
0230 index |= 0x20;
0231
0232 nvif_rd08(device, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
0233 nvif_wr08(device, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
0234 val = nvif_rd08(device, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE);
0235 return val;
0236 }
0237
0238 static inline void NVVgaSeqReset(struct drm_device *dev, int head, bool start)
0239 {
0240 NVWriteVgaSeq(dev, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3);
0241 }
0242
0243 static inline void NVVgaProtect(struct drm_device *dev, int head, bool protect)
0244 {
0245 uint8_t seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX);
0246
0247 if (protect) {
0248 NVVgaSeqReset(dev, head, true);
0249 NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20);
0250 } else {
0251
0252 NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20);
0253 NVVgaSeqReset(dev, head, false);
0254 }
0255 NVSetEnablePalette(dev, head, protect);
0256 }
0257
0258 static inline bool
0259 nv_heads_tied(struct drm_device *dev)
0260 {
0261 struct nvif_object *device = &nouveau_drm(dev)->client.device.object;
0262 struct nouveau_drm *drm = nouveau_drm(dev);
0263
0264 if (drm->client.device.info.chipset == 0x11)
0265 return !!(nvif_rd32(device, NV_PBUS_DEBUG_1) & (1 << 28));
0266
0267 return NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44) & 0x4;
0268 }
0269
0270
0271 static inline bool
0272 nv_lock_vga_crtc_base(struct drm_device *dev, int head, bool lock)
0273 {
0274 uint8_t cr11 = NVReadVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX);
0275 bool waslocked = cr11 & 0x80;
0276
0277 if (lock)
0278 cr11 |= 0x80;
0279 else
0280 cr11 &= ~0x80;
0281 NVWriteVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX, cr11);
0282
0283 return waslocked;
0284 }
0285
0286 static inline void
0287 nv_lock_vga_crtc_shadow(struct drm_device *dev, int head, int lock)
0288 {
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 uint8_t cr21 = lock;
0300
0301 if (lock < 0)
0302
0303 cr21 = NVReadVgaCrtc(dev, head, NV_CIO_CRE_21) | 0xfa;
0304
0305 NVWriteVgaCrtc(dev, head, NV_CIO_CRE_21, cr21);
0306 }
0307
0308
0309
0310
0311 static inline bool
0312 NVLockVgaCrtcs(struct drm_device *dev, bool lock)
0313 {
0314 struct nouveau_drm *drm = nouveau_drm(dev);
0315 bool waslocked = !NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX);
0316
0317 NVWriteVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX,
0318 lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE);
0319
0320 if (drm->client.device.info.chipset == 0x11 && !nv_heads_tied(dev))
0321 NVWriteVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX,
0322 lock ? NV_CIO_SR_LOCK_VALUE :
0323 NV_CIO_SR_UNLOCK_RW_VALUE);
0324
0325 return waslocked;
0326 }
0327
0328
0329 #define NV04_CURSOR_SIZE 32
0330
0331 #define NV10_CURSOR_SIZE 64
0332
0333 static inline int nv_cursor_width(struct drm_device *dev)
0334 {
0335 struct nouveau_drm *drm = nouveau_drm(dev);
0336
0337 return drm->client.device.info.family >= NV_DEVICE_INFO_V0_CELSIUS ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
0338 }
0339
0340 static inline void
0341 nv_fix_nv40_hw_cursor(struct drm_device *dev, int head)
0342 {
0343
0344
0345
0346
0347
0348 uint32_t curpos = NVReadRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS);
0349 NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos);
0350 }
0351
0352 static inline void
0353 nv_set_crtc_base(struct drm_device *dev, int head, uint32_t offset)
0354 {
0355 struct nouveau_drm *drm = nouveau_drm(dev);
0356
0357 NVWriteCRTC(dev, head, NV_PCRTC_START, offset);
0358
0359 if (drm->client.device.info.family == NV_DEVICE_INFO_V0_TNT) {
0360
0361
0362
0363
0364 int cre_heb = NVReadVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX);
0365
0366 NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX,
0367 (cre_heb & ~0x40) | ((offset >> 18) & 0x40));
0368 }
0369 }
0370
0371 static inline void
0372 nv_show_cursor(struct drm_device *dev, int head, bool show)
0373 {
0374 struct nouveau_drm *drm = nouveau_drm(dev);
0375 uint8_t *curctl1 =
0376 &nv04_display(dev)->mode_reg.crtc_reg[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX];
0377
0378 if (show)
0379 *curctl1 |= MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
0380 else
0381 *curctl1 &= ~MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
0382 NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1);
0383
0384 if (drm->client.device.info.family == NV_DEVICE_INFO_V0_CURIE)
0385 nv_fix_nv40_hw_cursor(dev, head);
0386 }
0387
0388 static inline uint32_t
0389 nv_pitch_align(struct drm_device *dev, uint32_t width, int bpp)
0390 {
0391 struct nouveau_drm *drm = nouveau_drm(dev);
0392 int mask;
0393
0394 if (bpp == 15)
0395 bpp = 16;
0396 if (bpp == 24)
0397 bpp = 8;
0398
0399
0400 if (drm->client.device.info.family == NV_DEVICE_INFO_V0_TNT)
0401 mask = 128 / bpp - 1;
0402 else
0403 mask = 512 / bpp - 1;
0404
0405 return (width + mask) & ~mask;
0406 }
0407
0408 #endif