mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-27 01:10:52 +07:00
Merge remote branch 'nouveau/for-airlied' of ../drm-nouveau-next into drm-testing
* 'nouveau/for-airlied' of ../drm-nouveau-next: drm/nv50: cast IGP memory location to u64 before shifting drm/nv50: use alternate source of SOR_MODE_CTRL for DP hack drm/nouveau: fix dual-link displays when plugged into single-link outputs drm/nv50: obey dcb->duallink_possible drm/nv50: fix duallink_possible calculation for DCB 4.0 cards drm/nouveau: don't execute INIT_GPIO unless we're really running the table drm/nv40: allow cold-booting of nv4x chipsets drm/nouveau: fix POST detection for certain chipsets drm/nouveau: Add getparam for current PTIMER time. drm/nouveau: allow cursor image and position to survive suspend
This commit is contained in:
commit
36d1701c50
@ -2827,6 +2827,9 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
|
||||
BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
|
||||
|
||||
BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n",
|
||||
offset, gpio->tag, gpio->state_default);
|
||||
if (bios->execute)
|
||||
nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
|
||||
|
||||
/* The NVIDIA binary driver doesn't appear to actually do
|
||||
@ -5553,12 +5556,6 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
|
||||
entry->bus = (conn >> 16) & 0xf;
|
||||
entry->location = (conn >> 20) & 0x3;
|
||||
entry->or = (conn >> 24) & 0xf;
|
||||
/*
|
||||
* Normal entries consist of a single bit, but dual link has the
|
||||
* next most significant bit set too
|
||||
*/
|
||||
entry->duallink_possible =
|
||||
((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
|
||||
|
||||
switch (entry->type) {
|
||||
case OUTPUT_ANALOG:
|
||||
@ -5642,6 +5639,16 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
|
||||
break;
|
||||
}
|
||||
|
||||
if (dcb->version < 0x40) {
|
||||
/* Normal entries consist of a single bit, but dual link has
|
||||
* the next most significant bit set too
|
||||
*/
|
||||
entry->duallink_possible =
|
||||
((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
|
||||
} else {
|
||||
entry->duallink_possible = (entry->sorconf.link == 3);
|
||||
}
|
||||
|
||||
/* unsure what DCB version introduces this, 3.0? */
|
||||
if (conf & 0x100000)
|
||||
entry->i2c_upper_default = true;
|
||||
@ -6225,6 +6232,30 @@ nouveau_bios_i2c_devices_takedown(struct drm_device *dev)
|
||||
nouveau_i2c_fini(dev, entry);
|
||||
}
|
||||
|
||||
static bool
|
||||
nouveau_bios_posted(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
bool was_locked;
|
||||
unsigned htotal;
|
||||
|
||||
if (dev_priv->chipset >= NV_50) {
|
||||
if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
|
||||
NVReadVgaCrtc(dev, 0, 0x1a) == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
was_locked = NVLockVgaCrtcs(dev, false);
|
||||
htotal = NVReadVgaCrtc(dev, 0, 0x06);
|
||||
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
|
||||
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
|
||||
htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
|
||||
htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
|
||||
NVLockVgaCrtcs(dev, was_locked);
|
||||
return (htotal != 0);
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_bios_init(struct drm_device *dev)
|
||||
{
|
||||
@ -6259,11 +6290,9 @@ nouveau_bios_init(struct drm_device *dev)
|
||||
bios->execute = false;
|
||||
|
||||
/* ... unless card isn't POSTed already */
|
||||
if (dev_priv->card_type >= NV_10 &&
|
||||
NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
|
||||
NVReadVgaCrtc(dev, 0, 0x1a) == 0) {
|
||||
if (!nouveau_bios_posted(dev)) {
|
||||
NV_INFO(dev, "Adaptor not initialised\n");
|
||||
if (dev_priv->card_type < NV_50) {
|
||||
if (dev_priv->card_type < NV_40) {
|
||||
NV_ERROR(dev, "Unable to POST this chipset\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -432,24 +432,27 @@ nouveau_connector_set_property(struct drm_connector *connector,
|
||||
}
|
||||
|
||||
static struct drm_display_mode *
|
||||
nouveau_connector_native_mode(struct nouveau_connector *connector)
|
||||
nouveau_connector_native_mode(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->base.dev;
|
||||
struct drm_connector_helper_funcs *helper = connector->helper_private;
|
||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_display_mode *mode, *largest = NULL;
|
||||
int high_w = 0, high_h = 0, high_v = 0;
|
||||
|
||||
list_for_each_entry(mode, &nv_connector->base.probed_modes, head) {
|
||||
if (helper->mode_valid(connector, mode) != MODE_OK)
|
||||
continue;
|
||||
|
||||
/* Use preferred mode if there is one.. */
|
||||
list_for_each_entry(mode, &connector->base.probed_modes, head) {
|
||||
if (mode->type & DRM_MODE_TYPE_PREFERRED) {
|
||||
NV_DEBUG_KMS(dev, "native mode from preferred\n");
|
||||
return drm_mode_duplicate(dev, mode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, take the resolution with the largest width, then height,
|
||||
* then vertical refresh
|
||||
/* Otherwise, take the resolution with the largest width, then
|
||||
* height, then vertical refresh
|
||||
*/
|
||||
list_for_each_entry(mode, &connector->base.probed_modes, head) {
|
||||
if (mode->hdisplay < high_w)
|
||||
continue;
|
||||
|
||||
@ -553,7 +556,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
|
||||
*/
|
||||
if (!nv_connector->native_mode)
|
||||
nv_connector->native_mode =
|
||||
nouveau_connector_native_mode(nv_connector);
|
||||
nouveau_connector_native_mode(connector);
|
||||
if (ret == 0 && nv_connector->native_mode) {
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
@ -584,9 +587,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
|
||||
|
||||
switch (nv_encoder->dcb->type) {
|
||||
case OUTPUT_LVDS:
|
||||
BUG_ON(!nv_connector->native_mode);
|
||||
if (mode->hdisplay > nv_connector->native_mode->hdisplay ||
|
||||
mode->vdisplay > nv_connector->native_mode->vdisplay)
|
||||
if (nv_connector->native_mode &&
|
||||
(mode->hdisplay > nv_connector->native_mode->hdisplay ||
|
||||
mode->vdisplay > nv_connector->native_mode->vdisplay))
|
||||
return MODE_PANEL;
|
||||
|
||||
min_clock = 0;
|
||||
@ -594,8 +597,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
|
||||
break;
|
||||
case OUTPUT_TMDS:
|
||||
if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
|
||||
(dev_priv->card_type < NV_50 &&
|
||||
!nv_encoder->dcb->duallink_possible))
|
||||
!nv_encoder->dcb->duallink_possible)
|
||||
max_clock = 165000;
|
||||
else
|
||||
max_clock = 330000;
|
||||
@ -729,7 +731,7 @@ nouveau_connector_create_lvds(struct drm_device *dev,
|
||||
if (ret == 0)
|
||||
goto out;
|
||||
nv_connector->detected_encoder = nv_encoder;
|
||||
nv_connector->native_mode = nouveau_connector_native_mode(nv_connector);
|
||||
nv_connector->native_mode = nouveau_connector_native_mode(connector);
|
||||
list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
|
||||
drm_mode_remove(connector, mode);
|
||||
|
||||
|
@ -40,6 +40,8 @@ struct nouveau_crtc {
|
||||
int sharpness;
|
||||
int last_dpms;
|
||||
|
||||
int cursor_saved_x, cursor_saved_y;
|
||||
|
||||
struct {
|
||||
int cpp;
|
||||
bool blanked;
|
||||
|
@ -175,6 +175,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
|
||||
nouveau_bo_unpin(nouveau_fb->nvbo);
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
|
||||
nouveau_bo_unmap(nv_crtc->cursor.nvbo);
|
||||
nouveau_bo_unpin(nv_crtc->cursor.nvbo);
|
||||
}
|
||||
|
||||
NV_INFO(dev, "Evicting buffers...\n");
|
||||
ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
|
||||
|
||||
@ -314,12 +321,34 @@ nouveau_pci_resume(struct pci_dev *pdev)
|
||||
nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
int ret;
|
||||
|
||||
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
|
||||
if (!ret)
|
||||
ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
|
||||
if (ret)
|
||||
NV_ERROR(dev, "Could not pin/map cursor.\n");
|
||||
}
|
||||
|
||||
if (dev_priv->card_type < NV_50) {
|
||||
nv04_display_restore(dev);
|
||||
NVLockVgaCrtcs(dev, false);
|
||||
} else
|
||||
nv50_display_init(dev);
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
|
||||
nv_crtc->cursor.set_offset(nv_crtc,
|
||||
nv_crtc->cursor.nvbo->bo.offset -
|
||||
dev_priv->vm_vram_base);
|
||||
|
||||
nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
|
||||
nv_crtc->cursor_saved_y);
|
||||
}
|
||||
|
||||
/* Force CLUT to get re-loaded during modeset */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
|
@ -540,7 +540,8 @@ nouveau_mem_detect(struct drm_device *dev)
|
||||
dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA);
|
||||
dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
|
||||
if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
|
||||
dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
|
||||
dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10);
|
||||
dev_priv->vram_sys_base <<= 12;
|
||||
}
|
||||
|
||||
NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
|
||||
|
@ -916,6 +916,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
|
||||
case NOUVEAU_GETPARAM_VM_VRAM_BASE:
|
||||
getparam->value = dev_priv->vm_vram_base;
|
||||
break;
|
||||
case NOUVEAU_GETPARAM_PTIMER_TIME:
|
||||
getparam->value = dev_priv->engine.timer.read(dev);
|
||||
break;
|
||||
case NOUVEAU_GETPARAM_GRAPH_UNITS:
|
||||
/* NV40 and NV50 versions are quite different, but register
|
||||
* address is the same. User is supposed to know the card
|
||||
|
@ -20,6 +20,7 @@ nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
|
||||
static void
|
||||
nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
|
||||
{
|
||||
nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y;
|
||||
NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index,
|
||||
NV_PRAMDAC_CU_START_POS,
|
||||
XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) |
|
||||
|
@ -107,6 +107,7 @@ nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
|
||||
{
|
||||
struct drm_device *dev = nv_crtc->base.dev;
|
||||
|
||||
nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y;
|
||||
nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index),
|
||||
((y & 0xFFFF) << 16) | (x & 0xFFFF));
|
||||
/* Needed to make the cursor move. */
|
||||
|
@ -274,7 +274,6 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
|
||||
int
|
||||
nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_encoder *nv_encoder = NULL;
|
||||
struct drm_encoder *encoder;
|
||||
bool dum;
|
||||
@ -324,11 +323,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
|
||||
int or = nv_encoder->or, link = !(entry->dpconf.sor.link & 1);
|
||||
uint32_t tmp;
|
||||
|
||||
if (dev_priv->chipset < 0x90 ||
|
||||
dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
|
||||
tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or));
|
||||
else
|
||||
tmp = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or));
|
||||
tmp = nv_rd32(dev, 0x61c700 + (or * 0x800));
|
||||
|
||||
switch ((tmp & 0x00000f00) >> 8) {
|
||||
case 8:
|
||||
|
@ -79,6 +79,7 @@ struct drm_nouveau_gpuobj_free {
|
||||
#define NOUVEAU_GETPARAM_CHIPSET_ID 11
|
||||
#define NOUVEAU_GETPARAM_VM_VRAM_BASE 12
|
||||
#define NOUVEAU_GETPARAM_GRAPH_UNITS 13
|
||||
#define NOUVEAU_GETPARAM_PTIMER_TIME 14
|
||||
struct drm_nouveau_getparam {
|
||||
uint64_t param;
|
||||
uint64_t value;
|
||||
|
Loading…
Reference in New Issue
Block a user