aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/Makefile8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c194
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c19
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c87
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h45
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hw.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_i2c.c41
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_i2c.h8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c15
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_reg.h18
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c91
-rw-r--r--drivers/gpu/drm/nouveau/nv04_crtc.c15
-rw-r--r--drivers/gpu/drm/nouveau/nv04_dfp.c73
-rw-r--r--drivers/gpu/drm/nouveau/nv04_tv.c10
-rw-r--r--drivers/gpu/drm/nouveau/nv10_graph.c175
-rw-r--r--drivers/gpu/drm/nouveau/nv30_fb.c24
-rw-r--r--drivers/gpu/drm/nouveau/nv50_crtc.c34
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c5
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_fb.c38
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_fifo.c96
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_graph.c75
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_instmem.c232
29 files changed, 1128 insertions, 221 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 2405d5ef0ca7..e9b06e4ef2a2 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -12,12 +12,12 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
12 nouveau_dp.o \ 12 nouveau_dp.o \
13 nv04_timer.o \ 13 nv04_timer.o \
14 nv04_mc.o nv40_mc.o nv50_mc.o \ 14 nv04_mc.o nv40_mc.o nv50_mc.o \
15 nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o \ 15 nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o nvc0_fb.o \
16 nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ 16 nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o nvc0_fifo.o \
17 nv04_graph.o nv10_graph.o nv20_graph.o \ 17 nv04_graph.o nv10_graph.o nv20_graph.o \
18 nv40_graph.o nv50_graph.o \ 18 nv40_graph.o nv50_graph.o nvc0_graph.o \
19 nv40_grctx.o nv50_grctx.o \ 19 nv40_grctx.o nv50_grctx.o \
20 nv04_instmem.o nv50_instmem.o \ 20 nv04_instmem.o nv50_instmem.o nvc0_instmem.o \
21 nv50_crtc.o nv50_dac.o nv50_sor.o \ 21 nv50_crtc.o nv50_dac.o nv50_sor.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 \
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 7369b5e73649..0b69a9628c95 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -1928,6 +1928,31 @@ init_condition_time(struct nvbios *bios, uint16_t offset,
1928} 1928}
1929 1929
1930static int 1930static int
1931init_ltime(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1932{
1933 /*
1934 * INIT_LTIME opcode: 0x57 ('V')
1935 *
1936 * offset (8 bit): opcode
1937 * offset + 1 (16 bit): time
1938 *
1939 * Sleep for "time" miliseconds.
1940 */
1941
1942 unsigned time = ROM16(bios->data[offset + 1]);
1943
1944 if (!iexec->execute)
1945 return 3;
1946
1947 BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X miliseconds\n",
1948 offset, time);
1949
1950 msleep(time);
1951
1952 return 3;
1953}
1954
1955static int
1931init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, 1956init_zm_reg_sequence(struct nvbios *bios, uint16_t offset,
1932 struct init_exec *iexec) 1957 struct init_exec *iexec)
1933{ 1958{
@@ -1995,6 +2020,64 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1995} 2020}
1996 2021
1997static int 2022static int
2023init_i2c_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
2024{
2025 /*
2026 * INIT_I2C_IF opcode: 0x5E ('^')
2027 *
2028 * offset (8 bit): opcode
2029 * offset + 1 (8 bit): DCB I2C table entry index
2030 * offset + 2 (8 bit): I2C slave address
2031 * offset + 3 (8 bit): I2C register
2032 * offset + 4 (8 bit): mask
2033 * offset + 5 (8 bit): data
2034 *
2035 * Read the register given by "I2C register" on the device addressed
2036 * by "I2C slave address" on the I2C bus given by "DCB I2C table
2037 * entry index". Compare the result AND "mask" to "data".
2038 * If they're not equal, skip subsequent opcodes until condition is
2039 * inverted (INIT_NOT), or we hit INIT_RESUME
2040 */
2041
2042 uint8_t i2c_index = bios->data[offset + 1];
2043 uint8_t i2c_address = bios->data[offset + 2] >> 1;
2044 uint8_t reg = bios->data[offset + 3];
2045 uint8_t mask = bios->data[offset + 4];
2046 uint8_t data = bios->data[offset + 5];
2047 struct nouveau_i2c_chan *chan;
2048 union i2c_smbus_data val;
2049 int ret;
2050
2051 /* no execute check by design */
2052
2053 BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X\n",
2054 offset, i2c_index, i2c_address);
2055
2056 chan = init_i2c_device_find(bios->dev, i2c_index);
2057 if (!chan)
2058 return -ENODEV;
2059
2060 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
2061 I2C_SMBUS_READ, reg,
2062 I2C_SMBUS_BYTE_DATA, &val);
2063 if (ret < 0) {
2064 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: [no device], "
2065 "Mask: 0x%02X, Data: 0x%02X\n",
2066 offset, reg, mask, data);
2067 iexec->execute = 0;
2068 return 6;
2069 }
2070
2071 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
2072 "Mask: 0x%02X, Data: 0x%02X\n",
2073 offset, reg, val.byte, mask, data);
2074
2075 iexec->execute = ((val.byte & mask) == data);
2076
2077 return 6;
2078}
2079
2080static int
1998init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) 2081init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1999{ 2082{
2000 /* 2083 /*
@@ -2083,9 +2166,10 @@ peek_fb(struct drm_device *dev, struct io_mapping *fb,
2083 uint32_t val = 0; 2166 uint32_t val = 0;
2084 2167
2085 if (off < pci_resource_len(dev->pdev, 1)) { 2168 if (off < pci_resource_len(dev->pdev, 1)) {
2086 uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off, KM_USER0); 2169 uint32_t __iomem *p =
2170 io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0);
2087 2171
2088 val = ioread32(p); 2172 val = ioread32(p + (off & ~PAGE_MASK));
2089 2173
2090 io_mapping_unmap_atomic(p, KM_USER0); 2174 io_mapping_unmap_atomic(p, KM_USER0);
2091 } 2175 }
@@ -2098,9 +2182,10 @@ poke_fb(struct drm_device *dev, struct io_mapping *fb,
2098 uint32_t off, uint32_t val) 2182 uint32_t off, uint32_t val)
2099{ 2183{
2100 if (off < pci_resource_len(dev->pdev, 1)) { 2184 if (off < pci_resource_len(dev->pdev, 1)) {
2101 uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off, KM_USER0); 2185 uint32_t __iomem *p =
2186 io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0);
2102 2187
2103 iowrite32(val, p); 2188 iowrite32(val, p + (off & ~PAGE_MASK));
2104 wmb(); 2189 wmb();
2105 2190
2106 io_mapping_unmap_atomic(p, KM_USER0); 2191 io_mapping_unmap_atomic(p, KM_USER0);
@@ -2165,7 +2250,7 @@ nv04_init_compute_mem(struct nvbios *bios)
2165 NV04_PFB_BOOT_0_RAM_AMOUNT, 2250 NV04_PFB_BOOT_0_RAM_AMOUNT,
2166 NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); 2251 NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
2167 2252
2168 } else if (peek_fb(dev, fb, 0) == patt) { 2253 } else if (peek_fb(dev, fb, 0) != patt) {
2169 if (read_back_fb(dev, fb, 0x800000, patt)) 2254 if (read_back_fb(dev, fb, 0x800000, patt))
2170 bios_md32(bios, NV04_PFB_BOOT_0, 2255 bios_md32(bios, NV04_PFB_BOOT_0,
2171 NV04_PFB_BOOT_0_RAM_AMOUNT, 2256 NV04_PFB_BOOT_0_RAM_AMOUNT,
@@ -2593,7 +2678,7 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset,
2593 /* no iexec->execute check by design */ 2678 /* no iexec->execute check by design */
2594 2679
2595 uint32_t straps = bios_rd32(bios, NV_PEXTDEV_BOOT_0); 2680 uint32_t straps = bios_rd32(bios, NV_PEXTDEV_BOOT_0);
2596 uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); 2681 uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & 0x40) >> 6;
2597 2682
2598 if (bios->major_version > 2) 2683 if (bios->major_version > 2)
2599 return 0; 2684 return 0;
@@ -3140,7 +3225,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3140 const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; 3225 const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
3141 int i; 3226 int i;
3142 3227
3143 if (dev_priv->card_type != NV_50) { 3228 if (dev_priv->card_type < NV_50) {
3144 NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n"); 3229 NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
3145 return 1; 3230 return 1;
3146 } 3231 }
@@ -3490,6 +3575,69 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3490 return len; 3575 return len;
3491} 3576}
3492 3577
3578static int
3579init_i2c_long_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3580{
3581 /*
3582 * INIT_I2C_LONG_IF opcode: 0x9A ('')
3583 *
3584 * offset (8 bit): opcode
3585 * offset + 1 (8 bit): DCB I2C table entry index
3586 * offset + 2 (8 bit): I2C slave address
3587 * offset + 3 (16 bit): I2C register
3588 * offset + 5 (8 bit): mask
3589 * offset + 6 (8 bit): data
3590 *
3591 * Read the register given by "I2C register" on the device addressed
3592 * by "I2C slave address" on the I2C bus given by "DCB I2C table
3593 * entry index". Compare the result AND "mask" to "data".
3594 * If they're not equal, skip subsequent opcodes until condition is
3595 * inverted (INIT_NOT), or we hit INIT_RESUME
3596 */
3597
3598 uint8_t i2c_index = bios->data[offset + 1];
3599 uint8_t i2c_address = bios->data[offset + 2] >> 1;
3600 uint8_t reglo = bios->data[offset + 3];
3601 uint8_t reghi = bios->data[offset + 4];
3602 uint8_t mask = bios->data[offset + 5];
3603 uint8_t data = bios->data[offset + 6];
3604 struct nouveau_i2c_chan *chan;
3605 uint8_t buf0[2] = { reghi, reglo };
3606 uint8_t buf1[1];
3607 struct i2c_msg msg[2] = {
3608 { i2c_address, 0, 1, buf0 },
3609 { i2c_address, I2C_M_RD, 1, buf1 },
3610 };
3611 int ret;
3612
3613 /* no execute check by design */
3614
3615 BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X\n",
3616 offset, i2c_index, i2c_address);
3617
3618 chan = init_i2c_device_find(bios->dev, i2c_index);
3619 if (!chan)
3620 return -ENODEV;
3621
3622
3623 ret = i2c_transfer(&chan->adapter, msg, 2);
3624 if (ret < 0) {
3625 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X:0x%02X, Value: [no device], "
3626 "Mask: 0x%02X, Data: 0x%02X\n",
3627 offset, reghi, reglo, mask, data);
3628 iexec->execute = 0;
3629 return 7;
3630 }
3631
3632 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X:0x%02X, Value: 0x%02X, "
3633 "Mask: 0x%02X, Data: 0x%02X\n",
3634 offset, reghi, reglo, buf1[0], mask, data);
3635
3636 iexec->execute = ((buf1[0] & mask) == data);
3637
3638 return 7;
3639}
3640
3493static struct init_tbl_entry itbl_entry[] = { 3641static struct init_tbl_entry itbl_entry[] = {
3494 /* command name , id , length , offset , mult , command handler */ 3642 /* command name , id , length , offset , mult , command handler */
3495 /* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */ 3643 /* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */
@@ -3516,9 +3664,11 @@ static struct init_tbl_entry itbl_entry[] = {
3516 { "INIT_ZM_CR" , 0x53, init_zm_cr }, 3664 { "INIT_ZM_CR" , 0x53, init_zm_cr },
3517 { "INIT_ZM_CR_GROUP" , 0x54, init_zm_cr_group }, 3665 { "INIT_ZM_CR_GROUP" , 0x54, init_zm_cr_group },
3518 { "INIT_CONDITION_TIME" , 0x56, init_condition_time }, 3666 { "INIT_CONDITION_TIME" , 0x56, init_condition_time },
3667 { "INIT_LTIME" , 0x57, init_ltime },
3519 { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence }, 3668 { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence },
3520 /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */ 3669 /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */
3521 { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct }, 3670 { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct },
3671 { "INIT_I2C_IF" , 0x5E, init_i2c_if },
3522 { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg }, 3672 { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg },
3523 { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io }, 3673 { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io },
3524 { "INIT_COMPUTE_MEM" , 0x63, init_compute_mem }, 3674 { "INIT_COMPUTE_MEM" , 0x63, init_compute_mem },
@@ -3552,6 +3702,7 @@ static struct init_tbl_entry itbl_entry[] = {
3552 { "INIT_97" , 0x97, init_97 }, 3702 { "INIT_97" , 0x97, init_97 },
3553 { "INIT_AUXCH" , 0x98, init_auxch }, 3703 { "INIT_AUXCH" , 0x98, init_auxch },
3554 { "INIT_ZM_AUXCH" , 0x99, init_zm_auxch }, 3704 { "INIT_ZM_AUXCH" , 0x99, init_zm_auxch },
3705 { "INIT_I2C_LONG_IF" , 0x9A, init_i2c_long_if },
3555 { NULL , 0 , NULL } 3706 { NULL , 0 , NULL }
3556}; 3707};
3557 3708
@@ -4410,7 +4561,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
4410 bios->display.script_table_ptr, 4561 bios->display.script_table_ptr,
4411 table[2], table[3], table[0] >= 0x21); 4562 table[2], table[3], table[0] >= 0x21);
4412 if (!otable) { 4563 if (!otable) {
4413 NV_ERROR(dev, "Couldn't find matching output script table\n"); 4564 NV_DEBUG_KMS(dev, "failed to match any output table\n");
4414 return 1; 4565 return 1;
4415 } 4566 }
4416 4567
@@ -4467,7 +4618,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
4467 if (script) 4618 if (script)
4468 script = clkcmptable(bios, script, pxclk); 4619 script = clkcmptable(bios, script, pxclk);
4469 if (!script) { 4620 if (!script) {
4470 NV_ERROR(dev, "clock script 0 not found\n"); 4621 NV_DEBUG_KMS(dev, "clock script 0 not found\n");
4471 return 1; 4622 return 1;
4472 } 4623 }
4473 4624
@@ -4826,7 +4977,7 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
4826 pll_lim->min_p = record[12]; 4977 pll_lim->min_p = record[12];
4827 pll_lim->max_p = record[13]; 4978 pll_lim->max_p = record[13];
4828 /* where did this go to?? */ 4979 /* where did this go to?? */
4829 if (limit_match == 0x00614100 || limit_match == 0x00614900) 4980 if ((entry[0] & 0xf0) == 0x80)
4830 pll_lim->refclk = 27000; 4981 pll_lim->refclk = 27000;
4831 else 4982 else
4832 pll_lim->refclk = 100000; 4983 pll_lim->refclk = 100000;
@@ -5852,7 +6003,7 @@ static void fabricate_vga_output(struct dcb_table *dcb, int i2c, int heads)
5852 entry->i2c_index = i2c; 6003 entry->i2c_index = i2c;
5853 entry->heads = heads; 6004 entry->heads = heads;
5854 entry->location = DCB_LOC_ON_CHIP; 6005 entry->location = DCB_LOC_ON_CHIP;
5855 /* "or" mostly unused in early gen crt modesetting, 0 is fine */ 6006 entry->or = 1;
5856} 6007}
5857 6008
5858static void fabricate_dvi_i_output(struct dcb_table *dcb, bool twoHeads) 6009static void fabricate_dvi_i_output(struct dcb_table *dcb, bool twoHeads)
@@ -5980,7 +6131,13 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
5980 } 6131 }
5981 break; 6132 break;
5982 case OUTPUT_TMDS: 6133 case OUTPUT_TMDS:
5983 entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4; 6134 if (dcb->version >= 0x40)
6135 entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4;
6136 else if (dcb->version >= 0x30)
6137 entry->tmdsconf.slave_addr = (conf & 0x00000700) >> 8;
6138 else if (dcb->version >= 0x22)
6139 entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4;
6140
5984 break; 6141 break;
5985 case 0xe: 6142 case 0xe:
5986 /* weird g80 mobile type that "nv" treats as a terminator */ 6143 /* weird g80 mobile type that "nv" treats as a terminator */
@@ -6270,6 +6427,19 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
6270 dcb->i2c_table = &bios->data[i2ctabptr]; 6427 dcb->i2c_table = &bios->data[i2ctabptr];
6271 if (dcb->version >= 0x30) 6428 if (dcb->version >= 0x30)
6272 dcb->i2c_default_indices = dcb->i2c_table[4]; 6429 dcb->i2c_default_indices = dcb->i2c_table[4];
6430
6431 /*
6432 * Parse the "management" I2C bus, used for hardware
6433 * monitoring and some external TMDS transmitters.
6434 */
6435 if (dcb->version >= 0x22) {
6436 int idx = (dcb->version >= 0x40 ?
6437 dcb->i2c_default_indices & 0xf :
6438 2);
6439
6440 read_dcb_i2c_entry(dev, dcb->version, dcb->i2c_table,
6441 idx, &dcb->i2c[idx]);
6442 }
6273 } 6443 }
6274 6444
6275 if (entries > DCB_MAX_NUM_ENTRIES) 6445 if (entries > DCB_MAX_NUM_ENTRIES)
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index 024458a8d060..fd14dfd3d780 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -131,6 +131,7 @@ struct dcb_entry {
131 } dpconf; 131 } dpconf;
132 struct { 132 struct {
133 struct sor_conf sor; 133 struct sor_conf sor;
134 int slave_addr;
134 } tmdsconf; 135 } tmdsconf;
135 }; 136 };
136 bool i2c_upper_default; 137 bool i2c_upper_default;
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 3ca8343c15df..84f85183d041 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -51,9 +51,6 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
51 if (nvbo->tile) 51 if (nvbo->tile)
52 nv10_mem_expire_tiling(dev, nvbo->tile, NULL); 52 nv10_mem_expire_tiling(dev, nvbo->tile, NULL);
53 53
54 spin_lock(&dev_priv->ttm.bo_list_lock);
55 list_del(&nvbo->head);
56 spin_unlock(&dev_priv->ttm.bo_list_lock);
57 kfree(nvbo); 54 kfree(nvbo);
58} 55}
59 56
@@ -166,9 +163,6 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
166 } 163 }
167 nvbo->channel = NULL; 164 nvbo->channel = NULL;
168 165
169 spin_lock(&dev_priv->ttm.bo_list_lock);
170 list_add_tail(&nvbo->head, &dev_priv->ttm.bo_list);
171 spin_unlock(&dev_priv->ttm.bo_list_lock);
172 *pnvbo = nvbo; 166 *pnvbo = nvbo;
173 return 0; 167 return 0;
174} 168}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 734e92635e83..b1b22baf1428 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -37,12 +37,6 @@
37#include "nouveau_connector.h" 37#include "nouveau_connector.h"
38#include "nouveau_hw.h" 38#include "nouveau_hw.h"
39 39
40static inline struct drm_encoder_slave_funcs *
41get_slave_funcs(struct nouveau_encoder *enc)
42{
43 return to_encoder_slave(to_drm_encoder(enc))->slave_funcs;
44}
45
46static struct nouveau_encoder * 40static struct nouveau_encoder *
47find_encoder_by_type(struct drm_connector *connector, int type) 41find_encoder_by_type(struct drm_connector *connector, int type)
48{ 42{
@@ -360,6 +354,7 @@ nouveau_connector_set_property(struct drm_connector *connector,
360{ 354{
361 struct nouveau_connector *nv_connector = nouveau_connector(connector); 355 struct nouveau_connector *nv_connector = nouveau_connector(connector);
362 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; 356 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
357 struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
363 struct drm_device *dev = connector->dev; 358 struct drm_device *dev = connector->dev;
364 int ret; 359 int ret;
365 360
@@ -432,8 +427,8 @@ nouveau_connector_set_property(struct drm_connector *connector,
432 } 427 }
433 428
434 if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV) 429 if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV)
435 return get_slave_funcs(nv_encoder)-> 430 return get_slave_funcs(encoder)->set_property(
436 set_property(to_drm_encoder(nv_encoder), connector, property, value); 431 encoder, connector, property, value);
437 432
438 return -EINVAL; 433 return -EINVAL;
439} 434}
@@ -545,6 +540,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
545 struct drm_nouveau_private *dev_priv = dev->dev_private; 540 struct drm_nouveau_private *dev_priv = dev->dev_private;
546 struct nouveau_connector *nv_connector = nouveau_connector(connector); 541 struct nouveau_connector *nv_connector = nouveau_connector(connector);
547 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; 542 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
543 struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
548 int ret = 0; 544 int ret = 0;
549 545
550 /* destroy the native mode, the attached monitor could have changed. 546 /* destroy the native mode, the attached monitor could have changed.
@@ -580,8 +576,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
580 } 576 }
581 577
582 if (nv_encoder->dcb->type == OUTPUT_TV) 578 if (nv_encoder->dcb->type == OUTPUT_TV)
583 ret = get_slave_funcs(nv_encoder)-> 579 ret = get_slave_funcs(encoder)->get_modes(encoder, connector);
584 get_modes(to_drm_encoder(nv_encoder), connector);
585 580
586 if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS || 581 if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS ||
587 nv_connector->dcb->type == DCB_CONNECTOR_eDP) 582 nv_connector->dcb->type == DCB_CONNECTOR_eDP)
@@ -597,6 +592,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
597 struct drm_nouveau_private *dev_priv = connector->dev->dev_private; 592 struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
598 struct nouveau_connector *nv_connector = nouveau_connector(connector); 593 struct nouveau_connector *nv_connector = nouveau_connector(connector);
599 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; 594 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
595 struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
600 unsigned min_clock = 25000, max_clock = min_clock; 596 unsigned min_clock = 25000, max_clock = min_clock;
601 unsigned clock = mode->clock; 597 unsigned clock = mode->clock;
602 598
@@ -623,8 +619,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
623 max_clock = 350000; 619 max_clock = 350000;
624 break; 620 break;
625 case OUTPUT_TV: 621 case OUTPUT_TV:
626 return get_slave_funcs(nv_encoder)-> 622 return get_slave_funcs(encoder)->mode_valid(encoder, mode);
627 mode_valid(to_drm_encoder(nv_encoder), mode);
628 case OUTPUT_DP: 623 case OUTPUT_DP:
629 if (nv_encoder->dp.link_bw == DP_LINK_BW_2_7) 624 if (nv_encoder->dp.link_bw == DP_LINK_BW_2_7)
630 max_clock = nv_encoder->dp.link_nr * 270000; 625 max_clock = nv_encoder->dp.link_nr * 270000;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 74e6b4ed12c0..2e11fd65b4dd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -84,16 +84,16 @@ nouveau_user_framebuffer_create(struct drm_device *dev,
84 84
85 gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); 85 gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
86 if (!gem) 86 if (!gem)
87 return NULL; 87 return ERR_PTR(-ENOENT);
88 88
89 nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); 89 nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL);
90 if (!nouveau_fb) 90 if (!nouveau_fb)
91 return NULL; 91 return ERR_PTR(-ENOMEM);
92 92
93 ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem)); 93 ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem));
94 if (ret) { 94 if (ret) {
95 drm_gem_object_unreference(gem); 95 drm_gem_object_unreference(gem);
96 return NULL; 96 return ERR_PTR(ret);
97 } 97 }
98 98
99 return &nouveau_fb->base; 99 return &nouveau_fb->base;
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index 33742b11188b..8a1b188b4cd1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -572,47 +572,64 @@ out:
572 return ret ? ret : (stat & NV50_AUXCH_STAT_REPLY); 572 return ret ? ret : (stat & NV50_AUXCH_STAT_REPLY);
573} 573}
574 574
575int 575static int
576nouveau_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, 576nouveau_dp_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
577 uint8_t write_byte, uint8_t *read_byte)
578{ 577{
579 struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; 578 struct nouveau_i2c_chan *auxch = (struct nouveau_i2c_chan *)adap;
580 struct nouveau_i2c_chan *auxch = (struct nouveau_i2c_chan *)adapter;
581 struct drm_device *dev = auxch->dev; 579 struct drm_device *dev = auxch->dev;
582 int ret = 0, cmd, addr = algo_data->address; 580 struct i2c_msg *msg = msgs;
583 uint8_t *buf; 581 int ret, mcnt = num;
584
585 if (mode == MODE_I2C_READ) {
586 cmd = AUX_I2C_READ;
587 buf = read_byte;
588 } else {
589 cmd = (mode & MODE_I2C_READ) ? AUX_I2C_READ : AUX_I2C_WRITE;
590 buf = &write_byte;
591 }
592 582
593 if (!(mode & MODE_I2C_STOP)) 583 while (mcnt--) {
594 cmd |= AUX_I2C_MOT; 584 u8 remaining = msg->len;
585 u8 *ptr = msg->buf;
595 586
596 if (mode & MODE_I2C_START) 587 while (remaining) {
597 return 1; 588 u8 cnt = (remaining > 16) ? 16 : remaining;
589 u8 cmd;
598 590
599 for (;;) { 591 if (msg->flags & I2C_M_RD)
600 ret = nouveau_dp_auxch(auxch, cmd, addr, buf, 1); 592 cmd = AUX_I2C_READ;
601 if (ret < 0) 593 else
602 return ret; 594 cmd = AUX_I2C_WRITE;
603 595
604 switch (ret & NV50_AUXCH_STAT_REPLY_I2C) { 596 if (mcnt || remaining > 16)
605 case NV50_AUXCH_STAT_REPLY_I2C_ACK: 597 cmd |= AUX_I2C_MOT;
606 return 1; 598
607 case NV50_AUXCH_STAT_REPLY_I2C_NACK: 599 ret = nouveau_dp_auxch(auxch, cmd, msg->addr, ptr, cnt);
608 return -EREMOTEIO; 600 if (ret < 0)
609 case NV50_AUXCH_STAT_REPLY_I2C_DEFER: 601 return ret;
610 udelay(100); 602
611 break; 603 switch (ret & NV50_AUXCH_STAT_REPLY_I2C) {
612 default: 604 case NV50_AUXCH_STAT_REPLY_I2C_ACK:
613 NV_ERROR(dev, "invalid auxch status: 0x%08x\n", ret); 605 break;
614 return -EREMOTEIO; 606 case NV50_AUXCH_STAT_REPLY_I2C_NACK:
607 return -EREMOTEIO;
608 case NV50_AUXCH_STAT_REPLY_I2C_DEFER:
609 udelay(100);
610 continue;
611 default:
612 NV_ERROR(dev, "bad auxch reply: 0x%08x\n", ret);
613 return -EREMOTEIO;
614 }
615
616 ptr += cnt;
617 remaining -= cnt;
615 } 618 }
619
620 msg++;
616 } 621 }
622
623 return num;
624}
625
626static u32
627nouveau_dp_i2c_func(struct i2c_adapter *adap)
628{
629 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
617} 630}
618 631
632const struct i2c_algorithm nouveau_dp_i2c_algo = {
633 .master_xfer = nouveau_dp_i2c_xfer,
634 .functionality = nouveau_dp_i2c_func
635};
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index e15db15dca77..e424bf74d706 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -410,7 +410,7 @@ enum nv04_fp_display_regs {
410 410
411struct nv04_crtc_reg { 411struct nv04_crtc_reg {
412 unsigned char MiscOutReg; /* */ 412 unsigned char MiscOutReg; /* */
413 uint8_t CRTC[0x9f]; 413 uint8_t CRTC[0xa0];
414 uint8_t CR58[0x10]; 414 uint8_t CR58[0x10];
415 uint8_t Sequencer[5]; 415 uint8_t Sequencer[5];
416 uint8_t Graphics[9]; 416 uint8_t Graphics[9];
@@ -509,6 +509,7 @@ enum nouveau_card_type {
509 NV_30 = 0x30, 509 NV_30 = 0x30,
510 NV_40 = 0x40, 510 NV_40 = 0x40,
511 NV_50 = 0x50, 511 NV_50 = 0x50,
512 NV_C0 = 0xc0,
512}; 513};
513 514
514struct drm_nouveau_private { 515struct drm_nouveau_private {
@@ -536,8 +537,6 @@ struct drm_nouveau_private {
536 struct drm_global_reference mem_global_ref; 537 struct drm_global_reference mem_global_ref;
537 struct ttm_bo_global_ref bo_global_ref; 538 struct ttm_bo_global_ref bo_global_ref;
538 struct ttm_bo_device bdev; 539 struct ttm_bo_device bdev;
539 spinlock_t bo_list_lock;
540 struct list_head bo_list;
541 atomic_t validate_sequence; 540 atomic_t validate_sequence;
542 } ttm; 541 } ttm;
543 542
@@ -931,6 +930,10 @@ extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t,
931extern int nv50_fb_init(struct drm_device *); 930extern int nv50_fb_init(struct drm_device *);
932extern void nv50_fb_takedown(struct drm_device *); 931extern void nv50_fb_takedown(struct drm_device *);
933 932
933/* nvc0_fb.c */
934extern int nvc0_fb_init(struct drm_device *);
935extern void nvc0_fb_takedown(struct drm_device *);
936
934/* nv04_fifo.c */ 937/* nv04_fifo.c */
935extern int nv04_fifo_init(struct drm_device *); 938extern int nv04_fifo_init(struct drm_device *);
936extern void nv04_fifo_disable(struct drm_device *); 939extern void nv04_fifo_disable(struct drm_device *);
@@ -968,6 +971,20 @@ extern void nv50_fifo_destroy_context(struct nouveau_channel *);
968extern int nv50_fifo_load_context(struct nouveau_channel *); 971extern int nv50_fifo_load_context(struct nouveau_channel *);
969extern int nv50_fifo_unload_context(struct drm_device *); 972extern int nv50_fifo_unload_context(struct drm_device *);
970 973
974/* nvc0_fifo.c */
975extern int nvc0_fifo_init(struct drm_device *);
976extern void nvc0_fifo_takedown(struct drm_device *);
977extern void nvc0_fifo_disable(struct drm_device *);
978extern void nvc0_fifo_enable(struct drm_device *);
979extern bool nvc0_fifo_reassign(struct drm_device *, bool);
980extern bool nvc0_fifo_cache_flush(struct drm_device *);
981extern bool nvc0_fifo_cache_pull(struct drm_device *, bool);
982extern int nvc0_fifo_channel_id(struct drm_device *);
983extern int nvc0_fifo_create_context(struct nouveau_channel *);
984extern void nvc0_fifo_destroy_context(struct nouveau_channel *);
985extern int nvc0_fifo_load_context(struct nouveau_channel *);
986extern int nvc0_fifo_unload_context(struct drm_device *);
987
971/* nv04_graph.c */ 988/* nv04_graph.c */
972extern struct nouveau_pgraph_object_class nv04_graph_grclass[]; 989extern struct nouveau_pgraph_object_class nv04_graph_grclass[];
973extern int nv04_graph_init(struct drm_device *); 990extern int nv04_graph_init(struct drm_device *);
@@ -1032,6 +1049,16 @@ extern int nv50_graph_unload_context(struct drm_device *);
1032extern void nv50_graph_context_switch(struct drm_device *); 1049extern void nv50_graph_context_switch(struct drm_device *);
1033extern int nv50_grctx_init(struct nouveau_grctx *); 1050extern int nv50_grctx_init(struct nouveau_grctx *);
1034 1051
1052/* nvc0_graph.c */
1053extern int nvc0_graph_init(struct drm_device *);
1054extern void nvc0_graph_takedown(struct drm_device *);
1055extern void nvc0_graph_fifo_access(struct drm_device *, bool);
1056extern struct nouveau_channel *nvc0_graph_channel(struct drm_device *);
1057extern int nvc0_graph_create_context(struct nouveau_channel *);
1058extern void nvc0_graph_destroy_context(struct nouveau_channel *);
1059extern int nvc0_graph_load_context(struct nouveau_channel *);
1060extern int nvc0_graph_unload_context(struct drm_device *);
1061
1035/* nv04_instmem.c */ 1062/* nv04_instmem.c */
1036extern int nv04_instmem_init(struct drm_device *); 1063extern int nv04_instmem_init(struct drm_device *);
1037extern void nv04_instmem_takedown(struct drm_device *); 1064extern void nv04_instmem_takedown(struct drm_device *);
@@ -1058,6 +1085,18 @@ extern void nv50_instmem_flush(struct drm_device *);
1058extern void nv84_instmem_flush(struct drm_device *); 1085extern void nv84_instmem_flush(struct drm_device *);
1059extern void nv50_vm_flush(struct drm_device *, int engine); 1086extern void nv50_vm_flush(struct drm_device *, int engine);
1060 1087
1088/* nvc0_instmem.c */
1089extern int nvc0_instmem_init(struct drm_device *);
1090extern void nvc0_instmem_takedown(struct drm_device *);
1091extern int nvc0_instmem_suspend(struct drm_device *);
1092extern void nvc0_instmem_resume(struct drm_device *);
1093extern int nvc0_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
1094 uint32_t *size);
1095extern void nvc0_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
1096extern int nvc0_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
1097extern int nvc0_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
1098extern void nvc0_instmem_flush(struct drm_device *);
1099
1061/* nv04_mc.c */ 1100/* nv04_mc.c */
1062extern int nv04_mc_init(struct drm_device *); 1101extern int nv04_mc_init(struct drm_device *);
1063extern void nv04_mc_takedown(struct drm_device *); 1102extern void nv04_mc_takedown(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index a1a0d48ae70c..7c82d68bc155 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -71,6 +71,12 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc)
71 return &enc->base.base; 71 return &enc->base.base;
72} 72}
73 73
74static inline struct drm_encoder_slave_funcs *
75get_slave_funcs(struct drm_encoder *enc)
76{
77 return to_encoder_slave(enc)->slave_funcs;
78}
79
74struct nouveau_connector * 80struct nouveau_connector *
75nouveau_encoder_connector_get(struct nouveau_encoder *encoder); 81nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
76int nv50_sor_create(struct drm_connector *, struct dcb_entry *); 82int nv50_sor_create(struct drm_connector *, struct dcb_entry *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 099f637264aa..dbd30b2e43fd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -281,6 +281,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
281 281
282 if (dev_priv->channel && !nouveau_nofbaccel) { 282 if (dev_priv->channel && !nouveau_nofbaccel) {
283 switch (dev_priv->card_type) { 283 switch (dev_priv->card_type) {
284 case NV_C0:
285 break;
284 case NV_50: 286 case NV_50:
285 nv50_fbcon_accel_init(info); 287 nv50_fbcon_accel_init(info);
286 info->fbops = &nv50_fbcon_ops; 288 info->fbops = &nv50_fbcon_ops;
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 547f2c24c1e7..0f417ac1b696 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -284,7 +284,7 @@ retry:
284 if (!gem) { 284 if (!gem) {
285 NV_ERROR(dev, "Unknown handle 0x%08x\n", b->handle); 285 NV_ERROR(dev, "Unknown handle 0x%08x\n", b->handle);
286 validate_fini(op, NULL); 286 validate_fini(op, NULL);
287 return -EINVAL; 287 return -ENOENT;
288 } 288 }
289 nvbo = gem->driver_private; 289 nvbo = gem->driver_private;
290 290
@@ -759,7 +759,7 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
759 759
760 gem = drm_gem_object_lookup(dev, file_priv, req->handle); 760 gem = drm_gem_object_lookup(dev, file_priv, req->handle);
761 if (!gem) 761 if (!gem)
762 return ret; 762 return -ENOENT;
763 nvbo = nouveau_gem_object(gem); 763 nvbo = nouveau_gem_object(gem);
764 764
765 if (nvbo->cpu_filp) { 765 if (nvbo->cpu_filp) {
@@ -797,7 +797,7 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data,
797 797
798 gem = drm_gem_object_lookup(dev, file_priv, req->handle); 798 gem = drm_gem_object_lookup(dev, file_priv, req->handle);
799 if (!gem) 799 if (!gem)
800 return ret; 800 return -ENOENT;
801 nvbo = nouveau_gem_object(gem); 801 nvbo = nouveau_gem_object(gem);
802 802
803 if (nvbo->cpu_filp != file_priv) 803 if (nvbo->cpu_filp != file_priv)
@@ -822,7 +822,7 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data,
822 822
823 gem = drm_gem_object_lookup(dev, file_priv, req->handle); 823 gem = drm_gem_object_lookup(dev, file_priv, req->handle);
824 if (!gem) 824 if (!gem)
825 return -EINVAL; 825 return -ENOENT;
826 826
827 ret = nouveau_gem_info(gem, req); 827 ret = nouveau_gem_info(gem, req);
828 drm_gem_object_unreference_unlocked(gem); 828 drm_gem_object_unreference_unlocked(gem);
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c
index 7855b35effc3..7b613682e400 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.c
@@ -865,8 +865,12 @@ nv_save_state_ext(struct drm_device *dev, int head,
865 rd_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); 865 rd_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX);
866 rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); 866 rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX);
867 rd_cio_state(dev, head, regp, NV_CIO_CRE_21); 867 rd_cio_state(dev, head, regp, NV_CIO_CRE_21);
868 if (dev_priv->card_type >= NV_30) 868
869 if (dev_priv->card_type >= NV_30) {
869 rd_cio_state(dev, head, regp, NV_CIO_CRE_47); 870 rd_cio_state(dev, head, regp, NV_CIO_CRE_47);
871 rd_cio_state(dev, head, regp, 0x9f);
872 }
873
870 rd_cio_state(dev, head, regp, NV_CIO_CRE_49); 874 rd_cio_state(dev, head, regp, NV_CIO_CRE_49);
871 rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); 875 rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
872 rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); 876 rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
@@ -971,8 +975,11 @@ nv_load_state_ext(struct drm_device *dev, int head,
971 wr_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX); 975 wr_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX);
972 wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); 976 wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX);
973 wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); 977 wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX);
974 if (dev_priv->card_type >= NV_30) 978
979 if (dev_priv->card_type >= NV_30) {
975 wr_cio_state(dev, head, regp, NV_CIO_CRE_47); 980 wr_cio_state(dev, head, regp, NV_CIO_CRE_47);
981 wr_cio_state(dev, head, regp, 0x9f);
982 }
976 983
977 wr_cio_state(dev, head, regp, NV_CIO_CRE_49); 984 wr_cio_state(dev, head, regp, NV_CIO_CRE_49);
978 wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); 985 wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
index cb0cb34440c6..0bd407ca3d42 100644
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.c
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
@@ -163,7 +163,7 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
163 if (entry->chan) 163 if (entry->chan)
164 return -EEXIST; 164 return -EEXIST;
165 165
166 if (dev_priv->card_type == NV_50 && entry->read >= NV50_I2C_PORTS) { 166 if (dev_priv->card_type == NV_C0 && entry->read >= NV50_I2C_PORTS) {
167 NV_ERROR(dev, "unknown i2c port %d\n", entry->read); 167 NV_ERROR(dev, "unknown i2c port %d\n", entry->read);
168 return -EINVAL; 168 return -EINVAL;
169 } 169 }
@@ -174,26 +174,26 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
174 174
175 switch (entry->port_type) { 175 switch (entry->port_type) {
176 case 0: 176 case 0:
177 i2c->algo.bit.setsda = nv04_i2c_setsda; 177 i2c->bit.setsda = nv04_i2c_setsda;
178 i2c->algo.bit.setscl = nv04_i2c_setscl; 178 i2c->bit.setscl = nv04_i2c_setscl;
179 i2c->algo.bit.getsda = nv04_i2c_getsda; 179 i2c->bit.getsda = nv04_i2c_getsda;
180 i2c->algo.bit.getscl = nv04_i2c_getscl; 180 i2c->bit.getscl = nv04_i2c_getscl;
181 i2c->rd = entry->read; 181 i2c->rd = entry->read;
182 i2c->wr = entry->write; 182 i2c->wr = entry->write;
183 break; 183 break;
184 case 4: 184 case 4:
185 i2c->algo.bit.setsda = nv4e_i2c_setsda; 185 i2c->bit.setsda = nv4e_i2c_setsda;
186 i2c->algo.bit.setscl = nv4e_i2c_setscl; 186 i2c->bit.setscl = nv4e_i2c_setscl;
187 i2c->algo.bit.getsda = nv4e_i2c_getsda; 187 i2c->bit.getsda = nv4e_i2c_getsda;
188 i2c->algo.bit.getscl = nv4e_i2c_getscl; 188 i2c->bit.getscl = nv4e_i2c_getscl;
189 i2c->rd = 0x600800 + entry->read; 189 i2c->rd = 0x600800 + entry->read;
190 i2c->wr = 0x600800 + entry->write; 190 i2c->wr = 0x600800 + entry->write;
191 break; 191 break;
192 case 5: 192 case 5:
193 i2c->algo.bit.setsda = nv50_i2c_setsda; 193 i2c->bit.setsda = nv50_i2c_setsda;
194 i2c->algo.bit.setscl = nv50_i2c_setscl; 194 i2c->bit.setscl = nv50_i2c_setscl;
195 i2c->algo.bit.getsda = nv50_i2c_getsda; 195 i2c->bit.getsda = nv50_i2c_getsda;
196 i2c->algo.bit.getscl = nv50_i2c_getscl; 196 i2c->bit.getscl = nv50_i2c_getscl;
197 i2c->rd = nv50_i2c_port[entry->read]; 197 i2c->rd = nv50_i2c_port[entry->read];
198 i2c->wr = i2c->rd; 198 i2c->wr = i2c->rd;
199 break; 199 break;
@@ -216,17 +216,14 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
216 i2c_set_adapdata(&i2c->adapter, i2c); 216 i2c_set_adapdata(&i2c->adapter, i2c);
217 217
218 if (entry->port_type < 6) { 218 if (entry->port_type < 6) {
219 i2c->adapter.algo_data = &i2c->algo.bit; 219 i2c->adapter.algo_data = &i2c->bit;
220 i2c->algo.bit.udelay = 40; 220 i2c->bit.udelay = 40;
221 i2c->algo.bit.timeout = usecs_to_jiffies(5000); 221 i2c->bit.timeout = usecs_to_jiffies(5000);
222 i2c->algo.bit.data = i2c; 222 i2c->bit.data = i2c;
223 ret = i2c_bit_add_bus(&i2c->adapter); 223 ret = i2c_bit_add_bus(&i2c->adapter);
224 } else { 224 } else {
225 i2c->adapter.algo_data = &i2c->algo.dp; 225 i2c->adapter.algo = &nouveau_dp_i2c_algo;
226 i2c->algo.dp.running = false; 226 ret = i2c_add_adapter(&i2c->adapter);
227 i2c->algo.dp.address = 0;
228 i2c->algo.dp.aux_ch = nouveau_dp_i2c_aux_ch;
229 ret = i2c_dp_aux_add_bus(&i2c->adapter);
230 } 227 }
231 228
232 if (ret) { 229 if (ret) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h
index 6dd2f8713cd1..f71cb32f7571 100644
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.h
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h
@@ -33,10 +33,7 @@ struct dcb_i2c_entry;
33struct nouveau_i2c_chan { 33struct nouveau_i2c_chan {
34 struct i2c_adapter adapter; 34 struct i2c_adapter adapter;
35 struct drm_device *dev; 35 struct drm_device *dev;
36 union { 36 struct i2c_algo_bit_data bit;
37 struct i2c_algo_bit_data bit;
38 struct i2c_algo_dp_aux_data dp;
39 } algo;
40 unsigned rd; 37 unsigned rd;
41 unsigned wr; 38 unsigned wr;
42 unsigned data; 39 unsigned data;
@@ -49,7 +46,6 @@ bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr);
49int nouveau_i2c_identify(struct drm_device *dev, const char *what, 46int nouveau_i2c_identify(struct drm_device *dev, const char *what,
50 struct i2c_board_info *info, int index); 47 struct i2c_board_info *info, int index);
51 48
52int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte, 49extern const struct i2c_algorithm nouveau_dp_i2c_algo;
53 uint8_t *read_byte);
54 50
55#endif /* __NOUVEAU_I2C_H__ */ 51#endif /* __NOUVEAU_I2C_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
index 53360f156063..794b0ee30cf6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -49,7 +49,7 @@ nouveau_irq_preinstall(struct drm_device *dev)
49 /* Master disable */ 49 /* Master disable */
50 nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); 50 nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
51 51
52 if (dev_priv->card_type == NV_50) { 52 if (dev_priv->card_type >= NV_50) {
53 INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); 53 INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
54 INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); 54 INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh);
55 INIT_LIST_HEAD(&dev_priv->vbl_waiting); 55 INIT_LIST_HEAD(&dev_priv->vbl_waiting);
@@ -586,11 +586,11 @@ nouveau_pgraph_irq_handler(struct drm_device *dev)
586 } 586 }
587 587
588 if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) { 588 if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
589 nouveau_pgraph_intr_context_switch(dev);
590
591 status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; 589 status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
592 nv_wr32(dev, NV03_PGRAPH_INTR, 590 nv_wr32(dev, NV03_PGRAPH_INTR,
593 NV_PGRAPH_INTR_CONTEXT_SWITCH); 591 NV_PGRAPH_INTR_CONTEXT_SWITCH);
592
593 nouveau_pgraph_intr_context_switch(dev);
594 } 594 }
595 595
596 if (status) { 596 if (status) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index a9f36ab256b7..9689d4147686 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -320,7 +320,8 @@ nouveau_mem_detect(struct drm_device *dev)
320 if (dev_priv->card_type < NV_50) { 320 if (dev_priv->card_type < NV_50) {
321 dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); 321 dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA);
322 dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK; 322 dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
323 } else { 323 } else
324 if (dev_priv->card_type < NV_C0) {
324 dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); 325 dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA);
325 dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32; 326 dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32;
326 dev_priv->vram_size &= 0xffffffff00ll; 327 dev_priv->vram_size &= 0xffffffff00ll;
@@ -328,6 +329,9 @@ nouveau_mem_detect(struct drm_device *dev)
328 dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); 329 dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10);
329 dev_priv->vram_sys_base <<= 12; 330 dev_priv->vram_sys_base <<= 12;
330 } 331 }
332 } else {
333 dev_priv->vram_size = nv_rd32(dev, 0x10f20c) << 20;
334 dev_priv->vram_size *= nv_rd32(dev, 0x121c74);
331 } 335 }
332 336
333 NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); 337 NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
@@ -351,7 +355,7 @@ nouveau_mem_reset_agp(struct drm_device *dev)
351 /* First of all, disable fast writes, otherwise if it's 355 /* First of all, disable fast writes, otherwise if it's
352 * already enabled in the AGP bridge and we disable the card's 356 * already enabled in the AGP bridge and we disable the card's
353 * AGP controller we might be locking ourselves out of it. */ 357 * AGP controller we might be locking ourselves out of it. */
354 if (dev->agp->acquired) { 358 if (nv_rd32(dev, NV04_PBUS_PCI_NV_19) & PCI_AGP_COMMAND_FW) {
355 struct drm_agp_info info; 359 struct drm_agp_info info;
356 struct drm_agp_mode mode; 360 struct drm_agp_mode mode;
357 361
@@ -359,7 +363,7 @@ nouveau_mem_reset_agp(struct drm_device *dev)
359 if (ret) 363 if (ret)
360 return ret; 364 return ret;
361 365
362 mode.mode = info.mode & ~0x10; 366 mode.mode = info.mode & ~PCI_AGP_COMMAND_FW;
363 ret = drm_agp_enable(dev, mode); 367 ret = drm_agp_enable(dev, mode);
364 if (ret) 368 if (ret)
365 return ret; 369 return ret;
@@ -405,6 +409,8 @@ nouveau_mem_init_agp(struct drm_device *dev)
405 } 409 }
406 } 410 }
407 411
412 nouveau_mem_reset_agp(dev);
413
408 ret = drm_agp_info(dev, &info); 414 ret = drm_agp_info(dev, &info);
409 if (ret) { 415 if (ret) {
410 NV_ERROR(dev, "Unable to get AGP info: %d\n", ret); 416 NV_ERROR(dev, "Unable to get AGP info: %d\n", ret);
@@ -459,8 +465,6 @@ nouveau_mem_init(struct drm_device *dev)
459 return ret; 465 return ret;
460 } 466 }
461 467
462 INIT_LIST_HEAD(&dev_priv->ttm.bo_list);
463 spin_lock_init(&dev_priv->ttm.bo_list_lock);
464 spin_lock_init(&dev_priv->tile.lock); 468 spin_lock_init(&dev_priv->tile.lock);
465 469
466 dev_priv->fb_available_size = dev_priv->vram_size; 470 dev_priv->fb_available_size = dev_priv->vram_size;
@@ -494,7 +498,6 @@ nouveau_mem_init(struct drm_device *dev)
494 /* GART */ 498 /* GART */
495#if !defined(__powerpc__) && !defined(__ia64__) 499#if !defined(__powerpc__) && !defined(__ia64__)
496 if (drm_device_is_agp(dev) && dev->agp && !nouveau_noagp) { 500 if (drm_device_is_agp(dev) && dev->agp && !nouveau_noagp) {
497 nouveau_mem_reset_agp(dev);
498 ret = nouveau_mem_init_agp(dev); 501 ret = nouveau_mem_init_agp(dev);
499 if (ret) 502 if (ret)
500 NV_ERROR(dev, "Error initialising AGP: %d\n", ret); 503 NV_ERROR(dev, "Error initialising AGP: %d\n", ret);
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index 9c1056cb8a90..21a6e453b975 100644
--- a/drivers/gpu/drm/nouveau/nouveau_reg.h
+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
@@ -220,28 +220,21 @@
220# define NV_PGRAPH_INTR_ERROR (1<<20) 220# define NV_PGRAPH_INTR_ERROR (1<<20)
221#define NV10_PGRAPH_CTX_CONTROL 0x00400144 221#define NV10_PGRAPH_CTX_CONTROL 0x00400144
222#define NV10_PGRAPH_CTX_USER 0x00400148 222#define NV10_PGRAPH_CTX_USER 0x00400148
223#define NV10_PGRAPH_CTX_SWITCH1 0x0040014C 223#define NV10_PGRAPH_CTX_SWITCH(i) (0x0040014C + 0x4*(i))
224#define NV10_PGRAPH_CTX_SWITCH2 0x00400150
225#define NV10_PGRAPH_CTX_SWITCH3 0x00400154
226#define NV10_PGRAPH_CTX_SWITCH4 0x00400158
227#define NV10_PGRAPH_CTX_SWITCH5 0x0040015C
228#define NV04_PGRAPH_CTX_SWITCH1 0x00400160 224#define NV04_PGRAPH_CTX_SWITCH1 0x00400160
229#define NV10_PGRAPH_CTX_CACHE1 0x00400160 225#define NV10_PGRAPH_CTX_CACHE(i, j) (0x00400160 \
226 + 0x4*(i) + 0x20*(j))
230#define NV04_PGRAPH_CTX_SWITCH2 0x00400164 227#define NV04_PGRAPH_CTX_SWITCH2 0x00400164
231#define NV04_PGRAPH_CTX_SWITCH3 0x00400168 228#define NV04_PGRAPH_CTX_SWITCH3 0x00400168
232#define NV04_PGRAPH_CTX_SWITCH4 0x0040016C 229#define NV04_PGRAPH_CTX_SWITCH4 0x0040016C
233#define NV04_PGRAPH_CTX_CONTROL 0x00400170 230#define NV04_PGRAPH_CTX_CONTROL 0x00400170
234#define NV04_PGRAPH_CTX_USER 0x00400174 231#define NV04_PGRAPH_CTX_USER 0x00400174
235#define NV04_PGRAPH_CTX_CACHE1 0x00400180 232#define NV04_PGRAPH_CTX_CACHE1 0x00400180
236#define NV10_PGRAPH_CTX_CACHE2 0x00400180
237#define NV03_PGRAPH_CTX_CONTROL 0x00400190 233#define NV03_PGRAPH_CTX_CONTROL 0x00400190
238#define NV03_PGRAPH_CTX_USER 0x00400194 234#define NV03_PGRAPH_CTX_USER 0x00400194
239#define NV04_PGRAPH_CTX_CACHE2 0x004001A0 235#define NV04_PGRAPH_CTX_CACHE2 0x004001A0
240#define NV10_PGRAPH_CTX_CACHE3 0x004001A0
241#define NV04_PGRAPH_CTX_CACHE3 0x004001C0 236#define NV04_PGRAPH_CTX_CACHE3 0x004001C0
242#define NV10_PGRAPH_CTX_CACHE4 0x004001C0
243#define NV04_PGRAPH_CTX_CACHE4 0x004001E0 237#define NV04_PGRAPH_CTX_CACHE4 0x004001E0
244#define NV10_PGRAPH_CTX_CACHE5 0x004001E0
245#define NV40_PGRAPH_CTXCTL_0304 0x00400304 238#define NV40_PGRAPH_CTXCTL_0304 0x00400304
246#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001 239#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001
247#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308 240#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308
@@ -356,9 +349,12 @@
356#define NV04_PGRAPH_FFINTFC_ST2 0x00400754 349#define NV04_PGRAPH_FFINTFC_ST2 0x00400754
357#define NV10_PGRAPH_RDI_DATA 0x00400754 350#define NV10_PGRAPH_RDI_DATA 0x00400754
358#define NV04_PGRAPH_DMA_PITCH 0x00400760 351#define NV04_PGRAPH_DMA_PITCH 0x00400760
359#define NV10_PGRAPH_FFINTFC_ST2 0x00400764 352#define NV10_PGRAPH_FFINTFC_FIFO_PTR 0x00400760
360#define NV04_PGRAPH_DVD_COLORFMT 0x00400764 353#define NV04_PGRAPH_DVD_COLORFMT 0x00400764
354#define NV10_PGRAPH_FFINTFC_ST2 0x00400764
361#define NV04_PGRAPH_SCALED_FORMAT 0x00400768 355#define NV04_PGRAPH_SCALED_FORMAT 0x00400768
356#define NV10_PGRAPH_FFINTFC_ST2_DL 0x00400768
357#define NV10_PGRAPH_FFINTFC_ST2_DH 0x0040076c
362#define NV10_PGRAPH_DMA_PITCH 0x00400770 358#define NV10_PGRAPH_DMA_PITCH 0x00400770
363#define NV10_PGRAPH_DVD_COLORFMT 0x00400774 359#define NV10_PGRAPH_DVD_COLORFMT 0x00400774
364#define NV10_PGRAPH_SCALED_FORMAT 0x00400778 360#define NV10_PGRAPH_SCALED_FORMAT 0x00400778
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index ee3729e7823b..989322be3728 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -359,6 +359,54 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
359 engine->gpio.set = nv50_gpio_set; 359 engine->gpio.set = nv50_gpio_set;
360 engine->gpio.irq_enable = nv50_gpio_irq_enable; 360 engine->gpio.irq_enable = nv50_gpio_irq_enable;
361 break; 361 break;
362 case 0xC0:
363 engine->instmem.init = nvc0_instmem_init;
364 engine->instmem.takedown = nvc0_instmem_takedown;
365 engine->instmem.suspend = nvc0_instmem_suspend;
366 engine->instmem.resume = nvc0_instmem_resume;
367 engine->instmem.populate = nvc0_instmem_populate;
368 engine->instmem.clear = nvc0_instmem_clear;
369 engine->instmem.bind = nvc0_instmem_bind;
370 engine->instmem.unbind = nvc0_instmem_unbind;
371 engine->instmem.flush = nvc0_instmem_flush;
372 engine->mc.init = nv50_mc_init;
373 engine->mc.takedown = nv50_mc_takedown;
374 engine->timer.init = nv04_timer_init;
375 engine->timer.read = nv04_timer_read;
376 engine->timer.takedown = nv04_timer_takedown;
377 engine->fb.init = nvc0_fb_init;
378 engine->fb.takedown = nvc0_fb_takedown;
379 engine->graph.grclass = NULL; //nvc0_graph_grclass;
380 engine->graph.init = nvc0_graph_init;
381 engine->graph.takedown = nvc0_graph_takedown;
382 engine->graph.fifo_access = nvc0_graph_fifo_access;
383 engine->graph.channel = nvc0_graph_channel;
384 engine->graph.create_context = nvc0_graph_create_context;
385 engine->graph.destroy_context = nvc0_graph_destroy_context;
386 engine->graph.load_context = nvc0_graph_load_context;
387 engine->graph.unload_context = nvc0_graph_unload_context;
388 engine->fifo.channels = 128;
389 engine->fifo.init = nvc0_fifo_init;
390 engine->fifo.takedown = nvc0_fifo_takedown;
391 engine->fifo.disable = nvc0_fifo_disable;
392 engine->fifo.enable = nvc0_fifo_enable;
393 engine->fifo.reassign = nvc0_fifo_reassign;
394 engine->fifo.channel_id = nvc0_fifo_channel_id;
395 engine->fifo.create_context = nvc0_fifo_create_context;
396 engine->fifo.destroy_context = nvc0_fifo_destroy_context;
397 engine->fifo.load_context = nvc0_fifo_load_context;
398 engine->fifo.unload_context = nvc0_fifo_unload_context;
399 engine->display.early_init = nv50_display_early_init;
400 engine->display.late_takedown = nv50_display_late_takedown;
401 engine->display.create = nv50_display_create;
402 engine->display.init = nv50_display_init;
403 engine->display.destroy = nv50_display_destroy;
404 engine->gpio.init = nv50_gpio_init;
405 engine->gpio.takedown = nouveau_stub_takedown;
406 engine->gpio.get = nv50_gpio_get;
407 engine->gpio.set = nv50_gpio_set;
408 engine->gpio.irq_enable = nv50_gpio_irq_enable;
409 break;
362 default: 410 default:
363 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); 411 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
364 return 1; 412 return 1;
@@ -739,8 +787,10 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
739 int ret; 787 int ret;
740 788
741 dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); 789 dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
742 if (!dev_priv) 790 if (!dev_priv) {
743 return -ENOMEM; 791 ret = -ENOMEM;
792 goto err_out;
793 }
744 dev->dev_private = dev_priv; 794 dev->dev_private = dev_priv;
745 dev_priv->dev = dev; 795 dev_priv->dev = dev;
746 796
@@ -750,8 +800,10 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
750 dev->pci_vendor, dev->pci_device, dev->pdev->class); 800 dev->pci_vendor, dev->pci_device, dev->pdev->class);
751 801
752 dev_priv->wq = create_workqueue("nouveau"); 802 dev_priv->wq = create_workqueue("nouveau");
753 if (!dev_priv->wq) 803 if (!dev_priv->wq) {
754 return -EINVAL; 804 ret = -EINVAL;
805 goto err_priv;
806 }
755 807
756 /* resource 0 is mmio regs */ 808 /* resource 0 is mmio regs */
757 /* resource 1 is linear FB */ 809 /* resource 1 is linear FB */
@@ -764,7 +816,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
764 if (!dev_priv->mmio) { 816 if (!dev_priv->mmio) {
765 NV_ERROR(dev, "Unable to initialize the mmio mapping. " 817 NV_ERROR(dev, "Unable to initialize the mmio mapping. "
766 "Please report your setup to " DRIVER_EMAIL "\n"); 818 "Please report your setup to " DRIVER_EMAIL "\n");
767 return -EINVAL; 819 ret = -EINVAL;
820 goto err_wq;
768 } 821 }
769 NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", 822 NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
770 (unsigned long long)mmio_start_offs); 823 (unsigned long long)mmio_start_offs);
@@ -810,9 +863,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
810 case 0xa0: 863 case 0xa0:
811 dev_priv->card_type = NV_50; 864 dev_priv->card_type = NV_50;
812 break; 865 break;
866 case 0xc0:
867 dev_priv->card_type = NV_C0;
868 break;
813 default: 869 default:
814 NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0); 870 NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0);
815 return -EINVAL; 871 ret = -EINVAL;
872 goto err_mmio;
816 } 873 }
817 874
818 NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", 875 NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
@@ -820,7 +877,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
820 877
821 ret = nouveau_remove_conflicting_drivers(dev); 878 ret = nouveau_remove_conflicting_drivers(dev);
822 if (ret) 879 if (ret)
823 return ret; 880 goto err_mmio;
824 881
825 /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */ 882 /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */
826 if (dev_priv->card_type >= NV_40) { 883 if (dev_priv->card_type >= NV_40) {
@@ -834,7 +891,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
834 dev_priv->ramin_size); 891 dev_priv->ramin_size);
835 if (!dev_priv->ramin) { 892 if (!dev_priv->ramin) {
836 NV_ERROR(dev, "Failed to PRAMIN BAR"); 893 NV_ERROR(dev, "Failed to PRAMIN BAR");
837 return -ENOMEM; 894 ret = -ENOMEM;
895 goto err_mmio;
838 } 896 }
839 } else { 897 } else {
840 dev_priv->ramin_size = 1 * 1024 * 1024; 898 dev_priv->ramin_size = 1 * 1024 * 1024;
@@ -842,7 +900,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
842 dev_priv->ramin_size); 900 dev_priv->ramin_size);
843 if (!dev_priv->ramin) { 901 if (!dev_priv->ramin) {
844 NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n"); 902 NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n");
845 return -ENOMEM; 903 ret = -ENOMEM;
904 goto err_mmio;
846 } 905 }
847 } 906 }
848 907
@@ -857,9 +916,21 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
857 /* For kernel modesetting, init card now and bring up fbcon */ 916 /* For kernel modesetting, init card now and bring up fbcon */
858 ret = nouveau_card_init(dev); 917 ret = nouveau_card_init(dev);
859 if (ret) 918 if (ret)
860 return ret; 919 goto err_ramin;
861 920
862 return 0; 921 return 0;
922
923err_ramin:
924 iounmap(dev_priv->ramin);
925err_mmio:
926 iounmap(dev_priv->mmio);
927err_wq:
928 destroy_workqueue(dev_priv->wq);
929err_priv:
930 kfree(dev_priv);
931 dev->dev_private = NULL;
932err_out:
933 return ret;
863} 934}
864 935
865void nouveau_lastclose(struct drm_device *dev) 936void nouveau_lastclose(struct drm_device *dev)
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index 1c20c08ce67c..497df8765f28 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -542,6 +542,9 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
542 * 1 << 30 on 0x60.830), for no apparent reason */ 542 * 1 << 30 on 0x60.830), for no apparent reason */
543 regp->CRTC[NV_CIO_CRE_59] = off_chip_digital; 543 regp->CRTC[NV_CIO_CRE_59] = off_chip_digital;
544 544
545 if (dev_priv->card_type >= NV_30)
546 regp->CRTC[0x9f] = off_chip_digital ? 0x11 : 0x1;
547
545 regp->crtc_830 = mode->crtc_vdisplay - 3; 548 regp->crtc_830 = mode->crtc_vdisplay - 3;
546 regp->crtc_834 = mode->crtc_vdisplay - 1; 549 regp->crtc_834 = mode->crtc_vdisplay - 1;
547 550
@@ -739,15 +742,13 @@ nv_crtc_gamma_load(struct drm_crtc *crtc)
739} 742}
740 743
741static void 744static void
742nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t size) 745nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start,
746 uint32_t size)
743{ 747{
748 int end = (start + size > 256) ? 256 : start + size, i;
744 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 749 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
745 int i;
746 750
747 if (size != 256) 751 for (i = start; i < end; i++) {
748 return;
749
750 for (i = 0; i < 256; i++) {
751 nv_crtc->lut.r[i] = r[i]; 752 nv_crtc->lut.r[i] = r[i];
752 nv_crtc->lut.g[i] = g[i]; 753 nv_crtc->lut.g[i] = g[i];
753 nv_crtc->lut.b[i] = b[i]; 754 nv_crtc->lut.b[i] = b[i];
@@ -914,7 +915,7 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
914 915
915 gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); 916 gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
916 if (!gem) 917 if (!gem)
917 return -EINVAL; 918 return -ENOENT;
918 cursor = nouveau_gem_object(gem); 919 cursor = nouveau_gem_object(gem);
919 920
920 ret = nouveau_bo_map(cursor); 921 ret = nouveau_bo_map(cursor);
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c
index 3311f3a8c818..a5dcf7685800 100644
--- a/drivers/gpu/drm/nouveau/nv04_dfp.c
+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
@@ -34,6 +34,8 @@
34#include "nouveau_hw.h" 34#include "nouveau_hw.h"
35#include "nvreg.h" 35#include "nvreg.h"
36 36
37#include "i2c/sil164.h"
38
37#define FP_TG_CONTROL_ON (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | \ 39#define FP_TG_CONTROL_ON (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | \
38 NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | \ 40 NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | \
39 NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS) 41 NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS)
@@ -144,6 +146,36 @@ void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode)
144 } 146 }
145} 147}
146 148
149static struct drm_encoder *get_tmds_slave(struct drm_encoder *encoder)
150{
151 struct drm_device *dev = encoder->dev;
152 struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
153 struct drm_encoder *slave;
154
155 if (dcb->type != OUTPUT_TMDS || dcb->location == DCB_LOC_ON_CHIP)
156 return NULL;
157
158 /* Some BIOSes (e.g. the one in a Quadro FX1000) report several
159 * TMDS transmitters at the same I2C address, in the same I2C
160 * bus. This can still work because in that case one of them is
161 * always hard-wired to a reasonable configuration using straps,
162 * and the other one needs to be programmed.
163 *
164 * I don't think there's a way to know which is which, even the
165 * blob programs the one exposed via I2C for *both* heads, so
166 * let's do the same.
167 */
168 list_for_each_entry(slave, &dev->mode_config.encoder_list, head) {
169 struct dcb_entry *slave_dcb = nouveau_encoder(slave)->dcb;
170
171 if (slave_dcb->type == OUTPUT_TMDS && get_slave_funcs(slave) &&
172 slave_dcb->tmdsconf.slave_addr == dcb->tmdsconf.slave_addr)
173 return slave;
174 }
175
176 return NULL;
177}
178
147static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder, 179static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder,
148 struct drm_display_mode *mode, 180 struct drm_display_mode *mode,
149 struct drm_display_mode *adjusted_mode) 181 struct drm_display_mode *adjusted_mode)
@@ -429,6 +461,11 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
429 else 461 else
430 NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); 462 NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000);
431 463
464 /* Init external transmitters */
465 if (get_tmds_slave(encoder))
466 get_slave_funcs(get_tmds_slave(encoder))->mode_set(
467 encoder, &nv_encoder->mode, &nv_encoder->mode);
468
432 helper->dpms(encoder, DRM_MODE_DPMS_ON); 469 helper->dpms(encoder, DRM_MODE_DPMS_ON);
433 470
434 NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", 471 NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
@@ -550,10 +587,42 @@ static void nv04_dfp_destroy(struct drm_encoder *encoder)
550 587
551 NV_DEBUG_KMS(encoder->dev, "\n"); 588 NV_DEBUG_KMS(encoder->dev, "\n");
552 589
590 if (get_slave_funcs(encoder))
591 get_slave_funcs(encoder)->destroy(encoder);
592
553 drm_encoder_cleanup(encoder); 593 drm_encoder_cleanup(encoder);
554 kfree(nv_encoder); 594 kfree(nv_encoder);
555} 595}
556 596
597static void nv04_tmds_slave_init(struct drm_encoder *encoder)
598{
599 struct drm_device *dev = encoder->dev;
600 struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
601 struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, 2);
602 struct i2c_board_info info[] = {
603 {
604 .type = "sil164",
605 .addr = (dcb->tmdsconf.slave_addr == 0x7 ? 0x3a : 0x38),
606 .platform_data = &(struct sil164_encoder_params) {
607 SIL164_INPUT_EDGE_RISING
608 }
609 },
610 { }
611 };
612 int type;
613
614 if (!nv_gf4_disp_arch(dev) || !i2c ||
615 get_tmds_slave(encoder))
616 return;
617
618 type = nouveau_i2c_identify(dev, "TMDS transmitter", info, 2);
619 if (type < 0)
620 return;
621
622 drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
623 &i2c->adapter, &info[type]);
624}
625
557static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = { 626static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = {
558 .dpms = nv04_lvds_dpms, 627 .dpms = nv04_lvds_dpms,
559 .save = nv04_dfp_save, 628 .save = nv04_dfp_save,
@@ -616,6 +685,10 @@ nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry)
616 encoder->possible_crtcs = entry->heads; 685 encoder->possible_crtcs = entry->heads;
617 encoder->possible_clones = 0; 686 encoder->possible_clones = 0;
618 687
688 if (entry->type == OUTPUT_TMDS &&
689 entry->location != DCB_LOC_ON_CHIP)
690 nv04_tmds_slave_init(encoder);
691
619 drm_mode_connector_attach_encoder(connector, encoder); 692 drm_mode_connector_attach_encoder(connector, encoder);
620 return 0; 693 return 0;
621} 694}
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c
index 94e299cef0b2..0b5d012d7c28 100644
--- a/drivers/gpu/drm/nouveau/nv04_tv.c
+++ b/drivers/gpu/drm/nouveau/nv04_tv.c
@@ -89,7 +89,7 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode)
89 89
90 NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel); 90 NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel);
91 91
92 to_encoder_slave(encoder)->slave_funcs->dpms(encoder, mode); 92 get_slave_funcs(encoder)->dpms(encoder, mode);
93} 93}
94 94
95static void nv04_tv_bind(struct drm_device *dev, int head, bool bind) 95static void nv04_tv_bind(struct drm_device *dev, int head, bool bind)
@@ -152,7 +152,7 @@ static void nv04_tv_mode_set(struct drm_encoder *encoder,
152 regp->tv_vskew = 1; 152 regp->tv_vskew = 1;
153 regp->tv_vsync_delay = 1; 153 regp->tv_vsync_delay = 1;
154 154
155 to_encoder_slave(encoder)->slave_funcs->mode_set(encoder, mode, adjusted_mode); 155 get_slave_funcs(encoder)->mode_set(encoder, mode, adjusted_mode);
156} 156}
157 157
158static void nv04_tv_commit(struct drm_encoder *encoder) 158static void nv04_tv_commit(struct drm_encoder *encoder)
@@ -171,8 +171,7 @@ static void nv04_tv_commit(struct drm_encoder *encoder)
171 171
172static void nv04_tv_destroy(struct drm_encoder *encoder) 172static void nv04_tv_destroy(struct drm_encoder *encoder)
173{ 173{
174 to_encoder_slave(encoder)->slave_funcs->destroy(encoder); 174 get_slave_funcs(encoder)->destroy(encoder);
175
176 drm_encoder_cleanup(encoder); 175 drm_encoder_cleanup(encoder);
177 176
178 kfree(encoder->helper_private); 177 kfree(encoder->helper_private);
@@ -229,7 +228,7 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
229 goto fail_cleanup; 228 goto fail_cleanup;
230 229
231 /* Fill the function pointers */ 230 /* Fill the function pointers */
232 sfuncs = to_encoder_slave(encoder)->slave_funcs; 231 sfuncs = get_slave_funcs(encoder);
233 232
234 *hfuncs = (struct drm_encoder_helper_funcs) { 233 *hfuncs = (struct drm_encoder_helper_funcs) {
235 .dpms = nv04_tv_dpms, 234 .dpms = nv04_tv_dpms,
@@ -243,7 +242,6 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
243 }; 242 };
244 243
245 /* Attach it to the specified connector. */ 244 /* Attach it to the specified connector. */
246 sfuncs->set_config(encoder, nv04_tv_encoder_info[type].platform_data);
247 sfuncs->create_resources(encoder, connector); 245 sfuncs->create_resources(encoder, connector);
248 drm_mode_connector_attach_encoder(connector, encoder); 246 drm_mode_connector_attach_encoder(connector, encoder);
249 247
diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c
index fcf2cdd19493..b2f6a57c0cc5 100644
--- a/drivers/gpu/drm/nouveau/nv10_graph.c
+++ b/drivers/gpu/drm/nouveau/nv10_graph.c
@@ -43,51 +43,51 @@ struct pipe_state {
43}; 43};
44 44
45static int nv10_graph_ctx_regs[] = { 45static int nv10_graph_ctx_regs[] = {
46 NV10_PGRAPH_CTX_SWITCH1, 46 NV10_PGRAPH_CTX_SWITCH(0),
47 NV10_PGRAPH_CTX_SWITCH2, 47 NV10_PGRAPH_CTX_SWITCH(1),
48 NV10_PGRAPH_CTX_SWITCH3, 48 NV10_PGRAPH_CTX_SWITCH(2),
49 NV10_PGRAPH_CTX_SWITCH4, 49 NV10_PGRAPH_CTX_SWITCH(3),
50 NV10_PGRAPH_CTX_SWITCH5, 50 NV10_PGRAPH_CTX_SWITCH(4),
51 NV10_PGRAPH_CTX_CACHE1, /* 8 values from 0x400160 to 0x40017c */ 51 NV10_PGRAPH_CTX_CACHE(0, 0),
52 NV10_PGRAPH_CTX_CACHE2, /* 8 values from 0x400180 to 0x40019c */ 52 NV10_PGRAPH_CTX_CACHE(0, 1),
53 NV10_PGRAPH_CTX_CACHE3, /* 8 values from 0x4001a0 to 0x4001bc */ 53 NV10_PGRAPH_CTX_CACHE(0, 2),
54 NV10_PGRAPH_CTX_CACHE4, /* 8 values from 0x4001c0 to 0x4001dc */ 54 NV10_PGRAPH_CTX_CACHE(0, 3),
55 NV10_PGRAPH_CTX_CACHE5, /* 8 values from 0x4001e0 to 0x4001fc */ 55 NV10_PGRAPH_CTX_CACHE(0, 4),
56 0x00400164, 56 NV10_PGRAPH_CTX_CACHE(1, 0),
57 0x00400184, 57 NV10_PGRAPH_CTX_CACHE(1, 1),
58 0x004001a4, 58 NV10_PGRAPH_CTX_CACHE(1, 2),
59 0x004001c4, 59 NV10_PGRAPH_CTX_CACHE(1, 3),
60 0x004001e4, 60 NV10_PGRAPH_CTX_CACHE(1, 4),
61 0x00400168, 61 NV10_PGRAPH_CTX_CACHE(2, 0),
62 0x00400188, 62 NV10_PGRAPH_CTX_CACHE(2, 1),
63 0x004001a8, 63 NV10_PGRAPH_CTX_CACHE(2, 2),
64 0x004001c8, 64 NV10_PGRAPH_CTX_CACHE(2, 3),
65 0x004001e8, 65 NV10_PGRAPH_CTX_CACHE(2, 4),
66 0x0040016c, 66 NV10_PGRAPH_CTX_CACHE(3, 0),
67 0x0040018c, 67 NV10_PGRAPH_CTX_CACHE(3, 1),
68 0x004001ac, 68 NV10_PGRAPH_CTX_CACHE(3, 2),
69 0x004001cc, 69 NV10_PGRAPH_CTX_CACHE(3, 3),
70 0x004001ec, 70 NV10_PGRAPH_CTX_CACHE(3, 4),
71 0x00400170, 71 NV10_PGRAPH_CTX_CACHE(4, 0),
72 0x00400190, 72 NV10_PGRAPH_CTX_CACHE(4, 1),
73 0x004001b0, 73 NV10_PGRAPH_CTX_CACHE(4, 2),
74 0x004001d0, 74 NV10_PGRAPH_CTX_CACHE(4, 3),
75 0x004001f0, 75 NV10_PGRAPH_CTX_CACHE(4, 4),
76 0x00400174, 76 NV10_PGRAPH_CTX_CACHE(5, 0),
77 0x00400194, 77 NV10_PGRAPH_CTX_CACHE(5, 1),
78 0x004001b4, 78 NV10_PGRAPH_CTX_CACHE(5, 2),
79 0x004001d4, 79 NV10_PGRAPH_CTX_CACHE(5, 3),
80 0x004001f4, 80 NV10_PGRAPH_CTX_CACHE(5, 4),
81 0x00400178, 81 NV10_PGRAPH_CTX_CACHE(6, 0),
82 0x00400198, 82 NV10_PGRAPH_CTX_CACHE(6, 1),
83 0x004001b8, 83 NV10_PGRAPH_CTX_CACHE(6, 2),
84 0x004001d8, 84 NV10_PGRAPH_CTX_CACHE(6, 3),
85 0x004001f8, 85 NV10_PGRAPH_CTX_CACHE(6, 4),
86 0x0040017c, 86 NV10_PGRAPH_CTX_CACHE(7, 0),
87 0x0040019c, 87 NV10_PGRAPH_CTX_CACHE(7, 1),
88 0x004001bc, 88 NV10_PGRAPH_CTX_CACHE(7, 2),
89 0x004001dc, 89 NV10_PGRAPH_CTX_CACHE(7, 3),
90 0x004001fc, 90 NV10_PGRAPH_CTX_CACHE(7, 4),
91 NV10_PGRAPH_CTX_USER, 91 NV10_PGRAPH_CTX_USER,
92 NV04_PGRAPH_DMA_START_0, 92 NV04_PGRAPH_DMA_START_0,
93 NV04_PGRAPH_DMA_START_1, 93 NV04_PGRAPH_DMA_START_1,
@@ -653,6 +653,78 @@ static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
653 return -1; 653 return -1;
654} 654}
655 655
656static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan,
657 uint32_t inst)
658{
659 struct drm_device *dev = chan->dev;
660 struct drm_nouveau_private *dev_priv = dev->dev_private;
661 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
662 uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
663 uint32_t ctx_user, ctx_switch[5];
664 int i, subchan = -1;
665
666 /* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state
667 * that cannot be restored via MMIO. Do it through the FIFO
668 * instead.
669 */
670
671 /* Look for a celsius object */
672 for (i = 0; i < 8; i++) {
673 int class = nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff;
674
675 if (class == 0x56 || class == 0x96 || class == 0x99) {
676 subchan = i;
677 break;
678 }
679 }
680
681 if (subchan < 0 || !inst)
682 return;
683
684 /* Save the current ctx object */
685 ctx_user = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
686 for (i = 0; i < 5; i++)
687 ctx_switch[i] = nv_rd32(dev, NV10_PGRAPH_CTX_SWITCH(i));
688
689 /* Save the FIFO state */
690 st2 = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
691 st2_dl = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DL);
692 st2_dh = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DH);
693 fifo_ptr = nv_rd32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR);
694
695 for (i = 0; i < ARRAY_SIZE(fifo); i++)
696 fifo[i] = nv_rd32(dev, 0x4007a0 + 4 * i);
697
698 /* Switch to the celsius subchannel */
699 for (i = 0; i < 5; i++)
700 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i),
701 nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(subchan, i)));
702 nv_mask(dev, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13);
703
704 /* Inject NV10TCL_DMA_VTXBUF */
705 nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0);
706 nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2,
707 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c);
708 nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
709 nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
710 pgraph->fifo_access(dev, true);
711 pgraph->fifo_access(dev, false);
712
713 /* Restore the FIFO state */
714 for (i = 0; i < ARRAY_SIZE(fifo); i++)
715 nv_wr32(dev, 0x4007a0 + 4 * i, fifo[i]);
716
717 nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr);
718 nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, st2);
719 nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl);
720 nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh);
721
722 /* Restore the current ctx object */
723 for (i = 0; i < 5; i++)
724 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]);
725 nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user);
726}
727
656int nv10_graph_load_context(struct nouveau_channel *chan) 728int nv10_graph_load_context(struct nouveau_channel *chan)
657{ 729{
658 struct drm_device *dev = chan->dev; 730 struct drm_device *dev = chan->dev;
@@ -670,6 +742,8 @@ int nv10_graph_load_context(struct nouveau_channel *chan)
670 } 742 }
671 743
672 nv10_graph_load_pipe(chan); 744 nv10_graph_load_pipe(chan);
745 nv10_graph_load_dma_vtxbuf(chan, (nv_rd32(dev, NV10_PGRAPH_GLOBALSTATE1)
746 & 0xffff));
673 747
674 nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100); 748 nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
675 tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER); 749 tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
@@ -856,11 +930,12 @@ int nv10_graph_init(struct drm_device *dev)
856 for (i = 0; i < NV10_PFB_TILE__SIZE; i++) 930 for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
857 nv10_graph_set_region_tiling(dev, i, 0, 0, 0); 931 nv10_graph_set_region_tiling(dev, i, 0, 0, 0);
858 932
859 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000); 933 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
860 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000); 934 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
861 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH3, 0x00000000); 935 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
862 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH4, 0x00000000); 936 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
863 nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); 937 nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000);
938 nv_wr32(dev, NV10_PGRAPH_STATE, 0xFFFFFFFF);
864 939
865 tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff; 940 tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
866 tmp |= (dev_priv->engine.fifo.channels - 1) << 24; 941 tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
diff --git a/drivers/gpu/drm/nouveau/nv30_fb.c b/drivers/gpu/drm/nouveau/nv30_fb.c
index 9d35c8b3b839..4a3f2f095128 100644
--- a/drivers/gpu/drm/nouveau/nv30_fb.c
+++ b/drivers/gpu/drm/nouveau/nv30_fb.c
@@ -30,15 +30,25 @@
30#include "nouveau_drm.h" 30#include "nouveau_drm.h"
31 31
32static int 32static int
33calc_ref(int b, int l, int i) 33calc_bias(struct drm_device *dev, int k, int i, int j)
34{
35 struct drm_nouveau_private *dev_priv = dev->dev_private;
36 int b = (dev_priv->chipset > 0x30 ?
37 nv_rd32(dev, 0x122c + 0x10 * k + 0x4 * j) >> (4 * (i ^ 1)) :
38 0) & 0xf;
39
40 return 2 * (b & 0x8 ? b - 0x10 : b);
41}
42
43static int
44calc_ref(struct drm_device *dev, int l, int k, int i)
34{ 45{
35 int j, x = 0; 46 int j, x = 0;
36 47
37 for (j = 0; j < 4; j++) { 48 for (j = 0; j < 4; j++) {
38 int n = (b >> (8 * j) & 0xf); 49 int m = (l >> (8 * i) & 0xff) + calc_bias(dev, k, i, j);
39 int m = (l >> (8 * i) & 0xff) + 2 * (n & 0x8 ? n - 0x10 : n);
40 50
41 x |= (0x80 | (m & 0x1f)) << (8 * j); 51 x |= (0x80 | clamp(m, 0, 0x1f)) << (8 * j);
42 } 52 }
43 53
44 return x; 54 return x;
@@ -63,18 +73,16 @@ nv30_fb_init(struct drm_device *dev)
63 dev_priv->chipset == 0x35) { 73 dev_priv->chipset == 0x35) {
64 /* Related to ROP count */ 74 /* Related to ROP count */
65 int n = (dev_priv->chipset == 0x31 ? 2 : 4); 75 int n = (dev_priv->chipset == 0x31 ? 2 : 4);
66 int b = (dev_priv->chipset > 0x30 ?
67 nv_rd32(dev, 0x122c) & 0xf : 0);
68 int l = nv_rd32(dev, 0x1003d0); 76 int l = nv_rd32(dev, 0x1003d0);
69 77
70 for (i = 0; i < n; i++) { 78 for (i = 0; i < n; i++) {
71 for (j = 0; j < 3; j++) 79 for (j = 0; j < 3; j++)
72 nv_wr32(dev, 0x10037c + 0xc * i + 0x4 * j, 80 nv_wr32(dev, 0x10037c + 0xc * i + 0x4 * j,
73 calc_ref(b, l, j)); 81 calc_ref(dev, l, 0, j));
74 82
75 for (j = 0; j < 2; j++) 83 for (j = 0; j < 2; j++)
76 nv_wr32(dev, 0x1003ac + 0x8 * i + 0x4 * j, 84 nv_wr32(dev, 0x1003ac + 0x8 * i + 0x4 * j,
77 calc_ref(b, l, j)); 85 calc_ref(dev, l, 1, j));
78 } 86 }
79 } 87 }
80 88
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index 5d11ea101666..bfd4ca2fe7ef 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -264,11 +264,16 @@ 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 reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head); 267 struct drm_nouveau_private *dev_priv = dev->dev_private;
268 struct pll_lims pll; 268 struct pll_lims pll;
269 uint32_t reg1, reg2; 269 uint32_t reg, reg1, reg2;
270 int ret, N1, M1, N2, M2, P; 270 int ret, N1, M1, N2, M2, P;
271 271
272 if (dev_priv->chipset < NV_C0)
273 reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head);
274 else
275 reg = 0x614140 + (head * 0x800);
276
272 ret = get_pll_limits(dev, reg, &pll); 277 ret = get_pll_limits(dev, reg, &pll);
273 if (ret) 278 if (ret)
274 return ret; 279 return ret;
@@ -286,7 +291,8 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
286 nv_wr32(dev, reg, 0x10000611); 291 nv_wr32(dev, reg, 0x10000611);
287 nv_wr32(dev, reg + 4, reg1 | (M1 << 16) | N1); 292 nv_wr32(dev, reg + 4, reg1 | (M1 << 16) | N1);
288 nv_wr32(dev, reg + 8, reg2 | (P << 28) | (M2 << 16) | N2); 293 nv_wr32(dev, reg + 8, reg2 | (P << 28) | (M2 << 16) | N2);
289 } else { 294 } else
295 if (dev_priv->chipset < NV_C0) {
290 ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P); 296 ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P);
291 if (ret <= 0) 297 if (ret <= 0)
292 return 0; 298 return 0;
@@ -298,6 +304,17 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
298 nv_wr32(dev, reg, 0x50000610); 304 nv_wr32(dev, reg, 0x50000610);
299 nv_wr32(dev, reg + 4, reg1 | (P << 16) | (M1 << 8) | N1); 305 nv_wr32(dev, reg + 4, reg1 | (P << 16) | (M1 << 8) | N1);
300 nv_wr32(dev, reg + 8, N2); 306 nv_wr32(dev, reg + 8, N2);
307 } else {
308 ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P);
309 if (ret <= 0)
310 return 0;
311
312 NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n",
313 pclk, ret, N1, N2, M1, P);
314
315 nv_mask(dev, reg + 0x0c, 0x00000000, 0x00000100);
316 nv_wr32(dev, reg + 0x04, (P << 16) | (N1 << 8) | M1);
317 nv_wr32(dev, reg + 0x10, N2 << 16);
301 } 318 }
302 319
303 return 0; 320 return 0;
@@ -348,7 +365,7 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
348 365
349 gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); 366 gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
350 if (!gem) 367 if (!gem)
351 return -EINVAL; 368 return -ENOENT;
352 cursor = nouveau_gem_object(gem); 369 cursor = nouveau_gem_object(gem);
353 370
354 ret = nouveau_bo_map(cursor); 371 ret = nouveau_bo_map(cursor);
@@ -381,15 +398,12 @@ nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
381 398
382static void 399static void
383nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, 400nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
384 uint32_t size) 401 uint32_t start, uint32_t size)
385{ 402{
403 int end = (start + size > 256) ? 256 : start + size, i;
386 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 404 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
387 int i;
388
389 if (size != 256)
390 return;
391 405
392 for (i = 0; i < 256; i++) { 406 for (i = start; i < end; i++) {
393 nv_crtc->lut.r[i] = r[i]; 407 nv_crtc->lut.r[i] = r[i];
394 nv_crtc->lut.g[i] = g[i]; 408 nv_crtc->lut.g[i] = g[i];
395 nv_crtc->lut.b[i] = b[i]; 409 nv_crtc->lut.b[i] = b[i];
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index f13ad0de9c8f..612fa6d6a0cb 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -76,7 +76,10 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name,
76 nv_wo32(dev, obj, 2, offset); 76 nv_wo32(dev, obj, 2, offset);
77 nv_wo32(dev, obj, 3, 0x00000000); 77 nv_wo32(dev, obj, 3, 0x00000000);
78 nv_wo32(dev, obj, 4, 0x00000000); 78 nv_wo32(dev, obj, 4, 0x00000000);
79 nv_wo32(dev, obj, 5, 0x00010000); 79 if (dev_priv->card_type < NV_C0)
80 nv_wo32(dev, obj, 5, 0x00010000);
81 else
82 nv_wo32(dev, obj, 5, 0x00020000);
80 dev_priv->engine.instmem.flush(dev); 83 dev_priv->engine.instmem.flush(dev);
81 84
82 return 0; 85 return 0;
diff --git a/drivers/gpu/drm/nouveau/nvc0_fb.c b/drivers/gpu/drm/nouveau/nvc0_fb.c
new file mode 100644
index 000000000000..26a996025dd2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvc0_fb.c
@@ -0,0 +1,38 @@
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
27#include "nouveau_drv.h"
28
29int
30nvc0_fb_init(struct drm_device *dev)
31{
32 return 0;
33}
34
35void
36nvc0_fb_takedown(struct drm_device *dev)
37{
38}
diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c
new file mode 100644
index 000000000000..d64375871979
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvc0_fifo.c
@@ -0,0 +1,96 @@
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
27#include "nouveau_drv.h"
28
29void
30nvc0_fifo_disable(struct drm_device *dev)
31{
32}
33
34void
35nvc0_fifo_enable(struct drm_device *dev)
36{
37}
38
39bool
40nvc0_fifo_reassign(struct drm_device *dev, bool enable)
41{
42 return false;
43}
44
45bool
46nvc0_fifo_cache_flush(struct drm_device *dev)
47{
48 return true;
49}
50
51bool
52nvc0_fifo_cache_pull(struct drm_device *dev, bool enable)
53{
54 return false;
55}
56
57int
58nvc0_fifo_channel_id(struct drm_device *dev)
59{
60 return 127;
61}
62
63int
64nvc0_fifo_create_context(struct nouveau_channel *chan)
65{
66 return 0;
67}
68
69void
70nvc0_fifo_destroy_context(struct nouveau_channel *chan)
71{
72}
73
74int
75nvc0_fifo_load_context(struct nouveau_channel *chan)
76{
77 return 0;
78}
79
80int
81nvc0_fifo_unload_context(struct drm_device *dev)
82{
83 return 0;
84}
85
86void
87nvc0_fifo_takedown(struct drm_device *dev)
88{
89}
90
91int
92nvc0_fifo_init(struct drm_device *dev)
93{
94 return 0;
95}
96
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c
new file mode 100644
index 000000000000..717a5177a8d8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvc0_graph.c
@@ -0,0 +1,75 @@
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
27#include "nouveau_drv.h"
28
29void
30nvc0_graph_fifo_access(struct drm_device *dev, bool enabled)
31{
32}
33
34struct nouveau_channel *
35nvc0_graph_channel(struct drm_device *dev)
36{
37 return NULL;
38}
39
40int
41nvc0_graph_create_context(struct nouveau_channel *chan)
42{
43 return 0;
44}
45
46void
47nvc0_graph_destroy_context(struct nouveau_channel *chan)
48{
49}
50
51int
52nvc0_graph_load_context(struct nouveau_channel *chan)
53{
54 return 0;
55}
56
57int
58nvc0_graph_unload_context(struct drm_device *dev)
59{
60 return 0;
61}
62
63void
64nvc0_graph_takedown(struct drm_device *dev)
65{
66}
67
68int
69nvc0_graph_init(struct drm_device *dev)
70{
71 struct drm_nouveau_private *dev_priv = dev->dev_private;
72 dev_priv->engine.graph.accel_blocked = true;
73 return 0;
74}
75
diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c
new file mode 100644
index 000000000000..3ab3cdc42173
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c
@@ -0,0 +1,232 @@
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
27#include "nouveau_drv.h"
28
29int
30nvc0_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj,
31 uint32_t *size)
32{
33 int ret;
34
35 *size = ALIGN(*size, 4096);
36 if (*size == 0)
37 return -EINVAL;
38
39 ret = nouveau_bo_new(dev, NULL, *size, 0, TTM_PL_FLAG_VRAM, 0, 0x0000,
40 true, false, &gpuobj->im_backing);
41 if (ret) {
42 NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret);
43 return ret;
44 }
45
46 ret = nouveau_bo_pin(gpuobj->im_backing, TTM_PL_FLAG_VRAM);
47 if (ret) {
48 NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret);
49 nouveau_bo_ref(NULL, &gpuobj->im_backing);
50 return ret;
51 }
52
53 gpuobj->im_backing_start = gpuobj->im_backing->bo.mem.mm_node->start;
54 gpuobj->im_backing_start <<= PAGE_SHIFT;
55 return 0;
56}
57
58void
59nvc0_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
60{
61 struct drm_nouveau_private *dev_priv = dev->dev_private;
62
63 if (gpuobj && gpuobj->im_backing) {
64 if (gpuobj->im_bound)
65 dev_priv->engine.instmem.unbind(dev, gpuobj);
66 nouveau_bo_unpin(gpuobj->im_backing);
67 nouveau_bo_ref(NULL, &gpuobj->im_backing);
68 gpuobj->im_backing = NULL;
69 }
70}
71
72int
73nvc0_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
74{
75 struct drm_nouveau_private *dev_priv = dev->dev_private;
76 uint32_t pte, pte_end;
77 uint64_t vram;
78
79 if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound)
80 return -EINVAL;
81
82 NV_DEBUG(dev, "st=0x%lx sz=0x%lx\n",
83 gpuobj->im_pramin->start, gpuobj->im_pramin->size);
84
85 pte = gpuobj->im_pramin->start >> 12;
86 pte_end = (gpuobj->im_pramin->size >> 12) + pte;
87 vram = gpuobj->im_backing_start;
88
89 NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n",
90 gpuobj->im_pramin->start, pte, pte_end);
91 NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start);
92
93 while (pte < pte_end) {
94 nv_wr32(dev, 0x702000 + (pte * 8), (vram >> 8) | 1);
95 nv_wr32(dev, 0x702004 + (pte * 8), 0);
96 vram += 4096;
97 pte++;
98 }
99 dev_priv->engine.instmem.flush(dev);
100
101 if (1) {
102 u32 chan = nv_rd32(dev, 0x1700) << 16;
103 nv_wr32(dev, 0x100cb8, (chan + 0x1000) >> 8);
104 nv_wr32(dev, 0x100cbc, 0x80000005);
105 }
106
107 gpuobj->im_bound = 1;
108 return 0;
109}
110
111int
112nvc0_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
113{
114 struct drm_nouveau_private *dev_priv = dev->dev_private;
115 uint32_t pte, pte_end;
116
117 if (gpuobj->im_bound == 0)
118 return -EINVAL;
119
120 pte = gpuobj->im_pramin->start >> 12;
121 pte_end = (gpuobj->im_pramin->size >> 12) + pte;
122 while (pte < pte_end) {
123 nv_wr32(dev, 0x702000 + (pte * 8), 0);
124 nv_wr32(dev, 0x702004 + (pte * 8), 0);
125 pte++;
126 }
127 dev_priv->engine.instmem.flush(dev);
128
129 gpuobj->im_bound = 0;
130 return 0;
131}
132
133void
134nvc0_instmem_flush(struct drm_device *dev)
135{
136 nv_wr32(dev, 0x070000, 1);
137 if (!nv_wait(0x070000, 0x00000002, 0x00000000))
138 NV_ERROR(dev, "PRAMIN flush timeout\n");
139}
140
141int
142nvc0_instmem_suspend(struct drm_device *dev)
143{
144 struct drm_nouveau_private *dev_priv = dev->dev_private;
145 int i;
146
147 dev_priv->susres.ramin_copy = vmalloc(65536);
148 if (!dev_priv->susres.ramin_copy)
149 return -ENOMEM;
150
151 for (i = 0x700000; i < 0x710000; i += 4)
152 dev_priv->susres.ramin_copy[i/4] = nv_rd32(dev, i);
153 return 0;
154}
155
156void
157nvc0_instmem_resume(struct drm_device *dev)
158{
159 struct drm_nouveau_private *dev_priv = dev->dev_private;
160 u64 chan;
161 int i;
162
163 chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram;
164 nv_wr32(dev, 0x001700, chan >> 16);
165
166 for (i = 0x700000; i < 0x710000; i += 4)
167 nv_wr32(dev, i, dev_priv->susres.ramin_copy[i/4]);
168 vfree(dev_priv->susres.ramin_copy);
169 dev_priv->susres.ramin_copy = NULL;
170
171 nv_wr32(dev, 0x001714, 0xc0000000 | (chan >> 12));
172}
173
174int
175nvc0_instmem_init(struct drm_device *dev)
176{
177 struct drm_nouveau_private *dev_priv = dev->dev_private;
178 u64 chan, pgt3, imem, lim3 = dev_priv->ramin_size - 1;
179 int ret, i;
180
181 dev_priv->ramin_rsvd_vram = 1 * 1024 * 1024;
182 chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram;
183 imem = 4096 + 4096 + 32768;
184
185 nv_wr32(dev, 0x001700, chan >> 16);
186
187 /* channel setup */
188 nv_wr32(dev, 0x700200, lower_32_bits(chan + 0x1000));
189 nv_wr32(dev, 0x700204, upper_32_bits(chan + 0x1000));
190 nv_wr32(dev, 0x700208, lower_32_bits(lim3));
191 nv_wr32(dev, 0x70020c, upper_32_bits(lim3));
192
193 /* point pgd -> pgt */
194 nv_wr32(dev, 0x701000, 0);
195 nv_wr32(dev, 0x701004, ((chan + 0x2000) >> 8) | 1);
196
197 /* point pgt -> physical vram for channel */
198 pgt3 = 0x2000;
199 for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4096, pgt3 += 8) {
200 nv_wr32(dev, 0x700000 + pgt3, ((chan + i) >> 8) | 1);
201 nv_wr32(dev, 0x700004 + pgt3, 0);
202 }
203
204 /* clear rest of pgt */
205 for (; i < dev_priv->ramin_size; i += 4096, pgt3 += 8) {
206 nv_wr32(dev, 0x700000 + pgt3, 0);
207 nv_wr32(dev, 0x700004 + pgt3, 0);
208 }
209
210 /* point bar3 at the channel */
211 nv_wr32(dev, 0x001714, 0xc0000000 | (chan >> 12));
212
213 /* Global PRAMIN heap */
214 ret = drm_mm_init(&dev_priv->ramin_heap, imem,
215 dev_priv->ramin_size - imem);
216 if (ret) {
217 NV_ERROR(dev, "Failed to init RAMIN heap\n");
218 return -ENOMEM;
219 }
220
221 /*XXX: incorrect, but needed to make hash func "work" */
222 dev_priv->ramht_offset = 0x10000;
223 dev_priv->ramht_bits = 9;
224 dev_priv->ramht_size = (1 << dev_priv->ramht_bits);
225 return 0;
226}
227
228void
229nvc0_instmem_takedown(struct drm_device *dev)
230{
231}
232