forked from Minki/linux
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "Nothing too scary, we have one outstanding i915 regression but Daniel has promised the fix as soon as he's finished testing it a bit. Fixes for the main x86 drivers: - radeon: dpm fixes, displayport regression fix - i915: quirks for backlight regression, edp reboot fix, valleyview black screen fixes - nouveau: display port regression fixes, fix for memory reclocking" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/radeon/dpm: Reenabling SS on Cayman drm/radeon: fix typo in ci_stop_dpm() drm/radeon: fix typo in golden register setup on evergreen drm/radeon: only print meaningful VM faults drm/radeon/dp: return -EIO for flags not zero case drm/i915/vlv: T12 eDP panel timing enforcement during reboot drm/i915: Only unbind vgacon, not other console drivers drm/i915: Don't clobber the GTT when it's within stolen memory drm/i915/vlv: Update the DSI ULPS entry/exit sequence drm/i915/vlv: DPI FIFO empty check is not needed drm/i915: Toshiba CB35 has a controllable backlight drm/i915: Acer C720 and C720P have controllable backlights drm/i915: quirk asserts controllable backlight presence, overriding VBT drm/nouveau/ram: fix test for gpio presence drm/nouveau/dp: workaround broken display drm/nouveau/dp: fix required link bandwidth calculations drm/nouveau/kms: restore fbcon after display has been resumed drm/nv50-/kms: pass a non-zero value for head to sor dpms methods drm/nouveau/fb: Prevent inlining of ramfuc_reg drm/gk104/ram: bash mpll bit 31 on
This commit is contained in:
commit
85d90faed3
@ -1464,12 +1464,13 @@ static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
|
|||||||
#else
|
#else
|
||||||
static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
|
static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
DRM_INFO("Replacing VGA console driver\n");
|
DRM_INFO("Replacing VGA console driver\n");
|
||||||
|
|
||||||
console_lock();
|
console_lock();
|
||||||
ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
|
if (con_is_bound(&vga_con))
|
||||||
|
ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = do_unregister_con_driver(&vga_con);
|
ret = do_unregister_con_driver(&vga_con);
|
||||||
|
|
||||||
|
@ -656,6 +656,7 @@ enum intel_sbi_destination {
|
|||||||
#define QUIRK_PIPEA_FORCE (1<<0)
|
#define QUIRK_PIPEA_FORCE (1<<0)
|
||||||
#define QUIRK_LVDS_SSC_DISABLE (1<<1)
|
#define QUIRK_LVDS_SSC_DISABLE (1<<1)
|
||||||
#define QUIRK_INVERT_BRIGHTNESS (1<<2)
|
#define QUIRK_INVERT_BRIGHTNESS (1<<2)
|
||||||
|
#define QUIRK_BACKLIGHT_PRESENT (1<<3)
|
||||||
|
|
||||||
struct intel_fbdev;
|
struct intel_fbdev;
|
||||||
struct intel_fbc_work;
|
struct intel_fbc_work;
|
||||||
|
@ -74,6 +74,50 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
|
|||||||
if (base == 0)
|
if (base == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* make sure we don't clobber the GTT if it's within stolen memory */
|
||||||
|
if (INTEL_INFO(dev)->gen <= 4 && !IS_G33(dev) && !IS_G4X(dev)) {
|
||||||
|
struct {
|
||||||
|
u32 start, end;
|
||||||
|
} stolen[2] = {
|
||||||
|
{ .start = base, .end = base + dev_priv->gtt.stolen_size, },
|
||||||
|
{ .start = base, .end = base + dev_priv->gtt.stolen_size, },
|
||||||
|
};
|
||||||
|
u64 gtt_start, gtt_end;
|
||||||
|
|
||||||
|
gtt_start = I915_READ(PGTBL_CTL);
|
||||||
|
if (IS_GEN4(dev))
|
||||||
|
gtt_start = (gtt_start & PGTBL_ADDRESS_LO_MASK) |
|
||||||
|
(gtt_start & PGTBL_ADDRESS_HI_MASK) << 28;
|
||||||
|
else
|
||||||
|
gtt_start &= PGTBL_ADDRESS_LO_MASK;
|
||||||
|
gtt_end = gtt_start + gtt_total_entries(dev_priv->gtt) * 4;
|
||||||
|
|
||||||
|
if (gtt_start >= stolen[0].start && gtt_start < stolen[0].end)
|
||||||
|
stolen[0].end = gtt_start;
|
||||||
|
if (gtt_end > stolen[1].start && gtt_end <= stolen[1].end)
|
||||||
|
stolen[1].start = gtt_end;
|
||||||
|
|
||||||
|
/* pick the larger of the two chunks */
|
||||||
|
if (stolen[0].end - stolen[0].start >
|
||||||
|
stolen[1].end - stolen[1].start) {
|
||||||
|
base = stolen[0].start;
|
||||||
|
dev_priv->gtt.stolen_size = stolen[0].end - stolen[0].start;
|
||||||
|
} else {
|
||||||
|
base = stolen[1].start;
|
||||||
|
dev_priv->gtt.stolen_size = stolen[1].end - stolen[1].start;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stolen[0].start != stolen[1].start ||
|
||||||
|
stolen[0].end != stolen[1].end) {
|
||||||
|
DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n",
|
||||||
|
(unsigned long long) gtt_start,
|
||||||
|
(unsigned long long) gtt_end - 1);
|
||||||
|
DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n",
|
||||||
|
base, base + (u32) dev_priv->gtt.stolen_size - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Verify that nothing else uses this physical address. Stolen
|
/* Verify that nothing else uses this physical address. Stolen
|
||||||
* memory should be reserved by the BIOS and hidden from the
|
* memory should be reserved by the BIOS and hidden from the
|
||||||
* kernel. So if the region is already marked as busy, something
|
* kernel. So if the region is already marked as busy, something
|
||||||
|
@ -942,6 +942,9 @@ enum punit_power_well {
|
|||||||
/*
|
/*
|
||||||
* Instruction and interrupt control regs
|
* Instruction and interrupt control regs
|
||||||
*/
|
*/
|
||||||
|
#define PGTBL_CTL 0x02020
|
||||||
|
#define PGTBL_ADDRESS_LO_MASK 0xfffff000 /* bits [31:12] */
|
||||||
|
#define PGTBL_ADDRESS_HI_MASK 0x000000f0 /* bits [35:32] (gen4) */
|
||||||
#define PGTBL_ER 0x02024
|
#define PGTBL_ER 0x02024
|
||||||
#define RENDER_RING_BASE 0x02000
|
#define RENDER_RING_BASE 0x02000
|
||||||
#define BSD_RING_BASE 0x04000
|
#define BSD_RING_BASE 0x04000
|
||||||
|
@ -11591,6 +11591,14 @@ static void quirk_invert_brightness(struct drm_device *dev)
|
|||||||
DRM_INFO("applying inverted panel brightness quirk\n");
|
DRM_INFO("applying inverted panel brightness quirk\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Some VBT's incorrectly indicate no backlight is present */
|
||||||
|
static void quirk_backlight_present(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
dev_priv->quirks |= QUIRK_BACKLIGHT_PRESENT;
|
||||||
|
DRM_INFO("applying backlight present quirk\n");
|
||||||
|
}
|
||||||
|
|
||||||
struct intel_quirk {
|
struct intel_quirk {
|
||||||
int device;
|
int device;
|
||||||
int subsystem_vendor;
|
int subsystem_vendor;
|
||||||
@ -11659,6 +11667,12 @@ static struct intel_quirk intel_quirks[] = {
|
|||||||
|
|
||||||
/* Acer Aspire 5336 */
|
/* Acer Aspire 5336 */
|
||||||
{ 0x2a42, 0x1025, 0x048a, quirk_invert_brightness },
|
{ 0x2a42, 0x1025, 0x048a, quirk_invert_brightness },
|
||||||
|
|
||||||
|
/* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */
|
||||||
|
{ 0x0a06, 0x1025, 0x0a11, quirk_backlight_present },
|
||||||
|
|
||||||
|
/* Toshiba CB35 Chromebook (Celeron 2955U) */
|
||||||
|
{ 0x0a06, 0x1179, 0x0a88, quirk_backlight_present },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void intel_init_quirks(struct drm_device *dev)
|
static void intel_init_quirks(struct drm_device *dev)
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/notifier.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
#include <drm/drmP.h>
|
#include <drm/drmP.h>
|
||||||
#include <drm/drm_crtc.h>
|
#include <drm/drm_crtc.h>
|
||||||
#include <drm/drm_crtc_helper.h>
|
#include <drm/drm_crtc_helper.h>
|
||||||
@ -336,6 +338,37 @@ static u32 _pp_stat_reg(struct intel_dp *intel_dp)
|
|||||||
return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp));
|
return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reboot notifier handler to shutdown panel power to guarantee T12 timing
|
||||||
|
This function only applicable when panel PM state is not to be tracked */
|
||||||
|
static int edp_notify_handler(struct notifier_block *this, unsigned long code,
|
||||||
|
void *unused)
|
||||||
|
{
|
||||||
|
struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp),
|
||||||
|
edp_notifier);
|
||||||
|
struct drm_device *dev = intel_dp_to_dev(intel_dp);
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
u32 pp_div;
|
||||||
|
u32 pp_ctrl_reg, pp_div_reg;
|
||||||
|
enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
|
||||||
|
|
||||||
|
if (!is_edp(intel_dp) || code != SYS_RESTART)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (IS_VALLEYVIEW(dev)) {
|
||||||
|
pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe);
|
||||||
|
pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
|
||||||
|
pp_div = I915_READ(pp_div_reg);
|
||||||
|
pp_div &= PP_REFERENCE_DIVIDER_MASK;
|
||||||
|
|
||||||
|
/* 0x1F write to PP_DIV_REG sets max cycle delay */
|
||||||
|
I915_WRITE(pp_div_reg, pp_div | 0x1F);
|
||||||
|
I915_WRITE(pp_ctrl_reg, PANEL_UNLOCK_REGS | PANEL_POWER_OFF);
|
||||||
|
msleep(intel_dp->panel_power_cycle_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool edp_have_panel_power(struct intel_dp *intel_dp)
|
static bool edp_have_panel_power(struct intel_dp *intel_dp)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = intel_dp_to_dev(intel_dp);
|
struct drm_device *dev = intel_dp_to_dev(intel_dp);
|
||||||
@ -3707,6 +3740,10 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
|
|||||||
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
|
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
|
||||||
edp_panel_vdd_off_sync(intel_dp);
|
edp_panel_vdd_off_sync(intel_dp);
|
||||||
drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
||||||
|
if (intel_dp->edp_notifier.notifier_call) {
|
||||||
|
unregister_reboot_notifier(&intel_dp->edp_notifier);
|
||||||
|
intel_dp->edp_notifier.notifier_call = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
kfree(intel_dig_port);
|
kfree(intel_dig_port);
|
||||||
}
|
}
|
||||||
@ -4184,6 +4221,11 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|||||||
}
|
}
|
||||||
mutex_unlock(&dev->mode_config.mutex);
|
mutex_unlock(&dev->mode_config.mutex);
|
||||||
|
|
||||||
|
if (IS_VALLEYVIEW(dev)) {
|
||||||
|
intel_dp->edp_notifier.notifier_call = edp_notify_handler;
|
||||||
|
register_reboot_notifier(&intel_dp->edp_notifier);
|
||||||
|
}
|
||||||
|
|
||||||
intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
|
intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
|
||||||
intel_panel_setup_backlight(connector);
|
intel_panel_setup_backlight(connector);
|
||||||
|
|
||||||
|
@ -538,6 +538,8 @@ struct intel_dp {
|
|||||||
unsigned long last_power_on;
|
unsigned long last_power_on;
|
||||||
unsigned long last_backlight_off;
|
unsigned long last_backlight_off;
|
||||||
bool psr_setup_done;
|
bool psr_setup_done;
|
||||||
|
struct notifier_block edp_notifier;
|
||||||
|
|
||||||
bool use_tps3;
|
bool use_tps3;
|
||||||
struct intel_connector *attached_connector;
|
struct intel_connector *attached_connector;
|
||||||
|
|
||||||
|
@ -117,17 +117,18 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder)
|
|||||||
/* bandgap reset is needed after everytime we do power gate */
|
/* bandgap reset is needed after everytime we do power gate */
|
||||||
band_gap_reset(dev_priv);
|
band_gap_reset(dev_priv);
|
||||||
|
|
||||||
|
I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER);
|
||||||
|
usleep_range(2500, 3000);
|
||||||
|
|
||||||
val = I915_READ(MIPI_PORT_CTRL(pipe));
|
val = I915_READ(MIPI_PORT_CTRL(pipe));
|
||||||
I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD);
|
I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD);
|
||||||
usleep_range(1000, 1500);
|
usleep_range(1000, 1500);
|
||||||
I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT);
|
|
||||||
usleep_range(2000, 2500);
|
I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT);
|
||||||
|
usleep_range(2500, 3000);
|
||||||
|
|
||||||
I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
|
I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
|
||||||
usleep_range(2000, 2500);
|
usleep_range(2500, 3000);
|
||||||
I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00);
|
|
||||||
usleep_range(2000, 2500);
|
|
||||||
I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
|
|
||||||
usleep_range(2000, 2500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_dsi_enable(struct intel_encoder *encoder)
|
static void intel_dsi_enable(struct intel_encoder *encoder)
|
||||||
@ -271,23 +272,23 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
|
|||||||
|
|
||||||
DRM_DEBUG_KMS("\n");
|
DRM_DEBUG_KMS("\n");
|
||||||
|
|
||||||
I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER);
|
I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER);
|
||||||
usleep_range(2000, 2500);
|
usleep_range(2000, 2500);
|
||||||
|
|
||||||
I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT);
|
I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT);
|
||||||
usleep_range(2000, 2500);
|
usleep_range(2000, 2500);
|
||||||
|
|
||||||
I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER);
|
I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER);
|
||||||
usleep_range(2000, 2500);
|
usleep_range(2000, 2500);
|
||||||
|
|
||||||
val = I915_READ(MIPI_PORT_CTRL(pipe));
|
|
||||||
I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD);
|
|
||||||
usleep_range(1000, 1500);
|
|
||||||
|
|
||||||
if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT)
|
if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT)
|
||||||
== 0x00000), 30))
|
== 0x00000), 30))
|
||||||
DRM_ERROR("DSI LP not going Low\n");
|
DRM_ERROR("DSI LP not going Low\n");
|
||||||
|
|
||||||
|
val = I915_READ(MIPI_PORT_CTRL(pipe));
|
||||||
|
I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD);
|
||||||
|
usleep_range(1000, 1500);
|
||||||
|
|
||||||
I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00);
|
I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00);
|
||||||
usleep_range(2000, 2500);
|
usleep_range(2000, 2500);
|
||||||
|
|
||||||
|
@ -404,12 +404,6 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs)
|
|||||||
else
|
else
|
||||||
cmd |= DPI_LP_MODE;
|
cmd |= DPI_LP_MODE;
|
||||||
|
|
||||||
/* DPI virtual channel?! */
|
|
||||||
|
|
||||||
mask = DPI_FIFO_EMPTY;
|
|
||||||
if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 50))
|
|
||||||
DRM_ERROR("Timeout waiting for DPI FIFO empty.\n");
|
|
||||||
|
|
||||||
/* clear bit */
|
/* clear bit */
|
||||||
I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT);
|
I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT);
|
||||||
|
|
||||||
|
@ -1118,8 +1118,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!dev_priv->vbt.backlight.present) {
|
if (!dev_priv->vbt.backlight.present) {
|
||||||
DRM_DEBUG_KMS("native backlight control not available per VBT\n");
|
if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
|
||||||
return 0;
|
DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n");
|
||||||
|
} else {
|
||||||
|
DRM_DEBUG_KMS("no backlight present per VBT\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set level and max in panel struct */
|
/* set level and max in panel struct */
|
||||||
|
@ -1516,11 +1516,11 @@ nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch ((ctrl & 0x000f0000) >> 16) {
|
switch ((ctrl & 0x000f0000) >> 16) {
|
||||||
case 6: datarate = pclk * 30 / 8; break;
|
case 6: datarate = pclk * 30; break;
|
||||||
case 5: datarate = pclk * 24 / 8; break;
|
case 5: datarate = pclk * 24; break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
datarate = pclk * 18 / 8;
|
datarate = pclk * 18;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1159,11 +1159,11 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
|
|||||||
if (outp->info.type == DCB_OUTPUT_DP) {
|
if (outp->info.type == DCB_OUTPUT_DP) {
|
||||||
u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300));
|
u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300));
|
||||||
switch ((sync & 0x000003c0) >> 6) {
|
switch ((sync & 0x000003c0) >> 6) {
|
||||||
case 6: pclk = pclk * 30 / 8; break;
|
case 6: pclk = pclk * 30; break;
|
||||||
case 5: pclk = pclk * 24 / 8; break;
|
case 5: pclk = pclk * 24; break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
pclk = pclk * 18 / 8;
|
pclk = pclk * 18;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
|
|||||||
struct nvkm_output_dp *outp = (void *)base;
|
struct nvkm_output_dp *outp = (void *)base;
|
||||||
bool retrain = true;
|
bool retrain = true;
|
||||||
u8 link[2], stat[3];
|
u8 link[2], stat[3];
|
||||||
u32 rate;
|
u32 linkrate;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
/* check that the link is trained at a high enough rate */
|
/* check that the link is trained at a high enough rate */
|
||||||
@ -44,8 +44,10 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
rate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET);
|
linkrate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET);
|
||||||
if (rate < ((datarate / 8) * 10)) {
|
linkrate = (linkrate * 8) / 10; /* 8B/10B coding overhead */
|
||||||
|
datarate = (datarate + 9) / 10; /* -> decakilobits */
|
||||||
|
if (linkrate < datarate) {
|
||||||
DBG("link not trained at sufficient rate\n");
|
DBG("link not trained at sufficient rate\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,7 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size)
|
|||||||
struct nvkm_output_dp *outpdp = (void *)outp;
|
struct nvkm_output_dp *outpdp = (void *)outp;
|
||||||
switch (data) {
|
switch (data) {
|
||||||
case NV94_DISP_SOR_DP_PWR_STATE_OFF:
|
case NV94_DISP_SOR_DP_PWR_STATE_OFF:
|
||||||
|
nouveau_event_put(outpdp->irq);
|
||||||
((struct nvkm_output_dp_impl *)nv_oclass(outp))
|
((struct nvkm_output_dp_impl *)nv_oclass(outp))
|
||||||
->lnk_pwr(outpdp, 0);
|
->lnk_pwr(outpdp, 0);
|
||||||
atomic_set(&outpdp->lt.done, 0);
|
atomic_set(&outpdp->lt.done, 0);
|
||||||
|
@ -26,7 +26,7 @@ ramfuc_reg2(u32 addr1, u32 addr2)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct ramfuc_reg
|
static noinline struct ramfuc_reg
|
||||||
ramfuc_reg(u32 addr)
|
ramfuc_reg(u32 addr)
|
||||||
{
|
{
|
||||||
return ramfuc_reg2(addr, addr);
|
return ramfuc_reg2(addr, addr);
|
||||||
@ -107,7 +107,7 @@ ramfuc_nsec(struct ramfuc *ram, u32 nsec)
|
|||||||
|
|
||||||
#define ram_init(s,p) ramfuc_init(&(s)->base, (p))
|
#define ram_init(s,p) ramfuc_init(&(s)->base, (p))
|
||||||
#define ram_exec(s,e) ramfuc_exec(&(s)->base, (e))
|
#define ram_exec(s,e) ramfuc_exec(&(s)->base, (e))
|
||||||
#define ram_have(s,r) ((s)->r_##r.addr != 0x000000)
|
#define ram_have(s,r) ((s)->r_##r.addr[0] != 0x000000)
|
||||||
#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r)
|
#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r)
|
||||||
#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
|
#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
|
||||||
#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r)
|
#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r)
|
||||||
|
@ -200,6 +200,7 @@ r1373f4_init(struct nve0_ramfuc *fuc)
|
|||||||
/* (re)program mempll, if required */
|
/* (re)program mempll, if required */
|
||||||
if (ram->mode == 2) {
|
if (ram->mode == 2) {
|
||||||
ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
|
ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
|
||||||
|
ram_mask(fuc, 0x132000, 0x80000000, 0x80000000);
|
||||||
ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
|
ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
|
||||||
ram_mask(fuc, 0x132004, 0x103fffff, mcoef);
|
ram_mask(fuc, 0x132004, 0x103fffff, mcoef);
|
||||||
ram_mask(fuc, 0x132000, 0x00000001, 0x00000001);
|
ram_mask(fuc, 0x132000, 0x00000001, 0x00000001);
|
||||||
|
@ -652,12 +652,12 @@ int nouveau_pmops_resume(struct device *dev)
|
|||||||
ret = nouveau_do_resume(drm_dev);
|
ret = nouveau_do_resume(drm_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (drm_dev->mode_config.num_crtc)
|
|
||||||
nouveau_fbcon_set_suspend(drm_dev, 0);
|
|
||||||
|
|
||||||
nouveau_fbcon_zfill_all(drm_dev);
|
if (drm_dev->mode_config.num_crtc) {
|
||||||
if (drm_dev->mode_config.num_crtc)
|
|
||||||
nouveau_display_resume(drm_dev);
|
nouveau_display_resume(drm_dev);
|
||||||
|
nouveau_fbcon_set_suspend(drm_dev, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,11 +683,12 @@ static int nouveau_pmops_thaw(struct device *dev)
|
|||||||
ret = nouveau_do_resume(drm_dev);
|
ret = nouveau_do_resume(drm_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (drm_dev->mode_config.num_crtc)
|
|
||||||
nouveau_fbcon_set_suspend(drm_dev, 0);
|
if (drm_dev->mode_config.num_crtc) {
|
||||||
nouveau_fbcon_zfill_all(drm_dev);
|
|
||||||
if (drm_dev->mode_config.num_crtc)
|
|
||||||
nouveau_display_resume(drm_dev);
|
nouveau_display_resume(drm_dev);
|
||||||
|
nouveau_fbcon_set_suspend(drm_dev, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,17 +531,10 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
|
|||||||
if (state == 1)
|
if (state == 1)
|
||||||
nouveau_fbcon_save_disable_accel(dev);
|
nouveau_fbcon_save_disable_accel(dev);
|
||||||
fb_set_suspend(drm->fbcon->helper.fbdev, state);
|
fb_set_suspend(drm->fbcon->helper.fbdev, state);
|
||||||
if (state == 0)
|
if (state == 0) {
|
||||||
nouveau_fbcon_restore_accel(dev);
|
nouveau_fbcon_restore_accel(dev);
|
||||||
|
nouveau_fbcon_zfill(dev, drm->fbcon);
|
||||||
|
}
|
||||||
console_unlock();
|
console_unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nouveau_fbcon_zfill_all(struct drm_device *dev)
|
|
||||||
{
|
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
|
||||||
if (drm->fbcon) {
|
|
||||||
nouveau_fbcon_zfill(dev, drm->fbcon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -61,7 +61,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info);
|
|||||||
int nouveau_fbcon_init(struct drm_device *dev);
|
int nouveau_fbcon_init(struct drm_device *dev);
|
||||||
void nouveau_fbcon_fini(struct drm_device *dev);
|
void nouveau_fbcon_fini(struct drm_device *dev);
|
||||||
void nouveau_fbcon_set_suspend(struct drm_device *dev, int state);
|
void nouveau_fbcon_set_suspend(struct drm_device *dev, int state);
|
||||||
void nouveau_fbcon_zfill_all(struct drm_device *dev);
|
|
||||||
void nouveau_fbcon_save_disable_accel(struct drm_device *dev);
|
void nouveau_fbcon_save_disable_accel(struct drm_device *dev);
|
||||||
void nouveau_fbcon_restore_accel(struct drm_device *dev);
|
void nouveau_fbcon_restore_accel(struct drm_device *dev);
|
||||||
|
|
||||||
|
@ -1741,7 +1741,8 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mthd = (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2;
|
mthd = (ffs(nv_encoder->dcb->heads) - 1) << 3;
|
||||||
|
mthd |= (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2;
|
||||||
mthd |= nv_encoder->or;
|
mthd |= nv_encoder->or;
|
||||||
|
|
||||||
if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
|
if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
|
||||||
|
@ -127,7 +127,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
|
|||||||
/* flags not zero */
|
/* flags not zero */
|
||||||
if (args.v1.ucReplyStatus == 2) {
|
if (args.v1.ucReplyStatus == 2) {
|
||||||
DRM_DEBUG_KMS("dp_aux_ch flags not zero\n");
|
DRM_DEBUG_KMS("dp_aux_ch flags not zero\n");
|
||||||
r = -EBUSY;
|
r = -EIO;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1179,7 +1179,7 @@ static int ci_stop_dpm(struct radeon_device *rdev)
|
|||||||
tmp &= ~GLOBAL_PWRMGT_EN;
|
tmp &= ~GLOBAL_PWRMGT_EN;
|
||||||
WREG32_SMC(GENERAL_PWRMGT, tmp);
|
WREG32_SMC(GENERAL_PWRMGT, tmp);
|
||||||
|
|
||||||
tmp = RREG32(SCLK_PWRMGT_CNTL);
|
tmp = RREG32_SMC(SCLK_PWRMGT_CNTL);
|
||||||
tmp &= ~DYNAMIC_PM_EN;
|
tmp &= ~DYNAMIC_PM_EN;
|
||||||
WREG32_SMC(SCLK_PWRMGT_CNTL, tmp);
|
WREG32_SMC(SCLK_PWRMGT_CNTL, tmp);
|
||||||
|
|
||||||
|
@ -7676,14 +7676,16 @@ restart_ih:
|
|||||||
addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
|
addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
|
||||||
status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
|
status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
|
||||||
mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT);
|
mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT);
|
||||||
|
/* reset addr and status */
|
||||||
|
WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
|
||||||
|
if (addr == 0x0 && status == 0x0)
|
||||||
|
break;
|
||||||
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
|
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
|
||||||
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
|
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
|
||||||
addr);
|
addr);
|
||||||
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
|
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
|
||||||
status);
|
status);
|
||||||
cik_vm_decode_fault(rdev, status, addr, mc_client);
|
cik_vm_decode_fault(rdev, status, addr, mc_client);
|
||||||
/* reset addr and status */
|
|
||||||
WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
|
|
||||||
break;
|
break;
|
||||||
case 167: /* VCE */
|
case 167: /* VCE */
|
||||||
DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data);
|
DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data);
|
||||||
|
@ -189,7 +189,7 @@ static const u32 evergreen_golden_registers[] =
|
|||||||
0x8c1c, 0xffffffff, 0x00001010,
|
0x8c1c, 0xffffffff, 0x00001010,
|
||||||
0x28350, 0xffffffff, 0x00000000,
|
0x28350, 0xffffffff, 0x00000000,
|
||||||
0xa008, 0xffffffff, 0x00010000,
|
0xa008, 0xffffffff, 0x00010000,
|
||||||
0x5cc, 0xffffffff, 0x00000001,
|
0x5c4, 0xffffffff, 0x00000001,
|
||||||
0x9508, 0xffffffff, 0x00000002,
|
0x9508, 0xffffffff, 0x00000002,
|
||||||
0x913c, 0x0000000f, 0x0000000a
|
0x913c, 0x0000000f, 0x0000000a
|
||||||
};
|
};
|
||||||
@ -476,7 +476,7 @@ static const u32 cedar_golden_registers[] =
|
|||||||
0x8c1c, 0xffffffff, 0x00001010,
|
0x8c1c, 0xffffffff, 0x00001010,
|
||||||
0x28350, 0xffffffff, 0x00000000,
|
0x28350, 0xffffffff, 0x00000000,
|
||||||
0xa008, 0xffffffff, 0x00010000,
|
0xa008, 0xffffffff, 0x00010000,
|
||||||
0x5cc, 0xffffffff, 0x00000001,
|
0x5c4, 0xffffffff, 0x00000001,
|
||||||
0x9508, 0xffffffff, 0x00000002
|
0x9508, 0xffffffff, 0x00000002
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -635,7 +635,7 @@ static const u32 juniper_mgcg_init[] =
|
|||||||
static const u32 supersumo_golden_registers[] =
|
static const u32 supersumo_golden_registers[] =
|
||||||
{
|
{
|
||||||
0x5eb4, 0xffffffff, 0x00000002,
|
0x5eb4, 0xffffffff, 0x00000002,
|
||||||
0x5cc, 0xffffffff, 0x00000001,
|
0x5c4, 0xffffffff, 0x00000001,
|
||||||
0x7030, 0xffffffff, 0x00000011,
|
0x7030, 0xffffffff, 0x00000011,
|
||||||
0x7c30, 0xffffffff, 0x00000011,
|
0x7c30, 0xffffffff, 0x00000011,
|
||||||
0x6104, 0x01000300, 0x00000000,
|
0x6104, 0x01000300, 0x00000000,
|
||||||
@ -719,7 +719,7 @@ static const u32 sumo_golden_registers[] =
|
|||||||
static const u32 wrestler_golden_registers[] =
|
static const u32 wrestler_golden_registers[] =
|
||||||
{
|
{
|
||||||
0x5eb4, 0xffffffff, 0x00000002,
|
0x5eb4, 0xffffffff, 0x00000002,
|
||||||
0x5cc, 0xffffffff, 0x00000001,
|
0x5c4, 0xffffffff, 0x00000001,
|
||||||
0x7030, 0xffffffff, 0x00000011,
|
0x7030, 0xffffffff, 0x00000011,
|
||||||
0x7c30, 0xffffffff, 0x00000011,
|
0x7c30, 0xffffffff, 0x00000011,
|
||||||
0x6104, 0x01000300, 0x00000000,
|
0x6104, 0x01000300, 0x00000000,
|
||||||
@ -5066,14 +5066,16 @@ restart_ih:
|
|||||||
case 147:
|
case 147:
|
||||||
addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
|
addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
|
||||||
status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
|
status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
|
||||||
|
/* reset addr and status */
|
||||||
|
WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
|
||||||
|
if (addr == 0x0 && status == 0x0)
|
||||||
|
break;
|
||||||
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
|
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
|
||||||
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
|
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
|
||||||
addr);
|
addr);
|
||||||
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
|
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
|
||||||
status);
|
status);
|
||||||
cayman_vm_decode_fault(rdev, status, addr);
|
cayman_vm_decode_fault(rdev, status, addr);
|
||||||
/* reset addr and status */
|
|
||||||
WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
|
|
||||||
break;
|
break;
|
||||||
case 176: /* CP_INT in ring buffer */
|
case 176: /* CP_INT in ring buffer */
|
||||||
case 177: /* CP_INT in IB1 */
|
case 177: /* CP_INT in IB1 */
|
||||||
|
@ -2329,12 +2329,6 @@ void rv770_get_engine_memory_ss(struct radeon_device *rdev)
|
|||||||
pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
|
pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
|
||||||
ASIC_INTERNAL_MEMORY_SS, 0);
|
ASIC_INTERNAL_MEMORY_SS, 0);
|
||||||
|
|
||||||
/* disable ss, causes hangs on some cayman boards */
|
|
||||||
if (rdev->family == CHIP_CAYMAN) {
|
|
||||||
pi->sclk_ss = false;
|
|
||||||
pi->mclk_ss = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pi->sclk_ss || pi->mclk_ss)
|
if (pi->sclk_ss || pi->mclk_ss)
|
||||||
pi->dynamic_ss = true;
|
pi->dynamic_ss = true;
|
||||||
else
|
else
|
||||||
|
@ -6376,14 +6376,16 @@ restart_ih:
|
|||||||
case 147:
|
case 147:
|
||||||
addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
|
addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
|
||||||
status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
|
status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
|
||||||
|
/* reset addr and status */
|
||||||
|
WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
|
||||||
|
if (addr == 0x0 && status == 0x0)
|
||||||
|
break;
|
||||||
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
|
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
|
||||||
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
|
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
|
||||||
addr);
|
addr);
|
||||||
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
|
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
|
||||||
status);
|
status);
|
||||||
si_vm_decode_fault(rdev, status, addr);
|
si_vm_decode_fault(rdev, status, addr);
|
||||||
/* reset addr and status */
|
|
||||||
WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
|
|
||||||
break;
|
break;
|
||||||
case 176: /* RINGID0 CP_INT */
|
case 176: /* RINGID0 CP_INT */
|
||||||
radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
|
radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
|
||||||
|
Loading…
Reference in New Issue
Block a user