Skip to content

Commit c3b6ef8

Browse files
committed
Merge remote branch 'nouveau/for-airlied' of /ssd/git/drm-nouveau-next into drm-core-next
* 'nouveau/for-airlied' of /ssd/git/drm-nouveau-next: (27 commits) drm/nvc0: fix typo in PRAMIN flush drm/nouveau: Fix DCB TMDS config parsing. drm/nv30: Fix PFB init for nv31. drm/nv04: Fix up SGRAM density detection. drm/i2c/ch7006: Don't use POWER_LEVEL_FULL_POWER_OFF on early chip versions. drm/nouveau: Init dcb->or on cards that have no usable DCB table. drm/nouveau: reduce severity of some "error" messages drm/nvc0: backup bar3 channel on suspend drm/nouveau: implement init table opcodex 0x5e and 0x9a drm/nouveau: implement init table op 0x57, INIT_LTIME drm/nvc0: implement crtc pll setting drm/nvc0: fix evo dma object so we display something drm/nvc0: rudimentary instmem support drm/nvc0: implement memory detection drm/nvc0: allow INIT_GPIO drm/nvc0: starting point for GF100 support, everything stubbed drm/nv30: Workaround dual TMDS brain damage. drm/nouveau: No need to set slave TV encoder configs explicitly. drm/nv17-nv4x: Attempt to init some external TMDS transmitters. drm/nv10: Fix up switching of NV10TCL_DMA_VTXBUF. ...
2 parents d8ab355 + 2dc5d2e commit c3b6ef8

30 files changed

+1118
-201
lines changed

drivers/gpu/drm/i2c/ch7006_drv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ static int ch7006_encoder_init(struct i2c_client *client,
470470
priv->hmargin = 50;
471471
priv->vmargin = 50;
472472
priv->last_dpms = -1;
473+
priv->chip_version = ch7006_read(client, CH7006_VERSION_ID);
473474

474475
if (ch7006_tv_norm) {
475476
for (i = 0; i < NUM_TV_NORMS; i++) {

drivers/gpu/drm/i2c/ch7006_mode.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,10 @@ void ch7006_setup_power_state(struct drm_encoder *encoder)
316316
}
317317

318318
} else {
319-
*power |= bitfs(CH7006_POWER_LEVEL, FULL_POWER_OFF);
319+
if (priv->chip_version >= 0x20)
320+
*power |= bitfs(CH7006_POWER_LEVEL, FULL_POWER_OFF);
321+
else
322+
*power |= bitfs(CH7006_POWER_LEVEL, POWER_OFF);
320323
}
321324
}
322325

drivers/gpu/drm/i2c/ch7006_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ struct ch7006_priv {
9595
int flicker;
9696
int scale;
9797

98+
int chip_version;
9899
int last_dpms;
99100
};
100101

drivers/gpu/drm/nouveau/Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
1212
nouveau_dp.o \
1313
nv04_timer.o \
1414
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 \
16-
nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.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 nvc0_fifo.o \
1717
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 \
1919
nv40_grctx.o nv50_grctx.o \
20-
nv04_instmem.o nv50_instmem.o \
20+
nv04_instmem.o nv50_instmem.o nvc0_instmem.o \
2121
nv50_crtc.o nv50_dac.o nv50_sor.o \
2222
nv50_cursor.o nv50_display.o nv50_fbcon.o \
2323
nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \

drivers/gpu/drm/nouveau/nouveau_bios.c

Lines changed: 182 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,6 +1927,31 @@ init_condition_time(struct nvbios *bios, uint16_t offset,
19271927
return 3;
19281928
}
19291929

1930+
static int
1931+
init_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+
19301955
static int
19311956
init_zm_reg_sequence(struct nvbios *bios, uint16_t offset,
19321957
struct init_exec *iexec)
@@ -1994,6 +2019,64 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
19942019
return 3;
19952020
}
19962021

2022+
static int
2023+
init_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+
19972080
static int
19982081
init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
19992082
{
@@ -2083,9 +2166,10 @@ peek_fb(struct drm_device *dev, struct io_mapping *fb,
20832166
uint32_t val = 0;
20842167

20852168
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);
20872171

2088-
val = ioread32(p);
2172+
val = ioread32(p + (off & ~PAGE_MASK));
20892173

20902174
io_mapping_unmap_atomic(p, KM_USER0);
20912175
}
@@ -2098,9 +2182,10 @@ poke_fb(struct drm_device *dev, struct io_mapping *fb,
20982182
uint32_t off, uint32_t val)
20992183
{
21002184
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);
21022187

2103-
iowrite32(val, p);
2188+
iowrite32(val, p + (off & ~PAGE_MASK));
21042189
wmb();
21052190

21062191
io_mapping_unmap_atomic(p, KM_USER0);
@@ -2165,7 +2250,7 @@ nv04_init_compute_mem(struct nvbios *bios)
21652250
NV04_PFB_BOOT_0_RAM_AMOUNT,
21662251
NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
21672252

