Commit 03cd06ca authored by Francisco Jerez's avatar Francisco Jerez Committed by Ben Skeggs

drm/nouveau: No need to lock/unlock the VGA CRTC regs all the time.

Locking only makes sense in the VBIOS parsing code as it's executed
before CRTC init.
Signed-off-by: default avatarFrancisco Jerez <currojerez@riseup.net>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent d06ab841
...@@ -6607,7 +6607,6 @@ static bool ...@@ -6607,7 +6607,6 @@ static bool
nouveau_bios_posted(struct drm_device *dev) nouveau_bios_posted(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
bool was_locked;
unsigned htotal; unsigned htotal;
if (dev_priv->chipset >= NV_50) { if (dev_priv->chipset >= NV_50) {
...@@ -6617,13 +6616,14 @@ nouveau_bios_posted(struct drm_device *dev) ...@@ -6617,13 +6616,14 @@ nouveau_bios_posted(struct drm_device *dev)
return true; return true;
} }
was_locked = NVLockVgaCrtcs(dev, false); NVLockVgaCrtcs(dev, false);
htotal = NVReadVgaCrtc(dev, 0, 0x06); htotal = NVReadVgaCrtc(dev, 0, 0x06);
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8; htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4; htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10; htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11; htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
NVLockVgaCrtcs(dev, was_locked); NVLockVgaCrtcs(dev, true);
return (htotal != 0); return (htotal != 0);
} }
...@@ -6632,7 +6632,6 @@ nouveau_bios_init(struct drm_device *dev) ...@@ -6632,7 +6632,6 @@ nouveau_bios_init(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nvbios *bios = &dev_priv->vbios; struct nvbios *bios = &dev_priv->vbios;
bool was_locked;
int ret; int ret;
if (!NVInitVBIOS(dev)) if (!NVInitVBIOS(dev))
...@@ -6667,14 +6666,14 @@ nouveau_bios_init(struct drm_device *dev) ...@@ -6667,14 +6666,14 @@ nouveau_bios_init(struct drm_device *dev)
return ret; return ret;
/* feature_byte on BMP is poor, but init always sets CR4B */ /* feature_byte on BMP is poor, but init always sets CR4B */
was_locked = NVLockVgaCrtcs(dev, false); NVLockVgaCrtcs(dev, false);
if (bios->major_version < 5) if (bios->major_version < 5)
bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40; bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40;
/* all BIT systems need p_f_m_t for digital_min_front_porch */ /* all BIT systems need p_f_m_t for digital_min_front_porch */
if (bios->is_mobile || bios->major_version >= 5) if (bios->is_mobile || bios->major_version >= 5)
ret = parse_fp_mode_table(dev, bios); ret = parse_fp_mode_table(dev, bios);
NVLockVgaCrtcs(dev, was_locked); NVLockVgaCrtcs(dev, true);
/* allow subsequent scripts to execute */ /* allow subsequent scripts to execute */
bios->execute = true; bios->execute = true;
......
...@@ -102,44 +102,12 @@ nouveau_connector_destroy(struct drm_connector *drm_connector) ...@@ -102,44 +102,12 @@ nouveau_connector_destroy(struct drm_connector *drm_connector)
kfree(drm_connector); kfree(drm_connector);
} }
static void
nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags)
{
struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
if (dev_priv->card_type >= NV_50)
return;
*flags = 0;
if (NVLockVgaCrtcs(dev_priv->dev, false))
*flags |= 1;
if (nv_heads_tied(dev_priv->dev))
*flags |= 2;
if (*flags & 2)
NVSetOwner(dev_priv->dev, 0); /* necessary? */
}
static void
nouveau_connector_ddc_finish(struct drm_connector *connector, int flags)
{
struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
if (dev_priv->card_type >= NV_50)
return;
if (flags & 2)
NVSetOwner(dev_priv->dev, 4);
if (flags & 1)
NVLockVgaCrtcs(dev_priv->dev, true);
}
static struct nouveau_i2c_chan * static struct nouveau_i2c_chan *
nouveau_connector_ddc_detect(struct drm_connector *connector, nouveau_connector_ddc_detect(struct drm_connector *connector,
struct nouveau_encoder **pnv_encoder) struct nouveau_encoder **pnv_encoder)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
int ret, flags, i; int i;
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
struct nouveau_i2c_chan *i2c; struct nouveau_i2c_chan *i2c;
...@@ -155,17 +123,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, ...@@ -155,17 +123,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
if (!obj) if (!obj)
continue; continue;
nv_encoder = nouveau_encoder(obj_to_encoder(obj)); nv_encoder = nouveau_encoder(obj_to_encoder(obj));
i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
if (nv_encoder->dcb->i2c_index < 0xf) if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) {
i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
if (!i2c)
continue;
nouveau_connector_ddc_prepare(connector, &flags);
ret = nouveau_probe_i2c_addr(i2c, 0x50);
nouveau_connector_ddc_finish(connector, flags);
if (ret) {
*pnv_encoder = nv_encoder; *pnv_encoder = nv_encoder;
return i2c; return i2c;
} }
...@@ -218,7 +178,7 @@ nouveau_connector_detect(struct drm_connector *connector) ...@@ -218,7 +178,7 @@ nouveau_connector_detect(struct drm_connector *connector)
struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = NULL; struct nouveau_encoder *nv_encoder = NULL;
struct nouveau_i2c_chan *i2c; struct nouveau_i2c_chan *i2c;
int type, flags; int type;
/* Cleanup the previous EDID block. */ /* Cleanup the previous EDID block. */
if (nv_connector->edid) { if (nv_connector->edid) {
...@@ -229,9 +189,7 @@ nouveau_connector_detect(struct drm_connector *connector) ...@@ -229,9 +189,7 @@ nouveau_connector_detect(struct drm_connector *connector)
i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
if (i2c) { if (i2c) {
nouveau_connector_ddc_prepare(connector, &flags);
nv_connector->edid = drm_get_edid(connector, &i2c->adapter); nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
nouveau_connector_ddc_finish(connector, flags);
drm_mode_connector_update_edid_property(connector, drm_mode_connector_update_edid_property(connector,
nv_connector->edid); nv_connector->edid);
if (!nv_connector->edid) { if (!nv_connector->edid) {
......
...@@ -321,10 +321,9 @@ nouveau_pci_resume(struct pci_dev *pdev) ...@@ -321,10 +321,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
NV_ERROR(dev, "Could not pin/map cursor.\n"); NV_ERROR(dev, "Could not pin/map cursor.\n");
} }
if (dev_priv->card_type < NV_50) { if (dev_priv->card_type < NV_50)
nv04_display_restore(dev); nv04_display_restore(dev);
NVLockVgaCrtcs(dev, false); else
} else
nv50_display_init(dev); nv50_display_init(dev);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
......
...@@ -32,8 +32,6 @@ ...@@ -32,8 +32,6 @@
#include "nouveau_encoder.h" #include "nouveau_encoder.h"
#include "nouveau_connector.h" #include "nouveau_connector.h"
#define MULTIPLE_ENCODERS(e) (e & (e - 1))
static void static void
nv04_display_store_initial_head_owner(struct drm_device *dev) nv04_display_store_initial_head_owner(struct drm_device *dev)
{ {
...@@ -41,7 +39,7 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) ...@@ -41,7 +39,7 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
if (dev_priv->chipset != 0x11) { if (dev_priv->chipset != 0x11) {
dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44); dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44);
goto ownerknown; return;
} }
/* reading CR44 is broken on nv11, so we attempt to infer it */ /* reading CR44 is broken on nv11, so we attempt to infer it */
...@@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) ...@@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
bool tvA = false; bool tvA = false;
bool tvB = false; bool tvB = false;
NVLockVgaCrtcs(dev, false);
slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) & slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) &
0x80; 0x80;
if (slaved_on_B) if (slaved_on_B)
...@@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) ...@@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) & tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) &
MASK(NV_CIO_CRE_LCD_LCD_SELECT)); MASK(NV_CIO_CRE_LCD_LCD_SELECT));
NVLockVgaCrtcs(dev, true);
if (slaved_on_A && !tvA) if (slaved_on_A && !tvA)
dev_priv->crtc_owner = 0x0; dev_priv->crtc_owner = 0x0;
else if (slaved_on_B && !tvB) else if (slaved_on_B && !tvB)
...@@ -79,12 +73,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) ...@@ -79,12 +73,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
else else
dev_priv->crtc_owner = 0x0; dev_priv->crtc_owner = 0x0;
} }
ownerknown:
/* we need to ensure the heads are not tied henceforth, or reading any
* 8 bit reg on head B will fail
* setting a single arbitrary head solves that */
NVSetOwner(dev, 0);
} }
int int
...@@ -99,8 +87,13 @@ nv04_display_create(struct drm_device *dev) ...@@ -99,8 +87,13 @@ nv04_display_create(struct drm_device *dev)
NV_DEBUG_KMS(dev, "\n"); NV_DEBUG_KMS(dev, "\n");
if (nv_two_heads(dev)) NVLockVgaCrtcs(dev, false);
if (nv_two_heads(dev)) {
nv04_display_store_initial_head_owner(dev); nv04_display_store_initial_head_owner(dev);
NVSetOwner(dev, 0);
}
nouveau_hw_save_vga_fonts(dev, 1); nouveau_hw_save_vga_fonts(dev, 1);
drm_mode_config_init(dev); drm_mode_config_init(dev);
...@@ -168,8 +161,6 @@ nv04_display_create(struct drm_device *dev) ...@@ -168,8 +161,6 @@ nv04_display_create(struct drm_device *dev)
} }
/* Save previous state */ /* Save previous state */
NVLockVgaCrtcs(dev, false);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
crtc->funcs->save(crtc); crtc->funcs->save(crtc);
...@@ -185,6 +176,7 @@ nv04_display_create(struct drm_device *dev) ...@@ -185,6 +176,7 @@ nv04_display_create(struct drm_device *dev)
void void
nv04_display_destroy(struct drm_device *dev) nv04_display_destroy(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_crtc *crtc; struct drm_crtc *crtc;
...@@ -200,8 +192,6 @@ nv04_display_destroy(struct drm_device *dev) ...@@ -200,8 +192,6 @@ nv04_display_destroy(struct drm_device *dev)
} }
/* Restore state */ /* Restore state */
NVLockVgaCrtcs(dev, false);
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
struct drm_encoder_helper_funcs *func = encoder->helper_private; struct drm_encoder_helper_funcs *func = encoder->helper_private;
...@@ -214,12 +204,15 @@ nv04_display_destroy(struct drm_device *dev) ...@@ -214,12 +204,15 @@ nv04_display_destroy(struct drm_device *dev)
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
nouveau_hw_save_vga_fonts(dev, 0); nouveau_hw_save_vga_fonts(dev, 0);
if (nv_two_heads(dev))
NVSetOwner(dev, dev_priv->crtc_owner);
NVLockVgaCrtcs(dev, true);
} }
void void
nv04_display_restore(struct drm_device *dev) nv04_display_restore(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_crtc *crtc; struct drm_crtc *crtc;
...@@ -241,10 +234,5 @@ nv04_display_restore(struct drm_device *dev) ...@@ -241,10 +234,5 @@ nv04_display_restore(struct drm_device *dev)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
crtc->funcs->restore(crtc); crtc->funcs->restore(crtc);
if (nv_two_heads(dev))
NVSetOwner(dev, dev_priv->crtc_owner);
NVLockVgaCrtcs(dev, true);
} }
...@@ -194,7 +194,6 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) ...@@ -194,7 +194,6 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
struct nouveau_i2c_chan *i2c = struct nouveau_i2c_chan *i2c =
nouveau_i2c_find(dev, entry->i2c_index); nouveau_i2c_find(dev, entry->i2c_index);
int type, ret; int type, ret;
bool was_locked;
/* Ensure that we can talk to this encoder */ /* Ensure that we can talk to this encoder */
type = nv04_tv_identify(dev, entry->i2c_index); type = nv04_tv_identify(dev, entry->i2c_index);
...@@ -224,13 +223,8 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) ...@@ -224,13 +223,8 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
nv_encoder->or = ffs(entry->or) - 1; nv_encoder->or = ffs(entry->or) - 1;
/* Run the slave-specific initialization */ /* Run the slave-specific initialization */
was_locked = NVLockVgaCrtcs(dev, false);
ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
&i2c->adapter, &nv04_tv_encoder_info[type]); &i2c->adapter, &nv04_tv_encoder_info[type]);
NVLockVgaCrtcs(dev, was_locked);
if (ret < 0) if (ret < 0)
goto fail_cleanup; goto fail_cleanup;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment