aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-05-21 01:44:32 -0400
committerDave Airlie <airlied@redhat.com>2010-05-21 01:44:32 -0400
commitdf696a6fe8b324344eae03127aff0a68d982e1fd (patch)
treefb1805d16381acec5f8a25957bf48ffe7bcd9b38 /drivers
parent5d9b7e2d2db95549aeab129c95d588236137a4c8 (diff)
parent893887ed75cacbfe1a855c63659838e0261d17e8 (diff)
Merge remote branch 'nouveau/for-airlied' into drm-next
* nouveau/for-airlied: drm/nouveau: fix i2c-related init table handlers drm/nouveau: support init table i2c device identifier 0x81 drm/nouveau: ensure we've parsed i2c table entry for INIT_*I2C* handlers drm/nouveau: display error message for any failed init table opcode drm/nouveau: fix init table handlers to return proper error codes drm/nv50: support fractional feedback divider on newer chips drm/nv50: fix monitor detection on certain chipsets drm/nv50: store full dcb i2c entry from vbios drm/nv50: fix suspend/resume with DP outputs drm/nv50: output calculated crtc pll when debugging on drm/nouveau: dump pll limits entries when debugging is on drm/nouveau: bios parser fixes for eDP boards drm/nouveau: fix a nouveau_bo dereference after it's been destroyed drm/nv40: remove some completed ctxprog TODOs drm/nv04: Implement missing nv04 PGRAPH methods in software. drm/nouveau: Use 0x5f instead of 0x9f as imageblit on original NV10.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/Makefile3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c500
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_i2c.c21
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_reg.h1
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fbcon.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv04_graph.c566
-rw-r--r--drivers/gpu/drm/nouveau/nv40_grctx.c5
-rw-r--r--drivers/gpu/drm/nouveau/nv50_calc.c87
-rw-r--r--drivers/gpu/drm/nouveau/nv50_crtc.c46
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c33
-rw-r--r--drivers/gpu/drm/nouveau/nv50_sor.c15
15 files changed, 1067 insertions, 223 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 453df3f6053f..acd31ed861ef 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -22,7 +22,8 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
22 nv50_cursor.o nv50_display.o nv50_fbcon.o \ 22 nv50_cursor.o nv50_display.o nv50_fbcon.o \
23 nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ 23 nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
24 nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ 24 nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
25 nv17_gpio.o nv50_gpio.o 25 nv17_gpio.o nv50_gpio.o \
26 nv50_calc.o
26 27
27nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o 28nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
28nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o 29nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index abc382a9918b..e7e69ccce5c9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -26,6 +26,7 @@
26#define NV_DEBUG_NOTRACE 26#define NV_DEBUG_NOTRACE
27#include "nouveau_drv.h" 27#include "nouveau_drv.h"
28#include "nouveau_hw.h" 28#include "nouveau_hw.h"
29#include "nouveau_encoder.h"
29 30
30/* these defines are made up */ 31/* these defines are made up */
31#define NV_CIO_CRE_44_HEADA 0x0 32#define NV_CIO_CRE_44_HEADA 0x0
@@ -256,6 +257,11 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
256struct init_tbl_entry { 257struct init_tbl_entry {
257 char *name; 258 char *name;
258 uint8_t id; 259 uint8_t id;
260 /* Return:
261 * > 0: success, length of opcode
262 * 0: success, but abort further parsing of table (INIT_DONE etc)
263 * < 0: failure, table parsing will be aborted
264 */
259 int (*handler)(struct nvbios *, uint16_t, struct init_exec *); 265 int (*handler)(struct nvbios *, uint16_t, struct init_exec *);
260}; 266};
261 267
@@ -709,6 +715,83 @@ static int dcb_entry_idx_from_crtchead(struct drm_device *dev)
709 return dcb_entry; 715 return dcb_entry;
710} 716}
711 717
718static int
719read_dcb_i2c_entry(struct drm_device *dev, int dcb_version, uint8_t *i2ctable, int index, struct dcb_i2c_entry *i2c)
720{
721 uint8_t dcb_i2c_ver = dcb_version, headerlen = 0, entry_len = 4;
722 int i2c_entries = DCB_MAX_NUM_I2C_ENTRIES;
723 int recordoffset = 0, rdofs = 1, wrofs = 0;
724 uint8_t port_type = 0;
725
726 if (!i2ctable)
727 return -EINVAL;
728
729 if (dcb_version >= 0x30) {
730 if (i2ctable[0] != dcb_version) /* necessary? */
731 NV_WARN(dev,
732 "DCB I2C table version mismatch (%02X vs %02X)\n",
733 i2ctable[0], dcb_version);
734 dcb_i2c_ver = i2ctable[0];
735 headerlen = i2ctable[1];
736 if (i2ctable[2] <= DCB_MAX_NUM_I2C_ENTRIES)
737 i2c_entries = i2ctable[2];
738 else
739 NV_WARN(dev,
740 "DCB I2C table has more entries than indexable "
741 "(%d entries, max %d)\n", i2ctable[2],
742 DCB_MAX_NUM_I2C_ENTRIES);
743 entry_len = i2ctable[3];
744 /* [4] is i2c_default_indices, read in parse_dcb_table() */
745 }
746 /*
747 * It's your own fault if you call this function on a DCB 1.1 BIOS --
748 * the test below is for DCB 1.2
749 */
750 if (dcb_version < 0x14) {
751 recordoffset = 2;
752 rdofs = 0;
753 wrofs = 1;
754 }
755
756 if (index == 0xf)
757 return 0;
758 if (index >= i2c_entries) {
759 NV_ERROR(dev, "DCB I2C index too big (%d >= %d)\n",
760 index, i2ctable[2]);
761 return -ENOENT;
762 }
763 if (i2ctable[headerlen + entry_len * index + 3] == 0xff) {
764 NV_ERROR(dev, "DCB I2C entry invalid\n");
765 return -EINVAL;
766 }
767
768 if (dcb_i2c_ver >= 0x30) {
769 port_type = i2ctable[headerlen + recordoffset + 3 + entry_len * index];
770
771 /*
772 * Fixup for chips using same address offset for read and
773 * write.
774 */
775 if (port_type == 4) /* seen on C51 */
776 rdofs = wrofs = 1;
777 if (port_type >= 5) /* G80+ */
778 rdofs = wrofs = 0;
779 }
780
781 if (dcb_i2c_ver >= 0x40) {
782 if (port_type != 5 && port_type != 6)
783 NV_WARN(dev, "DCB I2C table has port type %d\n", port_type);
784
785 i2c->entry = ROM32(i2ctable[headerlen + recordoffset + entry_len * index]);
786 }
787
788 i2c->port_type = port_type;
789 i2c->read = i2ctable[headerlen + recordoffset + rdofs + entry_len * index];
790 i2c->write = i2ctable[headerlen + recordoffset + wrofs + entry_len * index];
791
792 return 0;
793}
794
712static struct nouveau_i2c_chan * 795static struct nouveau_i2c_chan *
713init_i2c_device_find(struct drm_device *dev, int i2c_index) 796init_i2c_device_find(struct drm_device *dev, int i2c_index)
714{ 797{
@@ -727,6 +810,20 @@ init_i2c_device_find(struct drm_device *dev, int i2c_index)
727 } 810 }
728 if (i2c_index == 0x80) /* g80+ */ 811 if (i2c_index == 0x80) /* g80+ */
729 i2c_index = dcb->i2c_default_indices & 0xf; 812 i2c_index = dcb->i2c_default_indices & 0xf;
813 else
814 if (i2c_index == 0x81)
815 i2c_index = (dcb->i2c_default_indices & 0xf0) >> 4;
816
817 if (i2c_index > DCB_MAX_NUM_I2C_ENTRIES) {
818 NV_ERROR(dev, "invalid i2c_index 0x%x\n", i2c_index);
819 return NULL;
820 }
821
822 /* Make sure i2c table entry has been parsed, it may not
823 * have been if this is a bus not referenced by a DCB encoder
824 */
825 read_dcb_i2c_entry(dev, dcb->version, dcb->i2c_table,
826 i2c_index, &dcb->i2c[i2c_index]);
730 827
731 return nouveau_i2c_find(dev, i2c_index); 828 return nouveau_i2c_find(dev, i2c_index);
732} 829}
@@ -818,7 +915,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset,
818 NV_ERROR(bios->dev, 915 NV_ERROR(bios->dev,
819 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", 916 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
820 offset, config, count); 917 offset, config, count);
821 return 0; 918 return -EINVAL;
822 } 919 }
823 920
824 configval = ROM32(bios->data[offset + 11 + config * 4]); 921 configval = ROM32(bios->data[offset + 11 + config * 4]);
@@ -920,7 +1017,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset,
920 NV_ERROR(bios->dev, 1017 NV_ERROR(bios->dev,
921 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", 1018 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
922 offset, config, count); 1019 offset, config, count);
923 return 0; 1020 return -EINVAL;
924 } 1021 }
925 1022
926 freq = ROM16(bios->data[offset + 12 + config * 2]); 1023 freq = ROM16(bios->data[offset + 12 + config * 2]);
@@ -1067,6 +1164,126 @@ init_io_flag_condition(struct nvbios *bios, uint16_t offset,
1067} 1164}
1068 1165
1069static int 1166static int
1167init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1168{
1169 /*
1170 * INIT_DP_CONDITION opcode: 0x3A ('')
1171 *
1172 * offset (8 bit): opcode
1173 * offset + 1 (8 bit): "sub" opcode
1174 * offset + 2 (8 bit): unknown
1175 *
1176 */
1177
1178 struct bit_displayport_encoder_table *dpe = NULL;
1179 struct dcb_entry *dcb = bios->display.output;
1180 struct drm_device *dev = bios->dev;
1181 uint8_t cond = bios->data[offset + 1];
1182 int dummy;
1183
1184 BIOSLOG(bios, "0x%04X: subop 0x%02X\n", offset, cond);
1185
1186 if (!iexec->execute)
1187 return 3;
1188
1189 dpe = nouveau_bios_dp_table(dev, dcb, &dummy);
1190 if (!dpe) {
1191 NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset);
1192 return -EINVAL;
1193 }
1194
1195 switch (cond) {
1196 case 0:
1197 {
1198 struct dcb_connector_table_entry *ent =
1199 &bios->dcb.connector.entry[dcb->connector];
1200
1201 if (ent->type != DCB_CONNECTOR_eDP)
1202 iexec->execute = false;
1203 }
1204 break;
1205 case 1:
1206 case 2:
1207 if (!(dpe->unknown & cond))
1208 iexec->execute = false;
1209 break;
1210 case 5:
1211 {
1212 struct nouveau_i2c_chan *auxch;
1213 int ret;
1214
1215 auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index);
1216 if (!auxch)
1217 return -ENODEV;
1218
1219 ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1);
1220 if (ret)
1221 return ret;
1222
1223 if (cond & 1)
1224 iexec->execute = false;
1225 }
1226 break;
1227 default:
1228 NV_WARN(dev, "0x%04X: unknown INIT_3A op: %d\n", offset, cond);
1229 break;
1230 }
1231
1232 if (iexec->execute)
1233 BIOSLOG(bios, "0x%04X: continuing to execute\n", offset);
1234 else
1235 BIOSLOG(bios, "0x%04X: skipping following commands\n", offset);
1236
1237 return 3;
1238}
1239
1240static int
1241init_op_3b(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1242{
1243 /*
1244 * INIT_3B opcode: 0x3B ('')
1245 *
1246 * offset (8 bit): opcode
1247 * offset + 1 (8 bit): crtc index
1248 *
1249 */
1250
1251 uint8_t or = ffs(bios->display.output->or) - 1;
1252 uint8_t index = bios->data[offset + 1];
1253 uint8_t data;
1254
1255 if (!iexec->execute)
1256 return 2;
1257
1258 data = bios_idxprt_rd(bios, 0x3d4, index);
1259 bios_idxprt_wr(bios, 0x3d4, index, data & ~(1 << or));
1260 return 2;
1261}
1262
1263static int
1264init_op_3c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1265{
1266 /*
1267 * INIT_3C opcode: 0x3C ('')
1268 *
1269 * offset (8 bit): opcode
1270 * offset + 1 (8 bit): crtc index
1271 *
1272 */
1273
1274 uint8_t or = ffs(bios->display.output->or) - 1;
1275 uint8_t index = bios->data[offset + 1];
1276 uint8_t data;
1277
1278 if (!iexec->execute)
1279 return 2;
1280
1281 data = bios_idxprt_rd(bios, 0x3d4, index);
1282 bios_idxprt_wr(bios, 0x3d4, index, data | (1 << or));
1283 return 2;
1284}
1285
1286static int
1070init_idx_addr_latched(struct nvbios *bios, uint16_t offset, 1287init_idx_addr_latched(struct nvbios *bios, uint16_t offset,
1071 struct init_exec *iexec) 1288 struct init_exec *iexec)
1072{ 1289{
@@ -1170,7 +1387,7 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset,
1170 NV_ERROR(bios->dev, 1387 NV_ERROR(bios->dev,
1171 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", 1388 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
1172 offset, config, count); 1389 offset, config, count);
1173 return 0; 1390 return -EINVAL;
1174 } 1391 }
1175 1392
1176 freq = ROM32(bios->data[offset + 11 + config * 4]); 1393 freq = ROM32(bios->data[offset + 11 + config * 4]);
@@ -1231,12 +1448,11 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1231 */ 1448 */
1232 1449
1233 uint8_t i2c_index = bios->data[offset + 1]; 1450 uint8_t i2c_index = bios->data[offset + 1];
1234 uint8_t i2c_address = bios->data[offset + 2]; 1451 uint8_t i2c_address = bios->data[offset + 2] >> 1;
1235 uint8_t count = bios->data[offset + 3]; 1452 uint8_t count = bios->data[offset + 3];
1236 int len = 4 + count * 3;
1237 struct nouveau_i2c_chan *chan; 1453 struct nouveau_i2c_chan *chan;
1238 struct i2c_msg msg; 1454 int len = 4 + count * 3;
1239 int i; 1455 int ret, i;
1240 1456
1241 if (!iexec->execute) 1457 if (!iexec->execute)
1242 return len; 1458 return len;
@@ -1247,35 +1463,34 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1247 1463
1248 chan = init_i2c_device_find(bios->dev, i2c_index); 1464 chan = init_i2c_device_find(bios->dev, i2c_index);
1249 if (!chan) 1465 if (!chan)
1250 return 0; 1466 return -ENODEV;
1251 1467
1252 for (i = 0; i < count; i++) { 1468 for (i = 0; i < count; i++) {
1253 uint8_t i2c_reg = bios->data[offset + 4 + i * 3]; 1469 uint8_t reg = bios->data[offset + 4 + i * 3];
1254 uint8_t mask = bios->data[offset + 5 + i * 3]; 1470 uint8_t mask = bios->data[offset + 5 + i * 3];
1255 uint8_t data = bios->data[offset + 6 + i * 3]; 1471 uint8_t data = bios->data[offset + 6 + i * 3];
1256 uint8_t value; 1472 union i2c_smbus_data val;
1257 1473
1258 msg.addr = i2c_address; 1474 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
1259 msg.flags = I2C_M_RD; 1475 I2C_SMBUS_READ, reg,
1260 msg.len = 1; 1476 I2C_SMBUS_BYTE_DATA, &val);
1261 msg.buf = &value; 1477 if (ret < 0)
1262 if (i2c_transfer(&chan->adapter, &msg, 1) != 1) 1478 return ret;
1263 return 0;
1264 1479
1265 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " 1480 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
1266 "Mask: 0x%02X, Data: 0x%02X\n", 1481 "Mask: 0x%02X, Data: 0x%02X\n",
1267 offset, i2c_reg, value, mask, data); 1482 offset, reg, val.byte, mask, data);
1268 1483
1269 value = (value & mask) | data; 1484 if (!bios->execute)
1485 continue;
1270 1486
1271 if (bios->execute) { 1487 val.byte &= mask;
1272 msg.addr = i2c_address; 1488 val.byte |= data;
1273 msg.flags = 0; 1489 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
1274 msg.len = 1; 1490 I2C_SMBUS_WRITE, reg,
1275 msg.buf = &value; 1491 I2C_SMBUS_BYTE_DATA, &val);
1276 if (i2c_transfer(&chan->adapter, &msg, 1) != 1) 1492 if (ret < 0)
1277 return 0; 1493 return ret;
1278 }
1279 } 1494 }
1280 1495
1281 return len; 1496 return len;
@@ -1301,12 +1516,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1301 */ 1516 */
1302 1517
1303 uint8_t i2c_index = bios->data[offset + 1]; 1518 uint8_t i2c_index = bios->data[offset + 1];
1304 uint8_t i2c_address = bios->data[offset + 2]; 1519 uint8_t i2c_address = bios->data[offset + 2] >> 1;
1305 uint8_t count = bios->data[offset + 3]; 1520 uint8_t count = bios->data[offset + 3];
1306 int len = 4 + count * 2;
1307 struct nouveau_i2c_chan *chan; 1521 struct nouveau_i2c_chan *chan;
1308 struct i2c_msg msg; 1522 int len = 4 + count * 2;
1309 int i; 1523 int ret, i;
1310 1524
1311 if (!iexec->execute) 1525 if (!iexec->execute)
1312 return len; 1526 return len;
@@ -1317,23 +1531,25 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1317 1531
1318 chan = init_i2c_device_find(bios->dev, i2c_index); 1532 chan = init_i2c_device_find(bios->dev, i2c_index);
1319 if (!chan) 1533 if (!chan)
1320 return 0; 1534 return -ENODEV;
1321 1535
1322 for (i = 0; i < count; i++) { 1536 for (i = 0; i < count; i++) {
1323 uint8_t i2c_reg = bios->data[offset + 4 + i * 2]; 1537 uint8_t reg = bios->data[offset + 4 + i * 2];
1324 uint8_t data = bios->data[offset + 5 + i * 2]; 1538 union i2c_smbus_data val;
1539
1540 val.byte = bios->data[offset + 5 + i * 2];
1325 1541
1326 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n", 1542 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n",
1327 offset, i2c_reg, data); 1543 offset, reg, val.byte);
1328 1544
1329 if (bios->execute) { 1545 if (!bios->execute)
1330 msg.addr = i2c_address; 1546 continue;
1331 msg.flags = 0; 1547
1332 msg.len = 1; 1548 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
1333 msg.buf = &data; 1549 I2C_SMBUS_WRITE, reg,
1334 if (i2c_transfer(&chan->adapter, &msg, 1) != 1) 1550 I2C_SMBUS_BYTE_DATA, &val);
1335 return 0; 1551 if (ret < 0)
1336 } 1552 return ret;
1337 } 1553 }
1338 1554
1339 return len; 1555 return len;
@@ -1357,7 +1573,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1357 */ 1573 */
1358 1574
1359 uint8_t i2c_index = bios->data[offset + 1]; 1575 uint8_t i2c_index = bios->data[offset + 1];
1360 uint8_t i2c_address = bios->data[offset + 2]; 1576 uint8_t i2c_address = bios->data[offset + 2] >> 1;
1361 uint8_t count = bios->data[offset + 3]; 1577 uint8_t count = bios->data[offset + 3];
1362 int len = 4 + count; 1578 int len = 4 + count;
1363 struct nouveau_i2c_chan *chan; 1579 struct nouveau_i2c_chan *chan;
@@ -1374,7 +1590,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1374 1590
1375 chan = init_i2c_device_find(bios->dev, i2c_index); 1591 chan = init_i2c_device_find(bios->dev, i2c_index);
1376 if (!chan) 1592 if (!chan)
1377 return 0; 1593 return -ENODEV;
1378 1594
1379 for (i = 0; i < count; i++) { 1595 for (i = 0; i < count; i++) {
1380 data[i] = bios->data[offset + 4 + i]; 1596 data[i] = bios->data[offset + 4 + i];
@@ -1388,7 +1604,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1388 msg.len = count; 1604 msg.len = count;
1389 msg.buf = data; 1605 msg.buf = data;
1390 if (i2c_transfer(&chan->adapter, &msg, 1) != 1) 1606 if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
1391 return 0; 1607 return -EIO;
1392 } 1608 }
1393 1609
1394 return len; 1610 return len;
@@ -1427,7 +1643,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1427 1643
1428 reg = get_tmds_index_reg(bios->dev, mlv); 1644 reg = get_tmds_index_reg(bios->dev, mlv);
1429 if (!reg) 1645 if (!reg)
1430 return 0; 1646 return -EINVAL;
1431 1647
1432 bios_wr32(bios, reg, 1648 bios_wr32(bios, reg,
1433 tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); 1649 tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
@@ -1471,7 +1687,7 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
1471 1687
1472 reg = get_tmds_index_reg(bios->dev, mlv); 1688 reg = get_tmds_index_reg(bios->dev, mlv);
1473 if (!reg) 1689 if (!reg)
1474 return 0; 1690 return -EINVAL;
1475 1691
1476 for (i = 0; i < count; i++) { 1692 for (i = 0; i < count; i++) {
1477 uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; 1693 uint8_t tmdsaddr = bios->data[offset + 3 + i * 2];
@@ -1946,7 +2162,7 @@ init_configure_mem(struct nvbios *bios, uint16_t offset,
1946 uint32_t reg, data; 2162 uint32_t reg, data;
1947 2163
1948 if (bios->major_version > 2) 2164 if (bios->major_version > 2)
1949 return 0; 2165 return -ENODEV;
1950 2166
1951 bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( 2167 bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd(
1952 bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); 2168 bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20);
@@ -2001,7 +2217,7 @@ init_configure_clk(struct nvbios *bios, uint16_t offset,
2001 int clock; 2217 int clock;
2002 2218
2003 if (bios->major_version > 2) 2219 if (bios->major_version > 2)
2004 return 0; 2220 return -ENODEV;
2005 2221
2006 clock = ROM16(bios->data[meminitoffs + 4]) * 10; 2222 clock = ROM16(bios->data[meminitoffs + 4]) * 10;
2007 setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); 2223 setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock);
@@ -2034,7 +2250,7 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset,
2034 uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); 2250 uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6));
2035 2251
2036 if (bios->major_version > 2) 2252 if (bios->major_version > 2)
2037 return 0; 2253 return -ENODEV;
2038 2254
2039 bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, 2255 bios_idxprt_wr(bios, NV_CIO_CRX__COLOR,
2040 NV_CIO_CRE_SCRATCH4__INDEX, cr3c); 2256 NV_CIO_CRE_SCRATCH4__INDEX, cr3c);
@@ -2656,7 +2872,7 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
2656 NV_ERROR(bios->dev, 2872 NV_ERROR(bios->dev,
2657 "0x%04X: Zero block length - has the M table " 2873 "0x%04X: Zero block length - has the M table "
2658 "been parsed?\n", offset); 2874 "been parsed?\n", offset);
2659 return 0; 2875 return -EINVAL;
2660 } 2876 }
2661 2877
2662 strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; 2878 strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf;
@@ -2840,14 +3056,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
2840 3056
2841 if (!bios->display.output) { 3057 if (!bios->display.output) {
2842 NV_ERROR(dev, "INIT_AUXCH: no active output\n"); 3058 NV_ERROR(dev, "INIT_AUXCH: no active output\n");
2843 return 0; 3059 return -EINVAL;
2844 } 3060 }
2845 3061
2846 auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); 3062 auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
2847 if (!auxch) { 3063 if (!auxch) {
2848 NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", 3064 NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n",
2849 bios->display.output->i2c_index); 3065 bios->display.output->i2c_index);
2850 return 0; 3066 return -ENODEV;
2851 } 3067 }
2852 3068
2853 if (!iexec->execute) 3069 if (!iexec->execute)
@@ -2860,7 +3076,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
2860 ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); 3076 ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1);
2861 if (ret) { 3077 if (ret) {
2862 NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); 3078 NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret);
2863 return 0; 3079 return ret;
2864 } 3080 }
2865 3081
2866 data &= bios->data[offset + 0]; 3082 data &= bios->data[offset + 0];
@@ -2869,7 +3085,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
2869 ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); 3085 ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1);
2870 if (ret) { 3086 if (ret) {
2871 NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); 3087 NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret);
2872 return 0; 3088 return ret;
2873 } 3089 }
2874 } 3090 }
2875 3091
@@ -2899,14 +3115,14 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
2899 3115
2900 if (!bios->display.output) { 3116 if (!bios->display.output) {
2901 NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); 3117 NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n");
2902 return 0; 3118 return -EINVAL;
2903 } 3119 }
2904 3120
2905 auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); 3121 auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
2906 if (!auxch) { 3122 if (!auxch) {
2907 NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", 3123 NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n",
2908 bios->display.output->i2c_index); 3124 bios->display.output->i2c_index);
2909 return 0; 3125 return -ENODEV;
2910 } 3126 }
2911 3127
2912 if (!iexec->execute) 3128 if (!iexec->execute)
@@ -2917,7 +3133,7 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
2917 ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); 3133 ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1);
2918 if (ret) { 3134 if (ret) {
2919 NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); 3135 NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret);
2920 return 0; 3136 return ret;
2921 } 3137 }
2922 } 3138 }
2923 3139
@@ -2934,6 +3150,9 @@ static struct init_tbl_entry itbl_entry[] = {
2934 { "INIT_COPY" , 0x37, init_copy }, 3150 { "INIT_COPY" , 0x37, init_copy },
2935 { "INIT_NOT" , 0x38, init_not }, 3151 { "INIT_NOT" , 0x38, init_not },
2936 { "INIT_IO_FLAG_CONDITION" , 0x39, init_io_flag_condition }, 3152 { "INIT_IO_FLAG_CONDITION" , 0x39, init_io_flag_condition },
3153 { "INIT_DP_CONDITION" , 0x3A, init_dp_condition },
3154 { "INIT_OP_3B" , 0x3B, init_op_3b },
3155 { "INIT_OP_3C" , 0x3C, init_op_3c },
2937 { "INIT_INDEX_ADDRESS_LATCHED" , 0x49, init_idx_addr_latched }, 3156 { "INIT_INDEX_ADDRESS_LATCHED" , 0x49, init_idx_addr_latched },
2938 { "INIT_IO_RESTRICT_PLL2" , 0x4A, init_io_restrict_pll2 }, 3157 { "INIT_IO_RESTRICT_PLL2" , 0x4A, init_io_restrict_pll2 },
2939 { "INIT_PLL2" , 0x4B, init_pll2 }, 3158 { "INIT_PLL2" , 0x4B, init_pll2 },
@@ -3001,7 +3220,7 @@ parse_init_table(struct nvbios *bios, unsigned int offset,
3001 * is changed back to EXECUTE. 3220 * is changed back to EXECUTE.
3002 */ 3221 */
3003 3222
3004 int count = 0, i, res; 3223 int count = 0, i, ret;
3005 uint8_t id; 3224 uint8_t id;
3006 3225
3007 /* 3226 /*
@@ -3016,26 +3235,33 @@ parse_init_table(struct nvbios *bios, unsigned int offset,
3016 for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != id); i++) 3235 for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != id); i++)
3017 ; 3236 ;
3018 3237
3019 if (itbl_entry[i].name) { 3238 if (!itbl_entry[i].name) {
3020 BIOSLOG(bios, "0x%04X: [ (0x%02X) - %s ]\n",
3021 offset, itbl_entry[i].id, itbl_entry[i].name);
3022
3023 /* execute eventual command handler */
3024 res = (*itbl_entry[i].handler)(bios, offset, iexec);
3025 if (!res)
3026 break;
3027 /*
3028 * Add the offset of the current command including all data
3029 * of that command. The offset will then be pointing on the
3030 * next op code.
3031 */
3032 offset += res;
3033 } else {
3034 NV_ERROR(bios->dev, 3239 NV_ERROR(bios->dev,
3035 "0x%04X: Init table command not found: " 3240 "0x%04X: Init table command not found: "
3036 "0x%02X\n", offset, id); 3241 "0x%02X\n", offset, id);
3037 return -ENOENT; 3242 return -ENOENT;
3038 } 3243 }
3244
3245 BIOSLOG(bios, "0x%04X: [ (0x%02X) - %s ]\n", offset,
3246 itbl_entry[i].id, itbl_entry[i].name);
3247
3248 /* execute eventual command handler */
3249 ret = (*itbl_entry[i].handler)(bios, offset, iexec);
3250 if (ret < 0) {
3251 NV_ERROR(bios->dev, "0x%04X: Failed parsing init "
3252 "table opcode: %s %d\n", offset,
3253 itbl_entry[i].name, ret);
3254 }
3255
3256 if (ret <= 0)
3257 break;
3258
3259 /*
3260 * Add the offset of the current command including all data
3261 * of that command. The offset will then be pointing on the
3262 * next op code.
3263 */
3264 offset += ret;
3039 } 3265 }
3040 3266
3041 if (offset >= bios->length) 3267 if (offset >= bios->length)
@@ -4285,31 +4511,32 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4285 break; 4511 break;
4286 } 4512 }
4287 4513
4288#if 0 /* for easy debugging */ 4514 NV_DEBUG(dev, "pll.vco1.minfreq: %d\n", pll_lim->vco1.minfreq);
4289 ErrorF("pll.vco1.minfreq: %d\n", pll_lim->vco1.minfreq); 4515 NV_DEBUG(dev, "pll.vco1.maxfreq: %d\n", pll_lim->vco1.maxfreq);
4290 ErrorF("pll.vco1.maxfreq: %d\n", pll_lim->vco1.maxfreq); 4516 NV_DEBUG(dev, "pll.vco1.min_inputfreq: %d\n", pll_lim->vco1.min_inputfreq);
4291 ErrorF("pll.vco2.minfreq: %d\n", pll_lim->vco2.minfreq); 4517 NV_DEBUG(dev, "pll.vco1.max_inputfreq: %d\n", pll_lim->vco1.max_inputfreq);
4292 ErrorF("pll.vco2.maxfreq: %d\n", pll_lim->vco2.maxfreq); 4518 NV_DEBUG(dev, "pll.vco1.min_n: %d\n", pll_lim->vco1.min_n);
4293 4519 NV_DEBUG(dev, "pll.vco1.max_n: %d\n", pll_lim->vco1.max_n);
4294 ErrorF("pll.vco1.min_inputfreq: %d\n", pll_lim->vco1.min_inputfreq); 4520 NV_DEBUG(dev, "pll.vco1.min_m: %d\n", pll_lim->vco1.min_m);
4295 ErrorF("pll.vco1.max_inputfreq: %d\n", pll_lim->vco1.max_inputfreq); 4521 NV_DEBUG(dev, "pll.vco1.max_m: %d\n", pll_lim->vco1.max_m);
4296 ErrorF("pll.vco2.min_inputfreq: %d\n", pll_lim->vco2.min_inputfreq); 4522 if (pll_lim->vco2.maxfreq) {
4297 ErrorF("pll.vco2.max_inputfreq: %d\n", pll_lim->vco2.max_inputfreq); 4523 NV_DEBUG(dev, "pll.vco2.minfreq: %d\n", pll_lim->vco2.minfreq);
4298 4524 NV_DEBUG(dev, "pll.vco2.maxfreq: %d\n", pll_lim->vco2.maxfreq);
4299 ErrorF("pll.vco1.min_n: %d\n", pll_lim->vco1.min_n); 4525 NV_DEBUG(dev, "pll.vco2.min_inputfreq: %d\n", pll_lim->vco2.min_inputfreq);
4300 ErrorF("pll.vco1.max_n: %d\n", pll_lim->vco1.max_n); 4526 NV_DEBUG(dev, "pll.vco2.max_inputfreq: %d\n", pll_lim->vco2.max_inputfreq);
4301 ErrorF("pll.vco1.min_m: %d\n", pll_lim->vco1.min_m); 4527 NV_DEBUG(dev, "pll.vco2.min_n: %d\n", pll_lim->vco2.min_n);
4302 ErrorF("pll.vco1.max_m: %d\n", pll_lim->vco1.max_m); 4528 NV_DEBUG(dev, "pll.vco2.max_n: %d\n", pll_lim->vco2.max_n);
4303 ErrorF("pll.vco2.min_n: %d\n", pll_lim->vco2.min_n); 4529 NV_DEBUG(dev, "pll.vco2.min_m: %d\n", pll_lim->vco2.min_m);
4304 ErrorF("pll.vco2.max_n: %d\n", pll_lim->vco2.max_n); 4530 NV_DEBUG(dev, "pll.vco2.max_m: %d\n", pll_lim->vco2.max_m);
4305 ErrorF("pll.vco2.min_m: %d\n", pll_lim->vco2.min_m); 4531 }
4306 ErrorF("pll.vco2.max_m: %d\n", pll_lim->vco2.max_m); 4532 if (!pll_lim->max_p) {
4307 4533 NV_DEBUG(dev, "pll.max_log2p: %d\n", pll_lim->max_log2p);
4308 ErrorF("pll.max_log2p: %d\n", pll_lim->max_log2p); 4534 NV_DEBUG(dev, "pll.log2p_bias: %d\n", pll_lim->log2p_bias);
4309 ErrorF("pll.log2p_bias: %d\n", pll_lim->log2p_bias); 4535 } else {
4310 4536 NV_DEBUG(dev, "pll.min_p: %d\n", pll_lim->min_p);
4311 ErrorF("pll.refclk: %d\n", pll_lim->refclk); 4537 NV_DEBUG(dev, "pll.max_p: %d\n", pll_lim->max_p);
4312#endif 4538 }
4539 NV_DEBUG(dev, "pll.refclk: %d\n", pll_lim->refclk);
4313 4540
4314 return 0; 4541 return 0;
4315} 4542}
@@ -4953,79 +5180,6 @@ static uint16_t findstr(uint8_t *data, int n, const uint8_t *str, int len)
4953 return 0; 5180 return 0;
4954} 5181}
4955 5182
4956static int
4957read_dcb_i2c_entry(struct drm_device *dev, int dcb_version, uint8_t *i2ctable, int index, struct dcb_i2c_entry *i2c)
4958{
4959 uint8_t dcb_i2c_ver = dcb_version, headerlen = 0, entry_len = 4;
4960 int i2c_entries = DCB_MAX_NUM_I2C_ENTRIES;
4961 int recordoffset = 0, rdofs = 1, wrofs = 0;
4962 uint8_t port_type = 0;
4963
4964 if (!i2ctable)
4965 return -EINVAL;
4966
4967 if (dcb_version >= 0x30) {
4968 if (i2ctable[0] != dcb_version) /* necessary? */
4969 NV_WARN(dev,
4970 "DCB I2C table version mismatch (%02X vs %02X)\n",
4971 i2ctable[0], dcb_version);
4972 dcb_i2c_ver = i2ctable[0];
4973 headerlen = i2ctable[1];
4974 if (i2ctable[2] <= DCB_MAX_NUM_I2C_ENTRIES)
4975 i2c_entries = i2ctable[2];
4976 else
4977 NV_WARN(dev,
4978 "DCB I2C table has more entries than indexable "
4979 "(%d entries, max %d)\n", i2ctable[2],
4980 DCB_MAX_NUM_I2C_ENTRIES);
4981 entry_len = i2ctable[3];
4982 /* [4] is i2c_default_indices, read in parse_dcb_table() */
4983 }
4984 /*
4985 * It's your own fault if you call this function on a DCB 1.1 BIOS --
4986 * the test below is for DCB 1.2
4987 */
4988 if (dcb_version < 0x14) {
4989 recordoffset = 2;
4990 rdofs = 0;
4991 wrofs = 1;
4992 }
4993
4994 if (index == 0xf)
4995 return 0;
4996 if (index >= i2c_entries) {
4997 NV_ERROR(dev, "DCB I2C index too big (%d >= %d)\n",
4998 index, i2ctable[2]);
4999 return -ENOENT;
5000 }
5001 if (i2ctable[headerlen + entry_len * index + 3] == 0xff) {
5002 NV_ERROR(dev, "DCB I2C entry invalid\n");
5003 return -EINVAL;
5004 }
5005
5006 if (dcb_i2c_ver >= 0x30) {
5007 port_type = i2ctable[headerlen + recordoffset + 3 + entry_len * index];
5008
5009 /*
5010 * Fixup for chips using same address offset for read and
5011 * write.
5012 */
5013 if (port_type == 4) /* seen on C51 */
5014 rdofs = wrofs = 1;
5015 if (port_type >= 5) /* G80+ */
5016 rdofs = wrofs = 0;
5017 }
5018
5019 if (dcb_i2c_ver >= 0x40 && port_type != 5 && port_type != 6)
5020 NV_WARN(dev, "DCB I2C table has port type %d\n", port_type);
5021
5022 i2c->port_type = port_type;
5023 i2c->read = i2ctable[headerlen + recordoffset + rdofs + entry_len * index];
5024 i2c->write = i2ctable[headerlen + recordoffset + wrofs + entry_len * index];
5025
5026 return 0;
5027}
5028
5029static struct dcb_gpio_entry * 5183static struct dcb_gpio_entry *
5030new_gpio_entry(struct nvbios *bios) 5184new_gpio_entry(struct nvbios *bios)
5031{ 5185{
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index c0d7b0a3ece0..adf4ec2d06c0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -35,6 +35,7 @@
35#define DCB_LOC_ON_CHIP 0 35#define DCB_LOC_ON_CHIP 0
36 36
37struct dcb_i2c_entry { 37struct dcb_i2c_entry {
38 uint32_t entry;
38 uint8_t port_type; 39 uint8_t port_type;
39 uint8_t read, write; 40 uint8_t read, write;
40 struct nouveau_i2c_chan *chan; 41 struct nouveau_i2c_chan *chan;
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index fb164efada3b..6f3c19522377 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -160,11 +160,11 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
160 ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, 160 ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
161 ttm_bo_type_device, &nvbo->placement, align, 0, 161 ttm_bo_type_device, &nvbo->placement, align, 0,
162 false, NULL, size, nouveau_bo_del_ttm); 162 false, NULL, size, nouveau_bo_del_ttm);
163 nvbo->channel = NULL;
164 if (ret) { 163 if (ret) {
165 /* ttm will call nouveau_bo_del_ttm if it fails.. */ 164 /* ttm will call nouveau_bo_del_ttm if it fails.. */
166 return ret; 165 return ret;
167 } 166 }
167 nvbo->channel = NULL;
168 168
169 spin_lock(&dev_priv->ttm.bo_list_lock); 169 spin_lock(&dev_priv->ttm.bo_list_lock);
170 list_add_tail(&nvbo->head, &dev_priv->ttm.bo_list); 170 list_add_tail(&nvbo->head, &dev_priv->ttm.bo_list);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 94d8dd27bde8..5b134438effe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1170,6 +1170,12 @@ int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
1170int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); 1170int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
1171int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); 1171int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
1172 1172
1173/* nv50_calc. */
1174int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk,
1175 int *N1, int *M1, int *N2, int *M2, int *P);
1176int nv50_calc_pll2(struct drm_device *, struct pll_lims *,
1177 int clk, int *N, int *fN, int *M, int *P);
1178
1173#ifndef ioread32_native 1179#ifndef ioread32_native
1174#ifdef __BIG_ENDIAN 1180#ifdef __BIG_ENDIAN
1175#define ioread16_native ioread16be 1181#define ioread16_native ioread16be
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index 9f28b94e479b..e1df8209cd0f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -48,6 +48,8 @@ struct nouveau_encoder {
48 union { 48 union {
49 struct { 49 struct {
50 int mc_unknown; 50 int mc_unknown;
51 uint32_t unk0;
52 uint32_t unk1;
51 int dpcd_version; 53 int dpcd_version;
52 int link_nr; 54 int link_nr;
53 int link_bw; 55 int link_bw;
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
index 88583e7bf651..316a3c7e6eb4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.c
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
@@ -254,16 +254,27 @@ struct nouveau_i2c_chan *
254nouveau_i2c_find(struct drm_device *dev, int index) 254nouveau_i2c_find(struct drm_device *dev, int index)
255{ 255{
256 struct drm_nouveau_private *dev_priv = dev->dev_private; 256 struct drm_nouveau_private *dev_priv = dev->dev_private;
257 struct nvbios *bios = &dev_priv->vbios; 257 struct dcb_i2c_entry *i2c = &dev_priv->vbios.dcb.i2c[index];
258 258
259 if (index >= DCB_MAX_NUM_I2C_ENTRIES) 259 if (index >= DCB_MAX_NUM_I2C_ENTRIES)
260 return NULL; 260 return NULL;
261 261
262 if (!bios->dcb.i2c[index].chan) { 262 if (dev_priv->chipset >= NV_50 && (i2c->entry & 0x00000100)) {
263 if (nouveau_i2c_init(dev, &bios->dcb.i2c[index], index)) 263 uint32_t reg = 0xe500, val;
264 return NULL; 264
265 if (i2c->port_type == 6) {
266 reg += i2c->read * 0x50;
267 val = 0x2002;
268 } else {
269 reg += ((i2c->entry & 0x1e00) >> 9) * 0x50;
270 val = 0xe001;
271 }
272
273 nv_wr32(dev, reg, (nv_rd32(dev, reg) & ~0xf003) | val);
265 } 274 }
266 275
267 return bios->dcb.i2c[index].chan; 276 if (!i2c->chan && nouveau_i2c_init(dev, i2c, index))
277 return NULL;
278 return i2c->chan;
268} 279}
269 280
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index aa9b310e41be..6ca80a3fe70d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_reg.h
+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
@@ -826,6 +826,7 @@
826#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_2 0x02000000 826#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_2 0x02000000
827#define NV50_SOR_DP_UNK118(i,l) (0x0061c118 + (i) * 0x800 + (l) * 0x80) 827#define NV50_SOR_DP_UNK118(i,l) (0x0061c118 + (i) * 0x800 + (l) * 0x80)
828#define NV50_SOR_DP_UNK120(i,l) (0x0061c120 + (i) * 0x800 + (l) * 0x80) 828#define NV50_SOR_DP_UNK120(i,l) (0x0061c120 + (i) * 0x800 + (l) * 0x80)
829#define NV50_SOR_DP_UNK128(i,l) (0x0061c128 + (i) * 0x800 + (l) * 0x80)
829#define NV50_SOR_DP_UNK130(i,l) (0x0061c130 + (i) * 0x800 + (l) * 0x80) 830#define NV50_SOR_DP_UNK130(i,l) (0x0061c130 + (i) * 0x800 + (l) * 0x80)
830 831
831#define NV50_PDISPLAY_USER(i) ((i) * 0x1000 + 0x00640000) 832#define NV50_PDISPLAY_USER(i) ((i) * 0x1000 + 0x00640000)
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
index 603090ee6ac7..1eeac4fae73d 100644
--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
@@ -236,7 +236,7 @@ nv04_fbcon_accel_init(struct fb_info *info)
236 if (ret) 236 if (ret)
237 return ret; 237 return ret;
238 238
239 ret = nv04_fbcon_grobj_new(dev, dev_priv->card_type >= NV_10 ? 239 ret = nv04_fbcon_grobj_new(dev, dev_priv->chipset >= 0x11 ?
240 0x009f : 0x005f, NvImageBlit); 240 0x009f : 0x005f, NvImageBlit);
241 if (ret) 241 if (ret)
242 return ret; 242 return ret;
diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c
index e260986ea65a..618355e9cdd5 100644
--- a/drivers/gpu/drm/nouveau/nv04_graph.c
+++ b/drivers/gpu/drm/nouveau/nv04_graph.c
@@ -532,9 +532,82 @@ nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass,
532 return 0; 532 return 0;
533} 533}
534 534
535static int 535/*
536nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass, 536 * Software methods, why they are needed, and how they all work:
537 int mthd, uint32_t data) 537 *
538 * NV04 and NV05 keep most of the state in PGRAPH context itself, but some
539 * 2d engine settings are kept inside the grobjs themselves. The grobjs are
540 * 3 words long on both. grobj format on NV04 is:
541 *
542 * word 0:
543 * - bits 0-7: class
544 * - bit 12: color key active
545 * - bit 13: clip rect active
546 * - bit 14: if set, destination surface is swizzled and taken from buffer 5
547 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
548 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
549 * NV03_CONTEXT_SURFACE_DST].
550 * - bits 15-17: 2d operation [aka patch config]
551 * - bit 24: patch valid [enables rendering using this object]
552 * - bit 25: surf3d valid [for tex_tri and multitex_tri only]
553 * word 1:
554 * - bits 0-1: mono format
555 * - bits 8-13: color format
556 * - bits 16-31: DMA_NOTIFY instance
557 * word 2:
558 * - bits 0-15: DMA_A instance
559 * - bits 16-31: DMA_B instance
560 *
561 * On NV05 it's:
562 *
563 * word 0:
564 * - bits 0-7: class
565 * - bit 12: color key active
566 * - bit 13: clip rect active
567 * - bit 14: if set, destination surface is swizzled and taken from buffer 5
568 * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
569 * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
570 * NV03_CONTEXT_SURFACE_DST].
571 * - bits 15-17: 2d operation [aka patch config]
572 * - bits 20-22: dither mode
573 * - bit 24: patch valid [enables rendering using this object]
574 * - bit 25: surface_dst/surface_color/surf2d/surf3d valid
575 * - bit 26: surface_src/surface_zeta valid
576 * - bit 27: pattern valid
577 * - bit 28: rop valid
578 * - bit 29: beta1 valid
579 * - bit 30: beta4 valid
580 * word 1:
581 * - bits 0-1: mono format
582 * - bits 8-13: color format
583 * - bits 16-31: DMA_NOTIFY instance
584 * word 2:
585 * - bits 0-15: DMA_A instance
586 * - bits 16-31: DMA_B instance
587 *
588 * NV05 will set/unset the relevant valid bits when you poke the relevant
589 * object-binding methods with object of the proper type, or with the NULL
590 * type. It'll only allow rendering using the grobj if all needed objects
591 * are bound. The needed set of objects depends on selected operation: for
592 * example rop object is needed by ROP_AND, but not by SRCCOPY_AND.
593 *
594 * NV04 doesn't have these methods implemented at all, and doesn't have the
595 * relevant bits in grobj. Instead, it'll allow rendering whenever bit 24
596 * is set. So we have to emulate them in software, internally keeping the
597 * same bits as NV05 does. Since grobjs are aligned to 16 bytes on nv04,
598 * but the last word isn't actually used for anything, we abuse it for this
599 * purpose.
600 *
601 * Actually, NV05 can optionally check bit 24 too, but we disable this since
602 * there's no use for it.
603 *
604 * For unknown reasons, NV04 implements surf3d binding in hardware as an
605 * exception. Also for unknown reasons, NV04 doesn't implement the clipping
606 * methods on the surf3d object, so we have to emulate them too.
607 */
608
609static void
610nv04_graph_set_ctx1(struct nouveau_channel *chan, uint32_t mask, uint32_t value)
538{ 611{
539 struct drm_device *dev = chan->dev; 612 struct drm_device *dev = chan->dev;
540 uint32_t instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4; 613 uint32_t instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
@@ -542,42 +615,509 @@ nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass,
542 uint32_t tmp; 615 uint32_t tmp;
543 616
544 tmp = nv_ri32(dev, instance); 617 tmp = nv_ri32(dev, instance);
545 tmp &= ~0x00038000; 618 tmp &= ~mask;
546 tmp |= ((data & 7) << 15); 619 tmp |= value;
547 620
548 nv_wi32(dev, instance, tmp); 621 nv_wi32(dev, instance, tmp);
549 nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp); 622 nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp);
550 nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp); 623 nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
624}
625
626static void
627nv04_graph_set_ctx_val(struct nouveau_channel *chan, uint32_t mask, uint32_t value)
628{
629 struct drm_device *dev = chan->dev;
630 uint32_t instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
631 uint32_t tmp, ctx1;
632 int class, op, valid = 1;
633
634 ctx1 = nv_ri32(dev, instance);
635 class = ctx1 & 0xff;
636 op = (ctx1 >> 15) & 7;
637 tmp = nv_ri32(dev, instance + 0xc);
638 tmp &= ~mask;
639 tmp |= value;
640 nv_wi32(dev, instance + 0xc, tmp);
641
642 /* check for valid surf2d/surf_dst/surf_color */
643 if (!(tmp & 0x02000000))
644 valid = 0;
645 /* check for valid surf_src/surf_zeta */
646 if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000))
647 valid = 0;
648
649 switch (op) {
650 /* SRCCOPY_AND, SRCCOPY: no extra objects required */
651 case 0:
652 case 3:
653 break;
654 /* ROP_AND: requires pattern and rop */
655 case 1:
656 if (!(tmp & 0x18000000))
657 valid = 0;
658 break;
659 /* BLEND_AND: requires beta1 */
660 case 2:
661 if (!(tmp & 0x20000000))
662 valid = 0;
663 break;
664 /* SRCCOPY_PREMULT, BLEND_PREMULT: beta4 required */
665 case 4:
666 case 5:
667 if (!(tmp & 0x40000000))
668 valid = 0;
669 break;
670 }
671
672 nv04_graph_set_ctx1(chan, 0x01000000, valid << 24);
673}
674
675static int
676nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass,
677 int mthd, uint32_t data)
678{
679 if (data > 5)
680 return 1;
681 /* Old versions of the objects only accept first three operations. */
682 if (data > 2 && grclass < 0x40)
683 return 1;
684 nv04_graph_set_ctx1(chan, 0x00038000, data << 15);
685 /* changing operation changes set of objects needed for validation */
686 nv04_graph_set_ctx_val(chan, 0, 0);
687 return 0;
688}
689
690static int
691nv04_graph_mthd_surf3d_clip_h(struct nouveau_channel *chan, int grclass,
692 int mthd, uint32_t data)
693{
694 uint32_t min = data & 0xffff, max;
695 uint32_t w = data >> 16;
696 if (min & 0x8000)
697 /* too large */
698 return 1;
699 if (w & 0x8000)
700 /* yes, it accepts negative for some reason. */
701 w |= 0xffff0000;
702 max = min + w;
703 max &= 0x3ffff;
704 nv_wr32(chan->dev, 0x40053c, min);
705 nv_wr32(chan->dev, 0x400544, max);
706 return 0;
707}
708
709static int
710nv04_graph_mthd_surf3d_clip_v(struct nouveau_channel *chan, int grclass,
711 int mthd, uint32_t data)
712{
713 uint32_t min = data & 0xffff, max;
714 uint32_t w = data >> 16;
715 if (min & 0x8000)
716 /* too large */
717 return 1;
718 if (w & 0x8000)
719 /* yes, it accepts negative for some reason. */
720 w |= 0xffff0000;
721 max = min + w;
722 max &= 0x3ffff;
723 nv_wr32(chan->dev, 0x400540, min);
724 nv_wr32(chan->dev, 0x400548, max);
551 return 0; 725 return 0;
552} 726}
553 727
728static int
729nv04_graph_mthd_bind_surf2d(struct nouveau_channel *chan, int grclass,
730 int mthd, uint32_t data)
731{
732 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
733 case 0x30:
734 nv04_graph_set_ctx1(chan, 0x00004000, 0);
735 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
736 return 0;
737 case 0x42:
738 nv04_graph_set_ctx1(chan, 0x00004000, 0);
739 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
740 return 0;
741 }
742 return 1;
743}
744
745static int
746nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_channel *chan, int grclass,
747 int mthd, uint32_t data)
748{
749 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
750 case 0x30:
751 nv04_graph_set_ctx1(chan, 0x00004000, 0);
752 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
753 return 0;
754 case 0x42:
755 nv04_graph_set_ctx1(chan, 0x00004000, 0);
756 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
757 return 0;
758 case 0x52:
759 nv04_graph_set_ctx1(chan, 0x00004000, 0x00004000);
760 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
761 return 0;
762 }
763 return 1;
764}
765
766static int
767nv04_graph_mthd_bind_nv01_patt(struct nouveau_channel *chan, int grclass,
768 int mthd, uint32_t data)
769{
770 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
771 case 0x30:
772 nv04_graph_set_ctx_val(chan, 0x08000000, 0);
773 return 0;
774 case 0x18:
775 nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000);
776 return 0;
777 }
778 return 1;
779}
780
781static int
782nv04_graph_mthd_bind_nv04_patt(struct nouveau_channel *chan, int grclass,
783 int mthd, uint32_t data)
784{
785 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
786 case 0x30:
787 nv04_graph_set_ctx_val(chan, 0x08000000, 0);
788 return 0;
789 case 0x44:
790 nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000);
791 return 0;
792 }
793 return 1;
794}
795
796static int
797nv04_graph_mthd_bind_rop(struct nouveau_channel *chan, int grclass,
798 int mthd, uint32_t data)
799{
800 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
801 case 0x30:
802 nv04_graph_set_ctx_val(chan, 0x10000000, 0);
803 return 0;
804 case 0x43:
805 nv04_graph_set_ctx_val(chan, 0x10000000, 0x10000000);
806 return 0;
807 }
808 return 1;
809}
810
811static int
812nv04_graph_mthd_bind_beta1(struct nouveau_channel *chan, int grclass,
813 int mthd, uint32_t data)
814{
815 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
816 case 0x30:
817 nv04_graph_set_ctx_val(chan, 0x20000000, 0);
818 return 0;
819 case 0x12:
820 nv04_graph_set_ctx_val(chan, 0x20000000, 0x20000000);
821 return 0;
822 }
823 return 1;
824}
825
826static int
827nv04_graph_mthd_bind_beta4(struct nouveau_channel *chan, int grclass,
828 int mthd, uint32_t data)
829{
830 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
831 case 0x30:
832 nv04_graph_set_ctx_val(chan, 0x40000000, 0);
833 return 0;
834 case 0x72:
835 nv04_graph_set_ctx_val(chan, 0x40000000, 0x40000000);
836 return 0;
837 }
838 return 1;
839}
840
841static int
842nv04_graph_mthd_bind_surf_dst(struct nouveau_channel *chan, int grclass,
843 int mthd, uint32_t data)
844{
845 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
846 case 0x30:
847 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
848 return 0;
849 case 0x58:
850 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
851 return 0;
852 }
853 return 1;
854}
855
856static int
857nv04_graph_mthd_bind_surf_src(struct nouveau_channel *chan, int grclass,
858 int mthd, uint32_t data)
859{
860 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
861 case 0x30:
862 nv04_graph_set_ctx_val(chan, 0x04000000, 0);
863 return 0;
864 case 0x59:
865 nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000);
866 return 0;
867 }
868 return 1;
869}
870
871static int
872nv04_graph_mthd_bind_surf_color(struct nouveau_channel *chan, int grclass,
873 int mthd, uint32_t data)
874{
875 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
876 case 0x30:
877 nv04_graph_set_ctx_val(chan, 0x02000000, 0);
878 return 0;
879 case 0x5a:
880 nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
881 return 0;
882 }
883 return 1;
884}
885
886static int
887nv04_graph_mthd_bind_surf_zeta(struct nouveau_channel *chan, int grclass,
888 int mthd, uint32_t data)
889{
890 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
891 case 0x30:
892 nv04_graph_set_ctx_val(chan, 0x04000000, 0);
893 return 0;
894 case 0x5b:
895 nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000);
896 return 0;
897 }
898 return 1;
899}
900
901static int
902nv04_graph_mthd_bind_clip(struct nouveau_channel *chan, int grclass,
903 int mthd, uint32_t data)
904{
905 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
906 case 0x30:
907 nv04_graph_set_ctx1(chan, 0x2000, 0);
908 return 0;
909 case 0x19:
910 nv04_graph_set_ctx1(chan, 0x2000, 0x2000);
911 return 0;
912 }
913 return 1;
914}
915
916static int
917nv04_graph_mthd_bind_chroma(struct nouveau_channel *chan, int grclass,
918 int mthd, uint32_t data)
919{
920 switch (nv_ri32(chan->dev, data << 4) & 0xff) {
921 case 0x30:
922 nv04_graph_set_ctx1(chan, 0x1000, 0);
923 return 0;
924 /* Yes, for some reason even the old versions of objects
925 * accept 0x57 and not 0x17. Consistency be damned.
926 */
927 case 0x57:
928 nv04_graph_set_ctx1(chan, 0x1000, 0x1000);
929 return 0;
930 }
931 return 1;
932}
933
554static struct nouveau_pgraph_object_method nv04_graph_mthds_sw[] = { 934static struct nouveau_pgraph_object_method nv04_graph_mthds_sw[] = {
555 { 0x0150, nv04_graph_mthd_set_ref }, 935 { 0x0150, nv04_graph_mthd_set_ref },
556 {} 936 {}
557}; 937};
558 938
559static struct nouveau_pgraph_object_method nv04_graph_mthds_set_operation[] = { 939static struct nouveau_pgraph_object_method nv04_graph_mthds_nv03_gdirect[] = {
940 { 0x0184, nv04_graph_mthd_bind_nv01_patt },
941 { 0x0188, nv04_graph_mthd_bind_rop },
942 { 0x018c, nv04_graph_mthd_bind_beta1 },
943 { 0x0190, nv04_graph_mthd_bind_surf_dst },
944 { 0x02fc, nv04_graph_mthd_set_operation },
945 {},
946};
947
948static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_gdirect[] = {
949 { 0x0188, nv04_graph_mthd_bind_nv04_patt },
950 { 0x018c, nv04_graph_mthd_bind_rop },
951 { 0x0190, nv04_graph_mthd_bind_beta1 },
952 { 0x0194, nv04_graph_mthd_bind_beta4 },
953 { 0x0198, nv04_graph_mthd_bind_surf2d },
954 { 0x02fc, nv04_graph_mthd_set_operation },
955 {},
956};
957
958static struct nouveau_pgraph_object_method nv04_graph_mthds_nv01_imageblit[] = {
959 { 0x0184, nv04_graph_mthd_bind_chroma },
960 { 0x0188, nv04_graph_mthd_bind_clip },
961 { 0x018c, nv04_graph_mthd_bind_nv01_patt },
962 { 0x0190, nv04_graph_mthd_bind_rop },
963 { 0x0194, nv04_graph_mthd_bind_beta1 },
964 { 0x0198, nv04_graph_mthd_bind_surf_dst },
965 { 0x019c, nv04_graph_mthd_bind_surf_src },
966 { 0x02fc, nv04_graph_mthd_set_operation },
967 {},
968};
969
970static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_imageblit_ifc[] = {
971 { 0x0184, nv04_graph_mthd_bind_chroma },
972 { 0x0188, nv04_graph_mthd_bind_clip },
973 { 0x018c, nv04_graph_mthd_bind_nv04_patt },
974 { 0x0190, nv04_graph_mthd_bind_rop },
975 { 0x0194, nv04_graph_mthd_bind_beta1 },
976 { 0x0198, nv04_graph_mthd_bind_beta4 },
977 { 0x019c, nv04_graph_mthd_bind_surf2d },
978 { 0x02fc, nv04_graph_mthd_set_operation },
979 {},
980};
981
982static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_iifc[] = {
983 { 0x0188, nv04_graph_mthd_bind_chroma },
984 { 0x018c, nv04_graph_mthd_bind_clip },
985 { 0x0190, nv04_graph_mthd_bind_nv04_patt },
986 { 0x0194, nv04_graph_mthd_bind_rop },
987 { 0x0198, nv04_graph_mthd_bind_beta1 },
988 { 0x019c, nv04_graph_mthd_bind_beta4 },
989 { 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf },
990 { 0x03e4, nv04_graph_mthd_set_operation },
991 {},
992};
993
994static struct nouveau_pgraph_object_method nv04_graph_mthds_nv01_ifc[] = {
995 { 0x0184, nv04_graph_mthd_bind_chroma },
996 { 0x0188, nv04_graph_mthd_bind_clip },
997 { 0x018c, nv04_graph_mthd_bind_nv01_patt },
998 { 0x0190, nv04_graph_mthd_bind_rop },
999 { 0x0194, nv04_graph_mthd_bind_beta1 },
1000 { 0x0198, nv04_graph_mthd_bind_surf_dst },
1001 { 0x02fc, nv04_graph_mthd_set_operation },
1002 {},
1003};
1004
1005static struct nouveau_pgraph_object_method nv04_graph_mthds_nv03_sifc[] = {
1006 { 0x0184, nv04_graph_mthd_bind_chroma },
1007 { 0x0188, nv04_graph_mthd_bind_nv01_patt },
1008 { 0x018c, nv04_graph_mthd_bind_rop },
1009 { 0x0190, nv04_graph_mthd_bind_beta1 },
1010 { 0x0194, nv04_graph_mthd_bind_surf_dst },
560 { 0x02fc, nv04_graph_mthd_set_operation }, 1011 { 0x02fc, nv04_graph_mthd_set_operation },
561 {}, 1012 {},
562}; 1013};
563 1014
1015static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_sifc[] = {
1016 { 0x0184, nv04_graph_mthd_bind_chroma },
1017 { 0x0188, nv04_graph_mthd_bind_nv04_patt },
1018 { 0x018c, nv04_graph_mthd_bind_rop },
1019 { 0x0190, nv04_graph_mthd_bind_beta1 },
1020 { 0x0194, nv04_graph_mthd_bind_beta4 },
1021 { 0x0198, nv04_graph_mthd_bind_surf2d },
1022 { 0x02fc, nv04_graph_mthd_set_operation },
1023 {},
1024};
1025
1026static struct nouveau_pgraph_object_method nv04_graph_mthds_nv03_sifm[] = {
1027 { 0x0188, nv04_graph_mthd_bind_nv01_patt },
1028 { 0x018c, nv04_graph_mthd_bind_rop },
1029 { 0x0190, nv04_graph_mthd_bind_beta1 },
1030 { 0x0194, nv04_graph_mthd_bind_surf_dst },
1031 { 0x0304, nv04_graph_mthd_set_operation },
1032 {},
1033};
1034
1035static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_sifm[] = {
1036 { 0x0188, nv04_graph_mthd_bind_nv04_patt },
1037 { 0x018c, nv04_graph_mthd_bind_rop },
1038 { 0x0190, nv04_graph_mthd_bind_beta1 },
1039 { 0x0194, nv04_graph_mthd_bind_beta4 },
1040 { 0x0198, nv04_graph_mthd_bind_surf2d_swzsurf },
1041 { 0x0304, nv04_graph_mthd_set_operation },
1042 {},
1043};
1044
1045static struct nouveau_pgraph_object_method nv04_graph_mthds_nv01_shape[] = {
1046 { 0x0184, nv04_graph_mthd_bind_clip },
1047 { 0x0188, nv04_graph_mthd_bind_nv01_patt },
1048 { 0x018c, nv04_graph_mthd_bind_rop },
1049 { 0x0190, nv04_graph_mthd_bind_beta1 },
1050 { 0x0194, nv04_graph_mthd_bind_surf_dst },
1051 { 0x02fc, nv04_graph_mthd_set_operation },
1052 {},
1053};
1054
1055static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_shape[] = {
1056 { 0x0184, nv04_graph_mthd_bind_clip },
1057 { 0x0188, nv04_graph_mthd_bind_nv04_patt },
1058 { 0x018c, nv04_graph_mthd_bind_rop },
1059 { 0x0190, nv04_graph_mthd_bind_beta1 },
1060 { 0x0194, nv04_graph_mthd_bind_beta4 },
1061 { 0x0198, nv04_graph_mthd_bind_surf2d },
1062 { 0x02fc, nv04_graph_mthd_set_operation },
1063 {},
1064};
1065
1066static struct nouveau_pgraph_object_method nv04_graph_mthds_nv03_tex_tri[] = {
1067 { 0x0188, nv04_graph_mthd_bind_clip },
1068 { 0x018c, nv04_graph_mthd_bind_surf_color },
1069 { 0x0190, nv04_graph_mthd_bind_surf_zeta },
1070 {},
1071};
1072
1073static struct nouveau_pgraph_object_method nv04_graph_mthds_surf3d[] = {
1074 { 0x02f8, nv04_graph_mthd_surf3d_clip_h },
1075 { 0x02fc, nv04_graph_mthd_surf3d_clip_v },
1076 {},
1077};
1078
564struct nouveau_pgraph_object_class nv04_graph_grclass[] = { 1079struct nouveau_pgraph_object_class nv04_graph_grclass[] = {
565 { 0x0039, false, NULL }, 1080 { 0x0038, false, NULL }, /* dvd subpicture */
566 { 0x004a, false, nv04_graph_mthds_set_operation }, /* gdirect */ 1081 { 0x0039, false, NULL }, /* m2mf */
567 { 0x005f, false, nv04_graph_mthds_set_operation }, /* imageblit */ 1082 { 0x004b, false, nv04_graph_mthds_nv03_gdirect }, /* nv03 gdirect */
568 { 0x0061, false, nv04_graph_mthds_set_operation }, /* ifc */ 1083 { 0x004a, false, nv04_graph_mthds_nv04_gdirect }, /* nv04 gdirect */
569 { 0x0077, false, nv04_graph_mthds_set_operation }, /* sifm */ 1084 { 0x001f, false, nv04_graph_mthds_nv01_imageblit }, /* nv01 imageblit */
1085 { 0x005f, false, nv04_graph_mthds_nv04_imageblit_ifc }, /* nv04 imageblit */
1086 { 0x0060, false, nv04_graph_mthds_nv04_iifc }, /* nv04 iifc */
1087 { 0x0064, false, NULL }, /* nv05 iifc */
1088 { 0x0021, false, nv04_graph_mthds_nv01_ifc }, /* nv01 ifc */
1089 { 0x0061, false, nv04_graph_mthds_nv04_imageblit_ifc }, /* nv04 ifc */
1090 { 0x0065, false, NULL }, /* nv05 ifc */
1091 { 0x0036, false, nv04_graph_mthds_nv03_sifc }, /* nv03 sifc */
1092 { 0x0076, false, nv04_graph_mthds_nv04_sifc }, /* nv04 sifc */
1093 { 0x0066, false, NULL }, /* nv05 sifc */
1094 { 0x0037, false, nv04_graph_mthds_nv03_sifm }, /* nv03 sifm */
1095 { 0x0077, false, nv04_graph_mthds_nv04_sifm }, /* nv04 sifm */
570 { 0x0030, false, NULL }, /* null */ 1096 { 0x0030, false, NULL }, /* null */
571 { 0x0042, false, NULL }, /* surf2d */ 1097 { 0x0042, false, NULL }, /* surf2d */
572 { 0x0043, false, NULL }, /* rop */ 1098 { 0x0043, false, NULL }, /* rop */
573 { 0x0012, false, NULL }, /* beta1 */ 1099 { 0x0012, false, NULL }, /* beta1 */
574 { 0x0072, false, NULL }, /* beta4 */ 1100 { 0x0072, false, NULL }, /* beta4 */
575 { 0x0019, false, NULL }, /* cliprect */ 1101 { 0x0019, false, NULL }, /* cliprect */
576 { 0x0044, false, NULL }, /* pattern */ 1102 { 0x0018, false, NULL }, /* nv01 pattern */
1103 { 0x0044, false, NULL }, /* nv04 pattern */
577 { 0x0052, false, NULL }, /* swzsurf */ 1104 { 0x0052, false, NULL }, /* swzsurf */
578 { 0x0053, false, NULL }, /* surf3d */ 1105 { 0x0053, false, nv04_graph_mthds_surf3d }, /* surf3d */
1106 { 0x0048, false, nv04_graph_mthds_nv03_tex_tri }, /* nv03 tex_tri */
579 { 0x0054, false, NULL }, /* tex_tri */ 1107 { 0x0054, false, NULL }, /* tex_tri */
580 { 0x0055, false, NULL }, /* multitex_tri */ 1108 { 0x0055, false, NULL }, /* multitex_tri */
1109 { 0x0017, false, NULL }, /* nv01 chroma */
1110 { 0x0057, false, NULL }, /* nv04 chroma */
1111 { 0x0058, false, NULL }, /* surf_dst */
1112 { 0x0059, false, NULL }, /* surf_src */
1113 { 0x005a, false, NULL }, /* surf_color */
1114 { 0x005b, false, NULL }, /* surf_zeta */
1115 { 0x001c, false, nv04_graph_mthds_nv01_shape }, /* nv01 line */
1116 { 0x005c, false, nv04_graph_mthds_nv04_shape }, /* nv04 line */
1117 { 0x001d, false, nv04_graph_mthds_nv01_shape }, /* nv01 tri */
1118 { 0x005d, false, nv04_graph_mthds_nv04_shape }, /* nv04 tri */
1119 { 0x001e, false, nv04_graph_mthds_nv01_shape }, /* nv01 rect */
1120 { 0x005e, false, nv04_graph_mthds_nv04_shape }, /* nv04 rect */
581 { 0x506e, true, nv04_graph_mthds_sw }, 1121 { 0x506e, true, nv04_graph_mthds_sw },
582 {} 1122 {}
583}; 1123};
diff --git a/drivers/gpu/drm/nouveau/nv40_grctx.c b/drivers/gpu/drm/nouveau/nv40_grctx.c
index 11b11c31f543..9b5c97469588 100644
--- a/drivers/gpu/drm/nouveau/nv40_grctx.c
+++ b/drivers/gpu/drm/nouveau/nv40_grctx.c
@@ -115,11 +115,6 @@
115 115
116/* TODO: 116/* TODO:
117 * - get vs count from 0x1540 117 * - get vs count from 0x1540
118 * - document unimplemented bits compared to nvidia
119 * - nsource handling
120 * - R0 & 0x0200 handling
121 * - single-vs handling
122 * - 400314 bit 0
123 */ 118 */
124 119
125static int 120static int
diff --git a/drivers/gpu/drm/nouveau/nv50_calc.c b/drivers/gpu/drm/nouveau/nv50_calc.c
new file mode 100644
index 000000000000..2cdc2bfe7179
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_calc.c
@@ -0,0 +1,87 @@
1/*
2 * Copyright 2010 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include "drmP.h"
26#include "drm_fixed.h"
27#include "nouveau_drv.h"
28#include "nouveau_hw.h"
29
30int
31nv50_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk,
32 int *N1, int *M1, int *N2, int *M2, int *P)
33{
34 struct nouveau_pll_vals pll_vals;
35 int ret;
36
37 ret = nouveau_calc_pll_mnp(dev, pll, clk, &pll_vals);
38 if (ret <= 0)
39 return ret;
40
41 *N1 = pll_vals.N1;
42 *M1 = pll_vals.M1;
43 *N2 = pll_vals.N2;
44 *M2 = pll_vals.M2;
45 *P = pll_vals.log2P;
46 return ret;
47}
48
49int
50nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk,
51 int *N, int *fN, int *M, int *P)
52{
53 fixed20_12 fb_div, a, b;
54
55 *P = pll->vco1.maxfreq / clk;
56 if (*P > pll->max_p)
57 *P = pll->max_p;
58 if (*P < pll->min_p)
59 *P = pll->min_p;
60
61 /* *M = ceil(refclk / pll->vco.max_inputfreq); */
62 a.full = dfixed_const(pll->refclk);
63 b.full = dfixed_const(pll->vco1.max_inputfreq);
64 a.full = dfixed_div(a, b);
65 a.full = dfixed_ceil(a);
66 *M = dfixed_trunc(a);
67
68 /* fb_div = (vco * *M) / refclk; */
69 fb_div.full = dfixed_const(clk * *P);
70 fb_div.full = dfixed_mul(fb_div, a);
71 a.full = dfixed_const(pll->refclk);
72 fb_div.full = dfixed_div(fb_div, a);
73
74 /* *N = floor(fb_div); */
75 a.full = dfixed_floor(fb_div);
76 *N = dfixed_trunc(fb_div);
77
78 /* *fN = (fmod(fb_div, 1.0) * 8192) - 4096; */
79 b.full = dfixed_const(8192);
80 a.full = dfixed_mul(a, b);
81 fb_div.full = dfixed_mul(fb_div, b);
82 fb_div.full = fb_div.full - a.full;
83 *fN = dfixed_trunc(fb_div) - 4096;
84 *fN &= 0xffff;
85
86 return clk;
87}
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index cfabeb974a56..b4e4a3b05eae 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -264,32 +264,40 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update)
264int 264int
265nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) 265nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
266{ 266{
267 uint32_t pll_reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head); 267 uint32_t reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head);
268 struct nouveau_pll_vals pll; 268 struct pll_lims pll;
269 struct pll_lims limits;
270 uint32_t reg1, reg2; 269 uint32_t reg1, reg2;
271 int ret; 270 int ret, N1, M1, N2, M2, P;
272 271
273 ret = get_pll_limits(dev, pll_reg, &limits); 272 ret = get_pll_limits(dev, reg, &pll);
274 if (ret) 273 if (ret)
275 return ret; 274 return ret;
276 275
277 ret = nouveau_calc_pll_mnp(dev, &limits, pclk, &pll); 276 if (pll.vco2.maxfreq) {
278 if (ret <= 0) 277 ret = nv50_calc_pll(dev, &pll, pclk, &N1, &M1, &N2, &M2, &P);
279 return ret; 278 if (ret <= 0)
279 return 0;
280
281 NV_DEBUG(dev, "pclk %d out %d NM1 %d %d NM2 %d %d P %d\n",
282 pclk, ret, N1, M1, N2, M2, P);
280 283
281 if (limits.vco2.maxfreq) { 284 reg1 = nv_rd32(dev, reg + 4) & 0xff00ff00;
282 reg1 = nv_rd32(dev, pll_reg + 4) & 0xff00ff00; 285 reg2 = nv_rd32(dev, reg + 8) & 0x8000ff00;
283 reg2 = nv_rd32(dev, pll_reg + 8) & 0x8000ff00; 286 nv_wr32(dev, reg, 0x10000611);
284 nv_wr32(dev, pll_reg, 0x10000611); 287 nv_wr32(dev, reg + 4, reg1 | (M1 << 16) | N1);
285 nv_wr32(dev, pll_reg + 4, reg1 | (pll.M1 << 16) | pll.N1); 288 nv_wr32(dev, reg + 8, reg2 | (P << 28) | (M2 << 16) | N2);
286 nv_wr32(dev, pll_reg + 8,
287 reg2 | (pll.log2P << 28) | (pll.M2 << 16) | pll.N2);
288 } else { 289 } else {
289 reg1 = nv_rd32(dev, pll_reg + 4) & 0xffc00000; 290 ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P);
290 nv_wr32(dev, pll_reg, 0x50000610); 291 if (ret <= 0)
291 nv_wr32(dev, pll_reg + 4, reg1 | 292 return 0;
292 (pll.log2P << 16) | (pll.M1 << 8) | pll.N1); 293
294 NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n",
295 pclk, ret, N1, N2, M1, P);
296
297 reg1 = nv_rd32(dev, reg + 4) & 0xffc00000;
298 nv_wr32(dev, reg, 0x50000610);
299 nv_wr32(dev, reg + 4, reg1 | (P << 16) | (M1 << 8) | N1);
300 nv_wr32(dev, reg + 8, N2);
293 } 301 }
294 302
295 return 0; 303 return 0;
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 34156b69594f..580a5d10be93 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -784,6 +784,37 @@ ack:
784} 784}
785 785
786static void 786static void
787nv50_display_unk20_dp_hack(struct drm_device *dev, struct dcb_entry *dcb)
788{
789 int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1);
790 struct drm_encoder *encoder;
791 uint32_t tmp, unk0 = 0, unk1 = 0;
792
793 if (dcb->type != OUTPUT_DP)
794 return;
795
796 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
797 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
798
799 if (nv_encoder->dcb == dcb) {
800 unk0 = nv_encoder->dp.unk0;
801 unk1 = nv_encoder->dp.unk1;
802 break;
803 }
804 }
805
806 if (unk0 || unk1) {
807 tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
808 tmp &= 0xfffffe03;
809 nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp | unk0);
810
811 tmp = nv_rd32(dev, NV50_SOR_DP_UNK128(or, link));
812 tmp &= 0xfef080c0;
813 nv_wr32(dev, NV50_SOR_DP_UNK128(or, link), tmp | unk1);
814 }
815}
816
817static void
787nv50_display_unk20_handler(struct drm_device *dev) 818nv50_display_unk20_handler(struct drm_device *dev)
788{ 819{
789 struct dcb_entry *dcbent; 820 struct dcb_entry *dcbent;
@@ -806,6 +837,8 @@ nv50_display_unk20_handler(struct drm_device *dev)
806 837
807 nouveau_bios_run_display_table(dev, dcbent, script, pclk); 838 nouveau_bios_run_display_table(dev, dcbent, script, pclk);
808 839
840 nv50_display_unk20_dp_hack(dev, dcbent);
841
809 tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head)); 842 tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head));
810 tmp &= ~0x000000f; 843 tmp &= ~0x000000f;
811 nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp); 844 nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp);
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
index 0c68698f23df..b11eaf9c5c7c 100644
--- a/drivers/gpu/drm/nouveau/nv50_sor.c
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -321,18 +321,23 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
321 encoder->possible_clones = 0; 321 encoder->possible_clones = 0;
322 322
323 if (nv_encoder->dcb->type == OUTPUT_DP) { 323 if (nv_encoder->dcb->type == OUTPUT_DP) {
324 uint32_t mc, or = nv_encoder->or; 324 int or = nv_encoder->or, link = !(entry->dpconf.sor.link & 1);
325 uint32_t tmp;
325 326
326 if (dev_priv->chipset < 0x90 || 327 if (dev_priv->chipset < 0x90 ||
327 dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0) 328 dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
328 mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or)); 329 tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or));
329 else 330 else
330 mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or)); 331 tmp = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or));
331 332
332 switch ((mc & 0x00000f00) >> 8) { 333 switch ((tmp & 0x00000f00) >> 8) {
333 case 8: 334 case 8:
334 case 9: 335 case 9:
335 nv_encoder->dp.mc_unknown = (mc & 0x000f0000) >> 16; 336 nv_encoder->dp.mc_unknown = (tmp & 0x000f0000) >> 16;
337 tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
338 nv_encoder->dp.unk0 = tmp & 0x000001fc;
339 tmp = nv_rd32(dev, NV50_SOR_DP_UNK128(or, link));
340 nv_encoder->dp.unk1 = tmp & 0x010f7f3f;
336 break; 341 break;
337 default: 342 default:
338 break; 343 break;