2168-
} else if (peek_fb(dev, fb, 0) == patt) {
2253+
} else if (peek_fb(dev, fb, 0) != patt) {
21692254
if (read_back_fb(dev, fb, 0x800000, patt))
21702255
bios_md32(bios, NV04_PFB_BOOT_0,
21712256
NV04_PFB_BOOT_0_RAM_AMOUNT,
@@ -2593,7 +2678,7 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset,
25932678
/* no iexec->execute check by design */
25942679

25952680
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;
25972682

25982683
if (bios->major_version > 2)
25992684
return 0;
@@ -3140,7 +3225,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
31403225
const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
31413226
int i;
31423227

3143-
if (dev_priv->card_type != NV_50) {
3228+
if (dev_priv->card_type < NV_50) {
31443229
NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
31453230
return 1;
31463231
}
@@ -3490,6 +3575,69 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
34903575
return len;
34913576
}
34923577

3578+
static int
3579+
init_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+
34933641
static struct init_tbl_entry itbl_entry[] = {
34943642
/* command name , id , length , offset , mult , command handler */
34953643
/* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */
@@ -3516,9 +3664,11 @@ static struct init_tbl_entry itbl_entry[] = {
35163664
{ "INIT_ZM_CR" , 0x53, init_zm_cr },
35173665
{ "INIT_ZM_CR_GROUP" , 0x54, init_zm_cr_group },
35183666
{ "INIT_CONDITION_TIME" , 0x56, init_condition_time },
3667+
{ "INIT_LTIME" , 0x57, init_ltime },
35193668
{ "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence },
35203669
/* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */
35213670
{ "INIT_SUB_DIRECT" , 0x5B, init_sub_direct },
3671+
{ "INIT_I2C_IF" , 0x5E, init_i2c_if },
35223672
{ "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg },
35233673
{ "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io },
35243674
{ "INIT_COMPUTE_MEM" , 0x63, init_compute_mem },
@@ -3552,6 +3702,7 @@ static struct init_tbl_entry itbl_entry[] = {
35523702
{ "INIT_97" , 0x97, init_97 },
35533703
{ "INIT_AUXCH" , 0x98, init_auxch },
35543704
{ "INIT_ZM_AUXCH" , 0x99, init_zm_auxch },
3705+
{ "INIT_I2C_LONG_IF" , 0x9A, init_i2c_long_if },
35553706
{ NULL , 0 , NULL }
35563707
};
35573708

@@ -4410,7 +4561,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
44104561
bios->display.script_table_ptr,
44114562
table[2], table[3], table[0] >= 0x21);
44124563
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");
44144565
return 1;
44154566
}
44164567

@@ -4467,7 +4618,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
44674618
if (script)
44684619
script = clkcmptable(bios, script, pxclk);
44694620
if (!script) {
4470-
NV_ERROR(dev, "clock script 0 not found\n");
4621+
NV_DEBUG_KMS(dev, "clock script 0 not found\n");
44714622
return 1;
44724623
}
44734624

@@ -4826,7 +4977,7 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims
48264977
pll_lim->min_p = record[12];
48274978
pll_lim->max_p = record[13];
48284979
/* where did this go to?? */
4829-
if (limit_match == 0x00614100 || limit_match == 0x00614900)
4980+
if ((entry[0] & 0xf0) == 0x80)
48304981
pll_lim->refclk = 27000;
48314982
else
48324983
pll_lim->refclk = 100000;
@@ -5852,7 +6003,7 @@ static void fabricate_vga_output(struct dcb_table *dcb, int i2c, int heads)
58526003
entry->i2c_index = i2c;
58536004
entry->heads = heads;
58546005
entry->location = DCB_LOC_ON_CHIP;
5855-
/* "or" mostly unused in early gen crt modesetting, 0 is fine */
6006+
entry->or = 1;
58566007
}
58576008

58586009
static 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,
59806131
}
59816132
break;
59826133
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+
59846141
break;
59856142
case 0xe:
59866143
/* 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)
62706427
dcb->i2c_table = &bios->data[i2ctabptr];
62716428
if (dcb->version >= 0x30)
62726429
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+
}
62736443
}
62746444

62756445
if (entries > DCB_MAX_NUM_ENTRIES)

drivers/gpu/drm/nouveau/nouveau_bios.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ struct dcb_entry {
131131
} dpconf;
132132
struct {
133133
struct sor_conf sor;
134+
int slave_addr;
134135
} tmdsconf;
135136
};
136137
bool i2c_upper_default;

drivers/gpu/drm/nouveau/nouveau_bo.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
5151
if (nvbo->tile)
5252
nv10_mem_expire_tiling(dev, nvbo->tile, NULL);
5353

54-
spin_lock(&dev_priv->ttm.bo_list_lock);
55-
list_del(&nvbo->head);
56-
spin_unlock(&dev_priv->ttm.bo_list_lock);
5754
kfree(nvbo);
5855
}
5956

@@ -166,9 +163,6 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
166163
}
167164
nvbo->channel = NULL;
168165

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);
172166
*pnvbo = nvbo;
173167
return 0;
174168
}

0 commit comments

Comments
 (0)