16ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs/* 26ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * Copyright 2008 Stuart Bennett 36ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 46ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * Permission is hereby granted, free of charge, to any person obtaining a 56ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * copy of this software and associated documentation files (the "Software"), 66ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * to deal in the Software without restriction, including without limitation 76ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * the rights to use, copy, modify, merge, publish, distribute, sublicense, 86ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * and/or sell copies of the Software, and to permit persons to whom the 96ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * Software is furnished to do so, subject to the following conditions: 106ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 116ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * The above copyright notice and this permission notice shall be included in 126ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * all copies or substantial portions of the Software. 136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 146ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 156ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 166ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 176ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 186ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 196ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 206ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * SOFTWARE. 216ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs */ 226ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 236ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#ifndef __NOUVEAU_HW_H__ 246ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#define __NOUVEAU_HW_H__ 256ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 266ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#include "drmP.h" 276ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#include "nouveau_drv.h" 286ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 296ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#define MASK(field) ( \ 306ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs (0xffffffff >> (31 - ((1 ? field) - (0 ? field)))) << (0 ? field)) 316ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 326ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#define XLATE(src, srclowbit, outfield) ( \ 336ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs (((src) >> (srclowbit)) << (0 ? outfield)) & MASK(outfield)) 346ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 356ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsvoid NVWriteVgaSeq(struct drm_device *, int head, uint8_t index, uint8_t value); 366ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsuint8_t NVReadVgaSeq(struct drm_device *, int head, uint8_t index); 376ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsvoid NVWriteVgaGr(struct drm_device *, int head, uint8_t index, uint8_t value); 386ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsuint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index); 396ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsvoid NVSetOwner(struct drm_device *, int owner); 406ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsvoid NVBlankScreen(struct drm_device *, int head, bool blank); 416ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsvoid nouveau_hw_setpll(struct drm_device *, uint32_t reg1, 426ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_pll_vals *pv); 436ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsint nouveau_hw_get_pllvals(struct drm_device *, enum pll_types plltype, 446ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_pll_vals *pllvals); 456ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsint nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals); 466ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsint nouveau_hw_get_clock(struct drm_device *, enum pll_types plltype); 476ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsvoid nouveau_hw_save_vga_fonts(struct drm_device *, bool save); 486ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsvoid nouveau_hw_save_state(struct drm_device *, int head, 496ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nv04_mode_state *state); 506ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsvoid nouveau_hw_load_state(struct drm_device *, int head, 516ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nv04_mode_state *state); 526ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsvoid nouveau_hw_load_state_palette(struct drm_device *, int head, 536ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nv04_mode_state *state); 546ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 556ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs/* nouveau_calc.c */ 566ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsextern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp, 576ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int *burst, int *lwm); 586ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsextern int nouveau_calc_pll_mnp(struct drm_device *, struct pll_lims *pll_lim, 596ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int clk, struct nouveau_pll_vals *pv); 606ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 616ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint32_t 626ee738610f41b59733f63718f0bdbcba7d3a3f12Ben SkeggsnvReadMC(struct drm_device *dev, uint32_t reg) 636ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 646ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint32_t val = nv_rd32(dev, reg); 656ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val); 666ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return val; 676ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 686ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 696ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void 706ee738610f41b59733f63718f0bdbcba7d3a3f12Ben SkeggsnvWriteMC(struct drm_device *dev, uint32_t reg, uint32_t val) 716ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 726ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val); 736ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr32(dev, reg, val); 746ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 756ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 766ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint32_t 776ee738610f41b59733f63718f0bdbcba7d3a3f12Ben SkeggsnvReadVIDEO(struct drm_device *dev, uint32_t reg) 786ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 796ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint32_t val = nv_rd32(dev, reg); 806ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val); 816ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return val; 826ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 836ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 846ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void 856ee738610f41b59733f63718f0bdbcba7d3a3f12Ben SkeggsnvWriteVIDEO(struct drm_device *dev, uint32_t reg, uint32_t val) 866ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 876ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val); 886ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr32(dev, reg, val); 896ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 906ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 916ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint32_t 926ee738610f41b59733f63718f0bdbcba7d3a3f12Ben SkeggsnvReadFB(struct drm_device *dev, uint32_t reg) 936ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 946ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint32_t val = nv_rd32(dev, reg); 956ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val); 966ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return val; 976ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 986ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 996ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void 1006ee738610f41b59733f63718f0bdbcba7d3a3f12Ben SkeggsnvWriteFB(struct drm_device *dev, uint32_t reg, uint32_t val) 1016ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1026ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val); 1036ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr32(dev, reg, val); 1046ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1056ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1066ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint32_t 1076ee738610f41b59733f63718f0bdbcba7d3a3f12Ben SkeggsnvReadEXTDEV(struct drm_device *dev, uint32_t reg) 1086ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1096ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint32_t val = nv_rd32(dev, reg); 1106ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val); 1116ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return val; 1126ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1146ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void 1156ee738610f41b59733f63718f0bdbcba7d3a3f12Ben SkeggsnvWriteEXTDEV(struct drm_device *dev, uint32_t reg, uint32_t val) 1166ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1176ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val); 1186ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr32(dev, reg, val); 1196ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1206ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1216ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint32_t NVReadCRTC(struct drm_device *dev, 1226ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int head, uint32_t reg) 1236ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1246ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint32_t val; 1256ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (head) 1266ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs reg += NV_PCRTC0_SIZE; 1276ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs val = nv_rd32(dev, reg); 1286ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val); 1296ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return val; 1306ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1316ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1326ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void NVWriteCRTC(struct drm_device *dev, 1336ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int head, uint32_t reg, uint32_t val) 1346ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1356ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (head) 1366ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs reg += NV_PCRTC0_SIZE; 1376ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val); 1386ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr32(dev, reg, val); 1396ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1406ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1416ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint32_t NVReadRAMDAC(struct drm_device *dev, 1426ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int head, uint32_t reg) 1436ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1446ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint32_t val; 1456ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (head) 1466ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs reg += NV_PRAMDAC0_SIZE; 1476ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs val = nv_rd32(dev, reg); 1486ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n", 1496ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs head, reg, val); 1506ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return val; 1516ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1526ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1536ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void NVWriteRAMDAC(struct drm_device *dev, 1546ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int head, uint32_t reg, uint32_t val) 1556ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1566ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (head) 1576ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs reg += NV_PRAMDAC0_SIZE; 1586ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n", 1596ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs head, reg, val); 1606ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr32(dev, reg, val); 1616ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1626ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1636ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint8_t nv_read_tmds(struct drm_device *dev, 1646ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int or, int dl, uint8_t address) 1656ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1666ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int ramdac = (or & OUTPUT_C) >> 2; 1676ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1686ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, 1696ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address); 1706ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8); 1716ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1726ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1736ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void nv_write_tmds(struct drm_device *dev, 1746ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int or, int dl, uint8_t address, 1756ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint8_t data) 1766ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1776ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int ramdac = (or & OUTPUT_C) >> 2; 1786ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1796ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data); 1806ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address); 1816ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1826ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1836ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void NVWriteVgaCrtc(struct drm_device *dev, 1846ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int head, uint8_t index, uint8_t value) 1856ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1866ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n", 1876ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs head, index, value); 1886ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); 1896ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value); 1906ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1916ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1926ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint8_t NVReadVgaCrtc(struct drm_device *dev, 1936ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int head, uint8_t index) 1946ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 1956ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint8_t val; 1966ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); 1976ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs val = nv_rd08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE); 1986ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n", 1996ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs head, index, val); 2006ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return val; 2016ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2026ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2036ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs/* CR57 and CR58 are a fun pair of regs. CR57 provides an index (0-0xf) for CR58 2046ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * I suspect they in fact do nothing, but are merely a way to carry useful 2056ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * per-head variables around 2066ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 2076ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * Known uses: 2086ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * CR57 CR58 2096ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 0x00 index to the appropriate dcb entry (or 7f for inactive) 2106ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 0x02 dcb entry's "or" value (or 00 for inactive) 2116ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 0x03 bit0 set for dual link (LVDS, possibly elsewhere too) 2126ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 0x08 or 0x09 pxclk in MHz 2136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 0x0f laptop panel info - low nibble for PEXTDEV_BOOT_0 strap 2146ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * high nibble for xlat strap value 2156ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs */ 2166ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2176ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void 2186ee738610f41b59733f63718f0bdbcba7d3a3f12Ben SkeggsNVWriteVgaCrtc5758(struct drm_device *dev, int head, uint8_t index, uint8_t value) 2196ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2206ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index); 2216ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaCrtc(dev, head, NV_CIO_CRE_58, value); 2226ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2236ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2246ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint8_t NVReadVgaCrtc5758(struct drm_device *dev, int head, uint8_t index) 2256ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2266ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index); 2276ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return NVReadVgaCrtc(dev, head, NV_CIO_CRE_58); 2286ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2296ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2306ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint8_t NVReadPRMVIO(struct drm_device *dev, 2316ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int head, uint32_t reg) 2326ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2336ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_nouveau_private *dev_priv = dev->dev_private; 2346ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint8_t val; 2356ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2366ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs /* Only NV4x have two pvio ranges; other twoHeads cards MUST call 2376ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * NVSetOwner for the relevant head to be programmed */ 2386ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (head && dev_priv->card_type == NV_40) 2396ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs reg += NV_PRMVIO_SIZE; 2406ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2416ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs val = nv_rd08(dev, reg); 2426ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", head, reg, val); 2436ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return val; 2446ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2456ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2466ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void NVWritePRMVIO(struct drm_device *dev, 2476ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int head, uint32_t reg, uint8_t value) 2486ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2496ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_nouveau_private *dev_priv = dev->dev_private; 2506ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2516ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs /* Only NV4x have two pvio ranges; other twoHeads cards MUST call 2526ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * NVSetOwner for the relevant head to be programmed */ 2536ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (head && dev_priv->card_type == NV_40) 2546ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs reg += NV_PRMVIO_SIZE; 2556ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2566ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", 2576ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs head, reg, value); 2586ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr08(dev, reg, value); 2596ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2606ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2616ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void NVSetEnablePalette(struct drm_device *dev, int head, bool enable) 2626ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2636ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); 2646ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20); 2656ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2666ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2676ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline bool NVGetEnablePalette(struct drm_device *dev, int head) 2686ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2696ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); 2706ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return !(nv_rd08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20); 2716ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2726ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2736ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void NVWriteVgaAttr(struct drm_device *dev, 2746ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int head, uint8_t index, uint8_t value) 2756ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2766ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (NVGetEnablePalette(dev, head)) 2776ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs index &= ~0x20; 2786ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs else 2796ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs index |= 0x20; 2806ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2816ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); 2826ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n", 2836ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs head, index, value); 2846ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); 2856ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr08(dev, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value); 2866ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2876ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2886ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint8_t NVReadVgaAttr(struct drm_device *dev, 2896ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int head, uint8_t index) 2906ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2916ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint8_t val; 2926ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (NVGetEnablePalette(dev, head)) 2936ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs index &= ~0x20; 2946ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs else 2956ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs index |= 0x20; 2966ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2976ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); 2986ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); 2996ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs val = nv_rd08(dev, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE); 3006ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n", 3016ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs head, index, val); 3026ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return val; 3036ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 3046ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3056ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void NVVgaSeqReset(struct drm_device *dev, int head, bool start) 3066ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 3076ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaSeq(dev, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3); 3086ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 3096ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3106ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void NVVgaProtect(struct drm_device *dev, int head, bool protect) 3116ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 3126ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint8_t seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX); 3136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3146ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (protect) { 3156ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVVgaSeqReset(dev, head, true); 3166ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20); 3176ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs } else { 3186ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs /* Reenable sequencer, then turn on screen */ 3196ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); /* reenable display */ 3206ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVVgaSeqReset(dev, head, false); 3216ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs } 3226ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVSetEnablePalette(dev, head, protect); 3236ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 3246ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3256ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline bool 3266ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnv_heads_tied(struct drm_device *dev) 3276ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 3286ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_nouveau_private *dev_priv = dev->dev_private; 3296ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3306ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (dev_priv->chipset == 0x11) 3316ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return !!(nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28)); 3326ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3336ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44) & 0x4; 3346ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 3356ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3366ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs/* makes cr0-7 on the specified head read-only */ 3376ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline bool 3386ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnv_lock_vga_crtc_base(struct drm_device *dev, int head, bool lock) 3396ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 3406ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint8_t cr11 = NVReadVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX); 3416ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs bool waslocked = cr11 & 0x80; 3426ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3436ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (lock) 3446ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs cr11 |= 0x80; 3456ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs else 3466ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs cr11 &= ~0x80; 3476ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX, cr11); 3486ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3496ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return waslocked; 3506ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 3516ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3526ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void 3536ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnv_lock_vga_crtc_shadow(struct drm_device *dev, int head, int lock) 3546ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 3556ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs /* shadow lock: connects 0x60?3d? regs to "real" 0x3d? regs 3566ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * bit7: unlocks HDT, HBS, HBE, HRS, HRE, HEB 3576ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * bit6: seems to have some effect on CR09 (double scan, VBS_9) 3586ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * bit5: unlocks HDE 3596ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * bit4: unlocks VDE 3606ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * bit3: unlocks VDT, OVL, VRS, ?VRE?, VBS, VBE, LSR, EBR 3616ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * bit2: same as bit 1 of 0x60?804 3626ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * bit0: same as bit 0 of 0x60?804 3636ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs */ 3646ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3656ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint8_t cr21 = lock; 3666ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3676ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (lock < 0) 3686ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs /* 0xfa is generic "unlock all" mask */ 3696ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs cr21 = NVReadVgaCrtc(dev, head, NV_CIO_CRE_21) | 0xfa; 3706ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3716ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaCrtc(dev, head, NV_CIO_CRE_21, cr21); 3726ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 3736ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3746ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs/* renders the extended crtc regs (cr19+) on all crtcs impervious: 3756ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * immutable and unreadable 3766ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs */ 3776ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline bool 3786ee738610f41b59733f63718f0bdbcba7d3a3f12Ben SkeggsNVLockVgaCrtcs(struct drm_device *dev, bool lock) 3796ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 3806ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_nouveau_private *dev_priv = dev->dev_private; 3816ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs bool waslocked = !NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX); 3826ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3836ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX, 3846ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE); 3856ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs /* NV11 has independently lockable extended crtcs, except when tied */ 3866ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (dev_priv->chipset == 0x11 && !nv_heads_tied(dev)) 3876ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX, 3886ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs lock ? NV_CIO_SR_LOCK_VALUE : 3896ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NV_CIO_SR_UNLOCK_RW_VALUE); 3906ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3916ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return waslocked; 3926ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 3936ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3946ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */ 3956ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#define NV04_CURSOR_SIZE 32 3966ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */ 3976ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#define NV10_CURSOR_SIZE 64 3986ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 3996ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline int nv_cursor_width(struct drm_device *dev) 4006ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 4016ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_nouveau_private *dev_priv = dev->dev_private; 4026ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 4036ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return dev_priv->card_type >= NV_10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE; 4046ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 4056ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 4066ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void 4076ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnv_fix_nv40_hw_cursor(struct drm_device *dev, int head) 4086ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 4096ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs /* on some nv40 (such as the "true" (in the NV_PFB_BOOT_0 sense) nv40, 4106ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * the gf6800gt) a hardware bug requires a write to PRAMDAC_CURSOR_POS 4116ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * for changes to the CRTC CURCTL regs to take effect, whether changing 4126ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * the pixmap location, or just showing/hiding the cursor 4136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs */ 4146ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint32_t curpos = NVReadRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS); 4156ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos); 4166ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 4176ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 4186ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline void 4195794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jereznv_set_crtc_base(struct drm_device *dev, int head, uint32_t offset) 4205794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez{ 4215794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez struct drm_nouveau_private *dev_priv = dev->dev_private; 4225794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez 4235794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez NVWriteCRTC(dev, head, NV_PCRTC_START, offset); 4245794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez 4255794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez if (dev_priv->card_type == NV_04) { 4265794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez /* 4275794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez * Hilarious, the 24th bit doesn't want to stick to 4285794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez * PCRTC_START... 4295794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez */ 4305794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez int cre_heb = NVReadVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX); 4315794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez 4325794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX, 4335794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez (cre_heb & ~0x40) | ((offset >> 18) & 0x40)); 4345794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez } 4355794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez} 4365794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerez 4375794b5fdb579abf7be2c27c6e0d6106f391a26e4Francisco Jerezstatic inline void 4386ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnv_show_cursor(struct drm_device *dev, int head, bool show) 4396ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 4406ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_nouveau_private *dev_priv = dev->dev_private; 4416ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs uint8_t *curctl1 = 4426ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs &dev_priv->mode_reg.crtc_reg[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX]; 4436ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 4446ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (show) 4456ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs *curctl1 |= MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE); 4466ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs else 4476ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs *curctl1 &= ~MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE); 4486ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1); 4496ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 4506ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (dev_priv->card_type == NV_40) 4516ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nv_fix_nv40_hw_cursor(dev, head); 4526ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 4536ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 4546ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic inline uint32_t 4556ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnv_pitch_align(struct drm_device *dev, uint32_t width, int bpp) 4566ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 4576ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_nouveau_private *dev_priv = dev->dev_private; 4586ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int mask; 4596ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 4606ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (bpp == 15) 4616ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs bpp = 16; 4626ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (bpp == 24) 4636ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs bpp = 8; 4646ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 4656ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs /* Alignment requirements taken from the Haiku driver */ 4666ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (dev_priv->card_type == NV_04) 4676ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs mask = 128 / bpp - 1; 4686ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs else 4696ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs mask = 512 / bpp - 1; 4706ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 4716ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return (width + mask) & ~mask; 4726ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 4736ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 4746ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#endif /* __NOUVEAU_HW_H__ */ 475