diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 3c9c54e16a5a..387ac734e9b9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
| @@ -257,6 +257,11 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) | |||
| 257 | struct init_tbl_entry { | 257 | struct init_tbl_entry { |
| 258 | char *name; | 258 | char *name; |
| 259 | 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 | */ | ||
| 260 | int (*handler)(struct nvbios *, uint16_t, struct init_exec *); | 265 | int (*handler)(struct nvbios *, uint16_t, struct init_exec *); |
| 261 | }; | 266 | }; |
| 262 | 267 | ||
| @@ -819,7 +824,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset, | |||
| 819 | NV_ERROR(bios->dev, | 824 | NV_ERROR(bios->dev, |
| 820 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", | 825 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", |
| 821 | offset, config, count); | 826 | offset, config, count); |
| 822 | return 0; | 827 | return -EINVAL; |
| 823 | } | 828 | } |
| 824 | 829 | ||
| 825 | configval = ROM32(bios->data[offset + 11 + config * 4]); | 830 | configval = ROM32(bios->data[offset + 11 + config * 4]); |
| @@ -921,7 +926,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset, | |||
| 921 | NV_ERROR(bios->dev, | 926 | NV_ERROR(bios->dev, |
| 922 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", | 927 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", |
| 923 | offset, config, count); | 928 | offset, config, count); |
| 924 | return 0; | 929 | return -EINVAL; |
| 925 | } | 930 | } |
| 926 | 931 | ||
| 927 | freq = ROM16(bios->data[offset + 12 + config * 2]); | 932 | freq = ROM16(bios->data[offset + 12 + config * 2]); |
| @@ -1291,7 +1296,7 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, | |||
| 1291 | NV_ERROR(bios->dev, | 1296 | NV_ERROR(bios->dev, |
| 1292 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", | 1297 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", |
| 1293 | offset, config, count); | 1298 | offset, config, count); |
| 1294 | return 0; | 1299 | return -EINVAL; |
| 1295 | } | 1300 | } |
| 1296 | 1301 | ||
| 1297 | freq = ROM32(bios->data[offset + 11 + config * 4]); | 1302 | freq = ROM32(bios->data[offset + 11 + config * 4]); |
| @@ -1368,7 +1373,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 1368 | 1373 | ||
| 1369 | chan = init_i2c_device_find(bios->dev, i2c_index); | 1374 | chan = init_i2c_device_find(bios->dev, i2c_index); |
| 1370 | if (!chan) | 1375 | if (!chan) |
| 1371 | return 0; | 1376 | return -ENODEV; |
| 1372 | 1377 | ||
| 1373 | for (i = 0; i < count; i++) { | 1378 | for (i = 0; i < count; i++) { |
| 1374 | uint8_t i2c_reg = bios->data[offset + 4 + i * 3]; | 1379 | uint8_t i2c_reg = bios->data[offset + 4 + i * 3]; |
| @@ -1381,7 +1386,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 1381 | msg.len = 1; | 1386 | msg.len = 1; |
| 1382 | msg.buf = &value; | 1387 | msg.buf = &value; |
| 1383 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) | 1388 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) |
| 1384 | return 0; | 1389 | return -EIO; |
| 1385 | 1390 | ||
| 1386 | BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " | 1391 | BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " |
| 1387 | "Mask: 0x%02X, Data: 0x%02X\n", | 1392 | "Mask: 0x%02X, Data: 0x%02X\n", |
| @@ -1395,7 +1400,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 1395 | msg.len = 1; | 1400 | msg.len = 1; |
| 1396 | msg.buf = &value; | 1401 | msg.buf = &value; |
| 1397 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) | 1402 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) |
| 1398 | return 0; | 1403 | return -EIO; |
| 1399 | } | 1404 | } |
| 1400 | } | 1405 | } |
| 1401 | 1406 | ||
| @@ -1438,7 +1443,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 1438 | 1443 | ||
| 1439 | chan = init_i2c_device_find(bios->dev, i2c_index); | 1444 | chan = init_i2c_device_find(bios->dev, i2c_index); |
| 1440 | if (!chan) | 1445 | if (!chan) |
| 1441 | return 0; | 1446 | return -ENODEV; |
| 1442 | 1447 | ||
| 1443 | for (i = 0; i < count; i++) { | 1448 | for (i = 0; i < count; i++) { |
| 1444 | uint8_t i2c_reg = bios->data[offset + 4 + i * 2]; | 1449 | uint8_t i2c_reg = bios->data[offset + 4 + i * 2]; |
| @@ -1453,7 +1458,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 1453 | msg.len = 1; | 1458 | msg.len = 1; |
| 1454 | msg.buf = &data; | 1459 | msg.buf = &data; |
| 1455 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) | 1460 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) |
| 1456 | return 0; | 1461 | return -EIO; |
| 1457 | } | 1462 | } |
| 1458 | } | 1463 | } |
| 1459 | 1464 | ||
| @@ -1495,7 +1500,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 1495 | 1500 | ||
| 1496 | chan = init_i2c_device_find(bios->dev, i2c_index); | 1501 | chan = init_i2c_device_find(bios->dev, i2c_index); |
| 1497 | if (!chan) | 1502 | if (!chan) |
| 1498 | return 0; | 1503 | return -ENODEV; |
| 1499 | 1504 | ||
| 1500 | for (i = 0; i < count; i++) { | 1505 | for (i = 0; i < count; i++) { |
| 1501 | data[i] = bios->data[offset + 4 + i]; | 1506 | data[i] = bios->data[offset + 4 + i]; |
| @@ -1509,7 +1514,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 1509 | msg.len = count; | 1514 | msg.len = count; |
| 1510 | msg.buf = data; | 1515 | msg.buf = data; |
| 1511 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) | 1516 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) |
| 1512 | return 0; | 1517 | return -EIO; |
| 1513 | } | 1518 | } |
| 1514 | 1519 | ||
| 1515 | return len; | 1520 | return len; |
| @@ -1548,7 +1553,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 1548 | 1553 | ||
| 1549 | reg = get_tmds_index_reg(bios->dev, mlv); | 1554 | reg = get_tmds_index_reg(bios->dev, mlv); |
| 1550 | if (!reg) | 1555 | if (!reg) |
| 1551 | return 0; | 1556 | return -EINVAL; |
| 1552 | 1557 | ||
| 1553 | bios_wr32(bios, reg, | 1558 | bios_wr32(bios, reg, |
| 1554 | tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); | 1559 | tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); |
| @@ -1592,7 +1597,7 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, | |||
| 1592 | 1597 | ||
| 1593 | reg = get_tmds_index_reg(bios->dev, mlv); | 1598 | reg = get_tmds_index_reg(bios->dev, mlv); |
| 1594 | if (!reg) | 1599 | if (!reg) |
| 1595 | return 0; | 1600 | return -EINVAL; |
| 1596 | 1601 | ||
| 1597 | for (i = 0; i < count; i++) { | 1602 | for (i = 0; i < count; i++) { |
| 1598 | uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; | 1603 | uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; |
| @@ -2067,7 +2072,7 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, | |||
| 2067 | uint32_t reg, data; | 2072 | uint32_t reg, data; |
| 2068 | 2073 | ||
| 2069 | if (bios->major_version > 2) | 2074 | if (bios->major_version > 2) |
| 2070 | return 0; | 2075 | return -ENODEV; |
| 2071 | 2076 | ||
| 2072 | bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( | 2077 | bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( |
| 2073 | bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); | 2078 | bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); |
| @@ -2122,7 +2127,7 @@ init_configure_clk(struct nvbios *bios, uint16_t offset, | |||
| 2122 | int clock; | 2127 | int clock; |
| 2123 | 2128 | ||
| 2124 | if (bios->major_version > 2) | 2129 | if (bios->major_version > 2) |
| 2125 | return 0; | 2130 | return -ENODEV; |
| 2126 | 2131 | ||
| 2127 | clock = ROM16(bios->data[meminitoffs + 4]) * 10; | 2132 | clock = ROM16(bios->data[meminitoffs + 4]) * 10; |
| 2128 | setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); | 2133 | setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); |
| @@ -2155,7 +2160,7 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset, | |||
| 2155 | uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); | 2160 | uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); |
| 2156 | 2161 | ||
| 2157 | if (bios->major_version > 2) | 2162 | if (bios->major_version > 2) |
| 2158 | return 0; | 2163 | return -ENODEV; |
| 2159 | 2164 | ||
| 2160 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, | 2165 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, |
| 2161 | NV_CIO_CRE_SCRATCH4__INDEX, cr3c); | 2166 | NV_CIO_CRE_SCRATCH4__INDEX, cr3c); |
| @@ -2777,7 +2782,7 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, | |||
| 2777 | NV_ERROR(bios->dev, | 2782 | NV_ERROR(bios->dev, |
| 2778 | "0x%04X: Zero block length - has the M table " | 2783 | "0x%04X: Zero block length - has the M table " |
| 2779 | "been parsed?\n", offset); | 2784 | "been parsed?\n", offset); |
| 2780 | return 0; | 2785 | return -EINVAL; |
| 2781 | } | 2786 | } |
| 2782 | 2787 | ||
| 2783 | strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; | 2788 | strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; |
| @@ -2961,14 +2966,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 2961 | 2966 | ||
| 2962 | if (!bios->display.output) { | 2967 | if (!bios->display.output) { |
| 2963 | NV_ERROR(dev, "INIT_AUXCH: no active output\n"); | 2968 | NV_ERROR(dev, "INIT_AUXCH: no active output\n"); |
| 2964 | return 0; | 2969 | return -EINVAL; |
| 2965 | } | 2970 | } |
| 2966 | 2971 | ||
| 2967 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); | 2972 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); |
| 2968 | if (!auxch) { | 2973 | if (!auxch) { |
| 2969 | NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", | 2974 | NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", |
| 2970 | bios->display.output->i2c_index); | 2975 | bios->display.output->i2c_index); |
| 2971 | return 0; | 2976 | return -ENODEV; |
| 2972 | } | 2977 | } |
| 2973 | 2978 | ||
| 2974 | if (!iexec->execute) | 2979 | if (!iexec->execute) |
| @@ -2981,7 +2986,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 2981 | ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); | 2986 | ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); |
| 2982 | if (ret) { | 2987 | if (ret) { |
| 2983 | NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); | 2988 | NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); |
| 2984 | return 0; | 2989 | return ret; |
| 2985 | } | 2990 | } |
| 2986 | 2991 | ||
| 2987 | data &= bios->data[offset + 0]; | 2992 | data &= bios->data[offset + 0]; |
| @@ -2990,7 +2995,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 2990 | ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); | 2995 | ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); |
| 2991 | if (ret) { | 2996 | if (ret) { |
| 2992 | NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); | 2997 | NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); |
| 2993 | return 0; | 2998 | return ret; |
| 2994 | } | 2999 | } |
| 2995 | } | 3000 | } |
| 2996 | 3001 | ||
| @@ -3020,14 +3025,14 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 3020 | 3025 | ||
| 3021 | if (!bios->display.output) { | 3026 | if (!bios->display.output) { |
| 3022 | NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); | 3027 | NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); |
| 3023 | return 0; | 3028 | return -EINVAL; |
| 3024 | } | 3029 | } |
| 3025 | 3030 | ||
| 3026 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); | 3031 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); |
| 3027 | if (!auxch) { | 3032 | if (!auxch) { |
| 3028 | NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", | 3033 | NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", |
| 3029 | bios->display.output->i2c_index); | 3034 | bios->display.output->i2c_index); |
| 3030 | return 0; | 3035 | return -ENODEV; |
| 3031 | } | 3036 | } |
| 3032 | 3037 | ||
| 3033 | if (!iexec->execute) | 3038 | if (!iexec->execute) |
| @@ -3038,7 +3043,7 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 3038 | ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); | 3043 | ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); |
| 3039 | if (ret) { | 3044 | if (ret) { |
| 3040 | NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); | 3045 | NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); |
| 3041 | return 0; | 3046 | return ret; |
| 3042 | } | 3047 | } |
| 3043 | } | 3048 | } |
| 3044 | 3049 | ||
