Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "Nothing too crazy.

  Radeon irq fixes, i915 regression fixes, exynos fixes, tda998x chip
  fixes, and a bunch of msm fixes"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (31 commits)
  drm/i915: Pair va_copy with va_end in i915_error_vprintf
  drm/i915: Fix intel_pipe_to_cpu_transcoder for UMS
  drm/i915: Disable dp aux irq on g4x
  drm/msm: bigger synchronization hammer
  drm/exynos: Convert to use the standard hdmi.h header
  drm/exynos: Fix trivial typo
  drm/exynos: Remove unnecessary semicolon
  drm/exynos: Fix multiplatform breakage for ipp/gsc
  drm/exynos: Fix freeing issues in exynos_drm_drv.c
  drm/radeon: add missing include in btc_dpm.c
  drm/radeon/dpm: fix uninitialized read from stack in kv_dpm_late_enable
  drm/radeon: remove useless return
  drm/radeon/dpm: use stored max_vddc rather than looking it up
  drm/radeon/dpm: use the driver state for dpm debugfs
  drm/radeon: fix UVD IRQ support on 7xx
  drm/radeon: fix UVD IRQ support on SI
  drm/msm: fix deadlock in bo create fail path
  drm/msm/mdp4: cursor fixes
  drm/msm/mdp4: pageflip fixes
  drm/msm/mdp5: fix ref leaks in error paths
  ...
This commit is contained in:
Linus Torvalds 2014-02-12 09:02:49 -08:00
commit 641f832c73
33 changed files with 270 additions and 161 deletions

View File

@ -2857,7 +2857,7 @@ M: Jani Nikula <jani.nikula@linux.intel.com>
L: intel-gfx@lists.freedesktop.org L: intel-gfx@lists.freedesktop.org
L: dri-devel@lists.freedesktop.org L: dri-devel@lists.freedesktop.org
Q: http://patchwork.freedesktop.org/project/intel-gfx/ Q: http://patchwork.freedesktop.org/project/intel-gfx/
T: git git://people.freedesktop.org/~danvet/drm-intel T: git git://anongit.freedesktop.org/drm-intel
S: Supported S: Supported
F: drivers/gpu/drm/i915/ F: drivers/gpu/drm/i915/
F: include/drm/i915* F: include/drm/i915*

View File

@ -51,7 +51,7 @@ config DRM_EXYNOS_G2D
config DRM_EXYNOS_IPP config DRM_EXYNOS_IPP
bool "Exynos DRM IPP" bool "Exynos DRM IPP"
depends on DRM_EXYNOS && !ARCH_MULTIPLATFORM depends on DRM_EXYNOS
help help
Choose this option if you want to use IPP feature for DRM. Choose this option if you want to use IPP feature for DRM.
@ -69,6 +69,6 @@ config DRM_EXYNOS_ROTATOR
config DRM_EXYNOS_GSC config DRM_EXYNOS_GSC
bool "Exynos DRM GSC" bool "Exynos DRM GSC"
depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !ARCH_MULTIPLATFORM
help help
Choose this option if you want to use Exynos GSC for DRM. Choose this option if you want to use Exynos GSC for DRM.

View File

@ -171,21 +171,23 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
file->driver_priv = file_priv; file->driver_priv = file_priv;
ret = exynos_drm_subdrv_open(dev, file); ret = exynos_drm_subdrv_open(dev, file);
if (ret) { if (ret)
kfree(file_priv); goto out;
file->driver_priv = NULL;
}
anon_filp = anon_inode_getfile("exynos_gem", &exynos_drm_gem_fops, anon_filp = anon_inode_getfile("exynos_gem", &exynos_drm_gem_fops,
NULL, 0); NULL, 0);
if (IS_ERR(anon_filp)) { if (IS_ERR(anon_filp)) {
kfree(file_priv); ret = PTR_ERR(anon_filp);
return PTR_ERR(anon_filp); goto out;
} }
anon_filp->f_mode = FMODE_READ | FMODE_WRITE; anon_filp->f_mode = FMODE_READ | FMODE_WRITE;
file_priv->anon_filp = anon_filp; file_priv->anon_filp = anon_filp;
return ret;
out:
kfree(file_priv);
file->driver_priv = NULL;
return ret; return ret;
} }

View File

@ -607,7 +607,7 @@ static enum g2d_reg_type g2d_get_reg_type(int reg_offset)
reg_type = REG_TYPE_NONE; reg_type = REG_TYPE_NONE;
DRM_ERROR("Unknown register offset![%d]\n", reg_offset); DRM_ERROR("Unknown register offset![%d]\n", reg_offset);
break; break;
}; }
return reg_type; return reg_type;
} }

View File

@ -16,7 +16,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <plat/map-base.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/exynos_drm.h> #include <drm/exynos_drm.h>
@ -826,7 +825,7 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node,
DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e); DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e);
/* /*
* quf == NULL condition means all event deletion. * qbuf == NULL condition means all event deletion.
* stop operations want to delete all event list. * stop operations want to delete all event list.
* another case delete only same buf id. * another case delete only same buf id.
*/ */

View File

@ -34,6 +34,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/hdmi.h>
#include <drm/exynos_drm.h> #include <drm/exynos_drm.h>
@ -59,19 +60,6 @@
#define HDMI_AUI_VERSION 0x01 #define HDMI_AUI_VERSION 0x01
#define HDMI_AUI_LENGTH 0x0A #define HDMI_AUI_LENGTH 0x0A
/* HDMI infoframe to configure HDMI out packet header, AUI and AVI */
enum HDMI_PACKET_TYPE {
/* refer to Table 5-8 Packet Type in HDMI specification v1.4a */
/* InfoFrame packet type */
HDMI_PACKET_TYPE_INFOFRAME = 0x80,
/* Vendor-Specific InfoFrame */
HDMI_PACKET_TYPE_VSI = HDMI_PACKET_TYPE_INFOFRAME + 1,
/* Auxiliary Video information InfoFrame */
HDMI_PACKET_TYPE_AVI = HDMI_PACKET_TYPE_INFOFRAME + 2,
/* Audio information InfoFrame */
HDMI_PACKET_TYPE_AUI = HDMI_PACKET_TYPE_INFOFRAME + 4
};
enum hdmi_type { enum hdmi_type {
HDMI_TYPE13, HDMI_TYPE13,
HDMI_TYPE14, HDMI_TYPE14,
@ -379,12 +367,6 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = {
}, },
}; };
struct hdmi_infoframe {
enum HDMI_PACKET_TYPE type;
u8 ver;
u8 len;
};
static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
{ {
return readl(hdata->regs + reg_id); return readl(hdata->regs + reg_id);
@ -682,7 +664,7 @@ static u8 hdmi_chksum(struct hdmi_context *hdata,
} }
static void hdmi_reg_infoframe(struct hdmi_context *hdata, static void hdmi_reg_infoframe(struct hdmi_context *hdata,
struct hdmi_infoframe *infoframe) union hdmi_infoframe *infoframe)
{ {
u32 hdr_sum; u32 hdr_sum;
u8 chksum; u8 chksum;
@ -700,13 +682,15 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata,
return; return;
} }
switch (infoframe->type) { switch (infoframe->any.type) {
case HDMI_PACKET_TYPE_AVI: case HDMI_INFOFRAME_TYPE_AVI:
hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC); hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->type); hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type);
hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1, infoframe->ver); hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1,
hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->len); infoframe->any.version);
hdr_sum = infoframe->type + infoframe->ver + infoframe->len; hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length);
hdr_sum = infoframe->any.type + infoframe->any.version +
infoframe->any.length;
/* Output format zero hardcoded ,RGB YBCR selection */ /* Output format zero hardcoded ,RGB YBCR selection */
hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 |
@ -722,18 +706,20 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata,
hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic); hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic);
chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1), chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
infoframe->len, hdr_sum); infoframe->any.length, hdr_sum);
DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum); DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum);
hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum); hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum);
break; break;
case HDMI_PACKET_TYPE_AUI: case HDMI_INFOFRAME_TYPE_AUDIO:
hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02); hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02);
hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->type); hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type);
hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1, infoframe->ver); hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1,
hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->len); infoframe->any.version);
hdr_sum = infoframe->type + infoframe->ver + infoframe->len; hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length);
hdr_sum = infoframe->any.type + infoframe->any.version +
infoframe->any.length;
chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1), chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1),
infoframe->len, hdr_sum); infoframe->any.length, hdr_sum);
DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum); DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum);
hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum); hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum);
break; break;
@ -985,7 +971,7 @@ static void hdmi_conf_reset(struct hdmi_context *hdata)
static void hdmi_conf_init(struct hdmi_context *hdata) static void hdmi_conf_init(struct hdmi_context *hdata)
{ {
struct hdmi_infoframe infoframe; union hdmi_infoframe infoframe;
/* disable HPD interrupts from HDMI IP block, use GPIO instead */ /* disable HPD interrupts from HDMI IP block, use GPIO instead */
hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
@ -1021,14 +1007,14 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
} else { } else {
infoframe.type = HDMI_PACKET_TYPE_AVI; infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI;
infoframe.ver = HDMI_AVI_VERSION; infoframe.any.version = HDMI_AVI_VERSION;
infoframe.len = HDMI_AVI_LENGTH; infoframe.any.length = HDMI_AVI_LENGTH;
hdmi_reg_infoframe(hdata, &infoframe); hdmi_reg_infoframe(hdata, &infoframe);
infoframe.type = HDMI_PACKET_TYPE_AUI; infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO;
infoframe.ver = HDMI_AUI_VERSION; infoframe.any.version = HDMI_AUI_VERSION;
infoframe.len = HDMI_AUI_LENGTH; infoframe.any.length = HDMI_AUI_LENGTH;
hdmi_reg_infoframe(hdata, &infoframe); hdmi_reg_infoframe(hdata, &infoframe);
/* enable AVI packet every vsync, fixes purple line problem */ /* enable AVI packet every vsync, fixes purple line problem */

View File

@ -208,7 +208,7 @@ struct tda998x_priv {
# define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1) # define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1)
# define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6) # define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6)
#define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */ #define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */
# define PLL_SERIAL_2_SRL_NOSC(x) (((x) & 3) << 0) # define PLL_SERIAL_2_SRL_NOSC(x) ((x) << 0)
# define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4) # define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4)
#define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */ #define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */
# define PLL_SERIAL_3_SRL_CCIR (1 << 0) # define PLL_SERIAL_3_SRL_CCIR (1 << 0)
@ -528,10 +528,10 @@ tda998x_write_aif(struct drm_encoder *encoder, struct tda998x_encoder_params *p)
{ {
uint8_t buf[PB(5) + 1]; uint8_t buf[PB(5) + 1];
memset(buf, 0, sizeof(buf));
buf[HB(0)] = 0x84; buf[HB(0)] = 0x84;
buf[HB(1)] = 0x01; buf[HB(1)] = 0x01;
buf[HB(2)] = 10; buf[HB(2)] = 10;
buf[PB(0)] = 0;
buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */ buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */
buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */ buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */
buf[PB(4)] = p->audio_frame[4]; buf[PB(4)] = p->audio_frame[4];
@ -824,6 +824,11 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
} }
div = 148500 / mode->clock; div = 148500 / mode->clock;
if (div != 0) {
div--;
if (div > 3)
div = 3;
}
/* mute the audio FIFO: */ /* mute the audio FIFO: */
reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
@ -913,7 +918,7 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
if (priv->rev == TDA19988) { if (priv->rev == TDA19988) {
/* let incoming pixels fill the active space (if any) */ /* let incoming pixels fill the active space (if any) */
reg_write(encoder, REG_ENABLE_SPACE, 0x01); reg_write(encoder, REG_ENABLE_SPACE, 0x00);
} }
/* must be last register set: */ /* must be last register set: */
@ -1094,6 +1099,8 @@ tda998x_encoder_destroy(struct drm_encoder *encoder)
{ {
struct tda998x_priv *priv = to_tda998x_priv(encoder); struct tda998x_priv *priv = to_tda998x_priv(encoder);
drm_i2c_encoder_destroy(encoder); drm_i2c_encoder_destroy(encoder);
if (priv->cec)
i2c_unregister_device(priv->cec);
kfree(priv); kfree(priv);
} }
@ -1142,8 +1149,10 @@ tda998x_encoder_init(struct i2c_client *client,
priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1);
priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5);
priv->current_page = 0; priv->current_page = 0xff;
priv->cec = i2c_new_dummy(client->adapter, 0x34); priv->cec = i2c_new_dummy(client->adapter, 0x34);
if (!priv->cec)
return -ENODEV;
priv->dpms = DRM_MODE_DPMS_OFF; priv->dpms = DRM_MODE_DPMS_OFF;
encoder_slave->slave_priv = priv; encoder_slave->slave_priv = priv;

View File

@ -1831,6 +1831,14 @@ struct drm_i915_file_private {
/* Early gen2 have a totally busted CS tlb and require pinned batches. */ /* Early gen2 have a totally busted CS tlb and require pinned batches. */
#define HAS_BROKEN_CS_TLB(dev) (IS_I830(dev) || IS_845G(dev)) #define HAS_BROKEN_CS_TLB(dev) (IS_I830(dev) || IS_845G(dev))
/*
* dp aux and gmbus irq on gen4 seems to be able to generate legacy interrupts
* even when in MSI mode. This results in spurious interrupt warnings if the
* legacy irq no. is shared with another device. The kernel then disables that
* interrupt source and so prevents the other device from working properly.
*/
#define HAS_AUX_IRQ(dev) (INTEL_INFO(dev)->gen >= 5)
#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5)
/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
* rows, which changed the alignment requirements and fence programming. * rows, which changed the alignment requirements and fence programming.

View File

@ -146,7 +146,10 @@ static void i915_error_vprintf(struct drm_i915_error_state_buf *e,
va_list tmp; va_list tmp;
va_copy(tmp, args); va_copy(tmp, args);
if (!__i915_error_seek(e, vsnprintf(NULL, 0, f, tmp))) len = vsnprintf(NULL, 0, f, tmp);
va_end(tmp);
if (!__i915_error_seek(e, len))
return; return;
} }

View File

@ -567,8 +567,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
vbl_start = mode->crtc_vblank_start * mode->crtc_htotal; vbl_start = mode->crtc_vblank_start * mode->crtc_htotal;
} else { } else {
enum transcoder cpu_transcoder = enum transcoder cpu_transcoder = (enum transcoder) pipe;
intel_pipe_to_cpu_transcoder(dev_priv, pipe);
u32 htotal; u32 htotal;
htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1; htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1;

View File

@ -404,7 +404,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
int i, ret, recv_bytes; int i, ret, recv_bytes;
uint32_t status; uint32_t status;
int try, precharge, clock = 0; int try, precharge, clock = 0;
bool has_aux_irq = true; bool has_aux_irq = HAS_AUX_IRQ(dev);
uint32_t timeout; uint32_t timeout;
/* dp aux is extremely sensitive to irq latency, hence request the /* dp aux is extremely sensitive to irq latency, hence request the
@ -1869,10 +1869,12 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
mutex_unlock(&dev_priv->dpio_lock); mutex_unlock(&dev_priv->dpio_lock);
/* init power sequencer on this pipe and port */ if (is_edp(intel_dp)) {
intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); /* init power sequencer on this pipe and port */
intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);
&power_seq); intel_dp_init_panel_power_sequencer_registers(dev, intel_dp,
&power_seq);
}
intel_enable_dp(encoder); intel_enable_dp(encoder);

View File

@ -258,13 +258,6 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
algo->data = bus; algo->data = bus;
} }
/*
* gmbus on gen4 seems to be able to generate legacy interrupts even when in MSI
* mode. This results in spurious interrupt warnings if the legacy irq no. is
* shared with another device. The kernel then disables that interrupt source
* and so prevents the other device from working properly.
*/
#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5)
static int static int
gmbus_wait_hw_status(struct drm_i915_private *dev_priv, gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
u32 gmbus2_status, u32 gmbus2_status,

View File

@ -226,6 +226,8 @@ struct opregion_asle {
#define ACPI_DIGITAL_OUTPUT (3<<8) #define ACPI_DIGITAL_OUTPUT (3<<8)
#define ACPI_LVDS_OUTPUT (4<<8) #define ACPI_LVDS_OUTPUT (4<<8)
#define MAX_DSLP 1500
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
{ {
@ -260,10 +262,11 @@ static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
/* The spec says 2ms should be the default, but it's too small /* The spec says 2ms should be the default, but it's too small
* for some machines. */ * for some machines. */
dslp = 50; dslp = 50;
} else if (dslp > 500) { } else if (dslp > MAX_DSLP) {
/* Hey bios, trust must be earned. */ /* Hey bios, trust must be earned. */
WARN_ONCE(1, "excessive driver sleep timeout (DSPL) %u\n", dslp); DRM_INFO_ONCE("ACPI BIOS requests an excessive sleep of %u ms, "
dslp = 500; "using %u ms instead\n", dslp, MAX_DSLP);
dslp = MAX_DSLP;
} }
/* The spec tells us to do this, but we are the only user... */ /* The spec tells us to do this, but we are the only user... */

View File

@ -39,6 +39,7 @@ struct mdp4_crtc {
spinlock_t lock; spinlock_t lock;
bool stale; bool stale;
uint32_t width, height; uint32_t width, height;
uint32_t x, y;
/* next cursor to scan-out: */ /* next cursor to scan-out: */
uint32_t next_iova; uint32_t next_iova;
@ -57,9 +58,16 @@ struct mdp4_crtc {
#define PENDING_FLIP 0x2 #define PENDING_FLIP 0x2
atomic_t pending; atomic_t pending;
/* the fb that we currently hold a scanout ref to: */ /* the fb that we logically (from PoV of KMS API) hold a ref
* to. Which we may not yet be scanning out (we may still
* be scanning out previous in case of page_flip while waiting
* for gpu rendering to complete:
*/
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
/* the fb that we currently hold a scanout ref to: */
struct drm_framebuffer *scanout_fb;
/* for unref'ing framebuffers after scanout completes: */ /* for unref'ing framebuffers after scanout completes: */
struct drm_flip_work unref_fb_work; struct drm_flip_work unref_fb_work;
@ -77,24 +85,73 @@ static struct mdp4_kms *get_kms(struct drm_crtc *crtc)
return to_mdp4_kms(to_mdp_kms(priv->kms)); return to_mdp4_kms(to_mdp_kms(priv->kms));
} }
static void update_fb(struct drm_crtc *crtc, bool async, static void request_pending(struct drm_crtc *crtc, uint32_t pending)
struct drm_framebuffer *new_fb) {
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
atomic_or(pending, &mdp4_crtc->pending);
mdp_irq_register(&get_kms(crtc)->base, &mdp4_crtc->vblank);
}
static void crtc_flush(struct drm_crtc *crtc)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc);
uint32_t i, flush = 0;
for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) {
struct drm_plane *plane = mdp4_crtc->planes[i];
if (plane) {
enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
flush |= pipe2flush(pipe_id);
}
}
flush |= ovlp2flush(mdp4_crtc->ovlp);
DBG("%s: flush=%08x", mdp4_crtc->name, flush);
mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush);
}
static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb)
{ {
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct drm_framebuffer *old_fb = mdp4_crtc->fb; struct drm_framebuffer *old_fb = mdp4_crtc->fb;
if (old_fb)
drm_flip_work_queue(&mdp4_crtc->unref_fb_work, old_fb);
/* grab reference to incoming scanout fb: */ /* grab reference to incoming scanout fb: */
drm_framebuffer_reference(new_fb); drm_framebuffer_reference(new_fb);
mdp4_crtc->base.fb = new_fb; mdp4_crtc->base.fb = new_fb;
mdp4_crtc->fb = new_fb; mdp4_crtc->fb = new_fb;
if (!async) { if (old_fb)
/* enable vblank to pick up the old_fb */ drm_flip_work_queue(&mdp4_crtc->unref_fb_work, old_fb);
mdp_irq_register(&get_kms(crtc)->base, &mdp4_crtc->vblank); }
}
/* unlike update_fb(), take a ref to the new scanout fb *before* updating
* plane, then call this. Needed to ensure we don't unref the buffer that
* is actually still being scanned out.
*
* Note that this whole thing goes away with atomic.. since we can defer
* calling into driver until rendering is done.
*/
static void update_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
/* flush updates, to make sure hw is updated to new scanout fb,
* so that we can safely queue unref to current fb (ie. next
* vblank we know hw is done w/ previous scanout_fb).
*/
crtc_flush(crtc);
if (mdp4_crtc->scanout_fb)
drm_flip_work_queue(&mdp4_crtc->unref_fb_work,
mdp4_crtc->scanout_fb);
mdp4_crtc->scanout_fb = fb;
/* enable vblank to complete flip: */
request_pending(crtc, PENDING_FLIP);
} }
/* if file!=NULL, this is preclose potential cancel-flip path */ /* if file!=NULL, this is preclose potential cancel-flip path */
@ -120,34 +177,6 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file)
spin_unlock_irqrestore(&dev->event_lock, flags); spin_unlock_irqrestore(&dev->event_lock, flags);
} }
static void crtc_flush(struct drm_crtc *crtc)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc);
uint32_t i, flush = 0;
for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) {
struct drm_plane *plane = mdp4_crtc->planes[i];
if (plane) {
enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
flush |= pipe2flush(pipe_id);
}
}
flush |= ovlp2flush(mdp4_crtc->ovlp);
DBG("%s: flush=%08x", mdp4_crtc->name, flush);
mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush);
}
static void request_pending(struct drm_crtc *crtc, uint32_t pending)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
atomic_or(pending, &mdp4_crtc->pending);
mdp_irq_register(&get_kms(crtc)->base, &mdp4_crtc->vblank);
}
static void pageflip_cb(struct msm_fence_cb *cb) static void pageflip_cb(struct msm_fence_cb *cb)
{ {
struct mdp4_crtc *mdp4_crtc = struct mdp4_crtc *mdp4_crtc =
@ -158,11 +187,9 @@ static void pageflip_cb(struct msm_fence_cb *cb)
if (!fb) if (!fb)
return; return;
drm_framebuffer_reference(fb);
mdp4_plane_set_scanout(mdp4_crtc->plane, fb); mdp4_plane_set_scanout(mdp4_crtc->plane, fb);
crtc_flush(crtc); update_scanout(crtc, fb);
/* enable vblank to complete flip: */
request_pending(crtc, PENDING_FLIP);
} }
static void unref_fb_worker(struct drm_flip_work *work, void *val) static void unref_fb_worker(struct drm_flip_work *work, void *val)
@ -320,6 +347,20 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc,
mode->vsync_end, mode->vtotal, mode->vsync_end, mode->vtotal,
mode->type, mode->flags); mode->type, mode->flags);
/* grab extra ref for update_scanout() */
drm_framebuffer_reference(crtc->fb);
ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb,
0, 0, mode->hdisplay, mode->vdisplay,
x << 16, y << 16,
mode->hdisplay << 16, mode->vdisplay << 16);
if (ret) {
drm_framebuffer_unreference(crtc->fb);
dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n",
mdp4_crtc->name, ret);
return ret;
}
mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma), mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma),
MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) | MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) |
MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay)); MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay));
@ -341,24 +382,15 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc,
mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1); mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1);
update_fb(crtc, false, crtc->fb);
ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb,
0, 0, mode->hdisplay, mode->vdisplay,
x << 16, y << 16,
mode->hdisplay << 16, mode->vdisplay << 16);
if (ret) {
dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n",
mdp4_crtc->name, ret);
return ret;
}
if (dma == DMA_E) { if (dma == DMA_E) {
mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(0), 0x00ff0000); mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(0), 0x00ff0000);
mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000); mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000);
mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000); mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000);
} }
update_fb(crtc, crtc->fb);
update_scanout(crtc, crtc->fb);
return 0; return 0;
} }
@ -385,13 +417,24 @@ static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct drm_plane *plane = mdp4_crtc->plane; struct drm_plane *plane = mdp4_crtc->plane;
struct drm_display_mode *mode = &crtc->mode; struct drm_display_mode *mode = &crtc->mode;
int ret;
update_fb(crtc, false, crtc->fb); /* grab extra ref for update_scanout() */
drm_framebuffer_reference(crtc->fb);
return mdp4_plane_mode_set(plane, crtc, crtc->fb, ret = mdp4_plane_mode_set(plane, crtc, crtc->fb,
0, 0, mode->hdisplay, mode->vdisplay, 0, 0, mode->hdisplay, mode->vdisplay,
x << 16, y << 16, x << 16, y << 16,
mode->hdisplay << 16, mode->vdisplay << 16); mode->hdisplay << 16, mode->vdisplay << 16);
if (ret) {
drm_framebuffer_unreference(crtc->fb);
return ret;
}
update_fb(crtc, crtc->fb);
update_scanout(crtc, crtc->fb);
return 0;
} }
static void mdp4_crtc_load_lut(struct drm_crtc *crtc) static void mdp4_crtc_load_lut(struct drm_crtc *crtc)
@ -419,7 +462,7 @@ static int mdp4_crtc_page_flip(struct drm_crtc *crtc,
mdp4_crtc->event = event; mdp4_crtc->event = event;
spin_unlock_irqrestore(&dev->event_lock, flags); spin_unlock_irqrestore(&dev->event_lock, flags);
update_fb(crtc, true, new_fb); update_fb(crtc, new_fb);
return msm_gem_queue_inactive_cb(obj, &mdp4_crtc->pageflip_cb); return msm_gem_queue_inactive_cb(obj, &mdp4_crtc->pageflip_cb);
} }
@ -442,12 +485,12 @@ static int mdp4_crtc_set_property(struct drm_crtc *crtc,
static void update_cursor(struct drm_crtc *crtc) static void update_cursor(struct drm_crtc *crtc)
{ {
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc);
enum mdp4_dma dma = mdp4_crtc->dma; enum mdp4_dma dma = mdp4_crtc->dma;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags); spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
if (mdp4_crtc->cursor.stale) { if (mdp4_crtc->cursor.stale) {
struct mdp4_kms *mdp4_kms = get_kms(crtc);
struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo; struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo;
struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo; struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo;
uint32_t iova = mdp4_crtc->cursor.next_iova; uint32_t iova = mdp4_crtc->cursor.next_iova;
@ -479,6 +522,11 @@ static void update_cursor(struct drm_crtc *crtc)
mdp4_crtc->cursor.scanout_bo = next_bo; mdp4_crtc->cursor.scanout_bo = next_bo;
mdp4_crtc->cursor.stale = false; mdp4_crtc->cursor.stale = false;
} }
mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma),
MDP4_DMA_CURSOR_POS_X(mdp4_crtc->cursor.x) |
MDP4_DMA_CURSOR_POS_Y(mdp4_crtc->cursor.y));
spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags); spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
} }
@ -530,6 +578,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
drm_gem_object_unreference_unlocked(old_bo); drm_gem_object_unreference_unlocked(old_bo);
} }
crtc_flush(crtc);
request_pending(crtc, PENDING_CURSOR); request_pending(crtc, PENDING_CURSOR);
return 0; return 0;
@ -542,12 +591,15 @@ fail:
static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{ {
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc); unsigned long flags;
enum mdp4_dma dma = mdp4_crtc->dma;
mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma), spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
MDP4_DMA_CURSOR_POS_X(x) | mdp4_crtc->cursor.x = x;
MDP4_DMA_CURSOR_POS_Y(y)); mdp4_crtc->cursor.y = y;
spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
crtc_flush(crtc);
request_pending(crtc, PENDING_CURSOR);
return 0; return 0;
} }
@ -713,6 +765,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
crtc = &mdp4_crtc->base; crtc = &mdp4_crtc->base;
mdp4_crtc->plane = plane; mdp4_crtc->plane = plane;
mdp4_crtc->id = id;
mdp4_crtc->ovlp = ovlp_id; mdp4_crtc->ovlp = ovlp_id;
mdp4_crtc->dma = dma_id; mdp4_crtc->dma = dma_id;

View File

@ -170,8 +170,8 @@ int mdp4_plane_mode_set(struct drm_plane *plane,
MDP4_PIPE_DST_SIZE_HEIGHT(crtc_h)); MDP4_PIPE_DST_SIZE_HEIGHT(crtc_h));
mdp4_write(mdp4_kms, REG_MDP4_PIPE_DST_XY(pipe), mdp4_write(mdp4_kms, REG_MDP4_PIPE_DST_XY(pipe),
MDP4_PIPE_SRC_XY_X(crtc_x) | MDP4_PIPE_DST_XY_X(crtc_x) |
MDP4_PIPE_SRC_XY_Y(crtc_y)); MDP4_PIPE_DST_XY_Y(crtc_y));
mdp4_plane_set_scanout(plane, fb); mdp4_plane_set_scanout(plane, fb);

View File

@ -296,6 +296,7 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc,
x << 16, y << 16, x << 16, y << 16,
mode->hdisplay << 16, mode->vdisplay << 16); mode->hdisplay << 16, mode->vdisplay << 16);
if (ret) { if (ret) {
drm_framebuffer_unreference(crtc->fb);
dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n",
mdp5_crtc->name, ret); mdp5_crtc->name, ret);
return ret; return ret;
@ -343,11 +344,15 @@ static int mdp5_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
0, 0, mode->hdisplay, mode->vdisplay, 0, 0, mode->hdisplay, mode->vdisplay,
x << 16, y << 16, x << 16, y << 16,
mode->hdisplay << 16, mode->vdisplay << 16); mode->hdisplay << 16, mode->vdisplay << 16);
if (ret) {
drm_framebuffer_unreference(crtc->fb);
return ret;
}
update_fb(crtc, crtc->fb); update_fb(crtc, crtc->fb);
update_scanout(crtc, crtc->fb); update_scanout(crtc, crtc->fb);
return ret; return 0;
} }
static void mdp5_crtc_load_lut(struct drm_crtc *crtc) static void mdp5_crtc_load_lut(struct drm_crtc *crtc)

View File

@ -644,7 +644,7 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev,
fail: fail:
if (obj) if (obj)
drm_gem_object_unreference_unlocked(obj); drm_gem_object_unreference(obj);
return ERR_PTR(ret); return ERR_PTR(ret);
} }

View File

@ -163,7 +163,7 @@ retry:
/* if locking succeeded, pin bo: */ /* if locking succeeded, pin bo: */
ret = msm_gem_get_iova(&msm_obj->base, ret = msm_gem_get_iova_locked(&msm_obj->base,
submit->gpu->id, &iova); submit->gpu->id, &iova);
/* this would break the logic in the fail path.. there is no /* this would break the logic in the fail path.. there is no
@ -247,7 +247,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
/* For now, just map the entire thing. Eventually we probably /* For now, just map the entire thing. Eventually we probably
* to do it page-by-page, w/ kmap() if not vmap()d.. * to do it page-by-page, w/ kmap() if not vmap()d..
*/ */
ptr = msm_gem_vaddr(&obj->base); ptr = msm_gem_vaddr_locked(&obj->base);
if (IS_ERR(ptr)) { if (IS_ERR(ptr)) {
ret = PTR_ERR(ptr); ret = PTR_ERR(ptr);
@ -307,14 +307,12 @@ static void submit_cleanup(struct msm_gem_submit *submit, bool fail)
{ {
unsigned i; unsigned i;
mutex_lock(&submit->dev->struct_mutex);
for (i = 0; i < submit->nr_bos; i++) { for (i = 0; i < submit->nr_bos; i++) {
struct msm_gem_object *msm_obj = submit->bos[i].obj; struct msm_gem_object *msm_obj = submit->bos[i].obj;
submit_unlock_unpin_bo(submit, i); submit_unlock_unpin_bo(submit, i);
list_del_init(&msm_obj->submit_entry); list_del_init(&msm_obj->submit_entry);
drm_gem_object_unreference(&msm_obj->base); drm_gem_object_unreference(&msm_obj->base);
} }
mutex_unlock(&submit->dev->struct_mutex);
ww_acquire_fini(&submit->ticket); ww_acquire_fini(&submit->ticket);
kfree(submit); kfree(submit);
@ -342,6 +340,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
if (args->nr_cmds > MAX_CMDS) if (args->nr_cmds > MAX_CMDS)
return -EINVAL; return -EINVAL;
mutex_lock(&dev->struct_mutex);
submit = submit_create(dev, gpu, args->nr_bos); submit = submit_create(dev, gpu, args->nr_bos);
if (!submit) { if (!submit) {
ret = -ENOMEM; ret = -ENOMEM;
@ -410,5 +410,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
out: out:
if (submit) if (submit)
submit_cleanup(submit, !!ret); submit_cleanup(submit, !!ret);
mutex_unlock(&dev->struct_mutex);
return ret; return ret;
} }

View File

@ -298,8 +298,6 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
struct msm_drm_private *priv = dev->dev_private; struct msm_drm_private *priv = dev->dev_private;
int i, ret; int i, ret;
mutex_lock(&dev->struct_mutex);
submit->fence = ++priv->next_fence; submit->fence = ++priv->next_fence;
gpu->submitted_fence = submit->fence; gpu->submitted_fence = submit->fence;
@ -331,7 +329,6 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence); msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence);
} }
hangcheck_timer_reset(gpu); hangcheck_timer_reset(gpu);
mutex_unlock(&dev->struct_mutex);
return ret; return ret;
} }

View File

@ -29,6 +29,7 @@
#include "cypress_dpm.h" #include "cypress_dpm.h"
#include "btc_dpm.h" #include "btc_dpm.h"
#include "atom.h" #include "atom.h"
#include <linux/seq_file.h>
#define MC_CG_ARB_FREQ_F0 0x0a #define MC_CG_ARB_FREQ_F0 0x0a
#define MC_CG_ARB_FREQ_F1 0x0b #define MC_CG_ARB_FREQ_F1 0x0b
@ -2756,6 +2757,37 @@ void btc_dpm_fini(struct radeon_device *rdev)
r600_free_extended_power_table(rdev); r600_free_extended_power_table(rdev);
} }
void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
struct seq_file *m)
{
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
struct radeon_ps *rps = &eg_pi->current_rps;
struct rv7xx_ps *ps = rv770_get_ps(rps);
struct rv7xx_pl *pl;
u32 current_index =
(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
CURRENT_PROFILE_INDEX_SHIFT;
if (current_index > 2) {
seq_printf(m, "invalid dpm profile %d\n", current_index);
} else {
if (current_index == 0)
pl = &ps->low;
else if (current_index == 1)
pl = &ps->medium;
else /* current_index == 2 */
pl = &ps->high;
seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
if (rdev->family >= CHIP_CEDAR) {
seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u vddci: %u\n",
current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
} else {
seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u\n",
current_index, pl->sclk, pl->mclk, pl->vddc);
}
}
}
u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low) u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low)
{ {
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);

View File

@ -44,6 +44,10 @@
# define DYN_SPREAD_SPECTRUM_EN (1 << 23) # define DYN_SPREAD_SPECTRUM_EN (1 << 23)
# define AC_DC_SW (1 << 24) # define AC_DC_SW (1 << 24)
#define TARGET_AND_CURRENT_PROFILE_INDEX 0x66c
# define CURRENT_PROFILE_INDEX_MASK (0xf << 4)
# define CURRENT_PROFILE_INDEX_SHIFT 4
#define CG_BIF_REQ_AND_RSP 0x7f4 #define CG_BIF_REQ_AND_RSP 0x7f4
#define CG_CLIENT_REQ(x) ((x) << 0) #define CG_CLIENT_REQ(x) ((x) << 0)
#define CG_CLIENT_REQ_MASK (0xff << 0) #define CG_CLIENT_REQ_MASK (0xff << 0)

View File

@ -1223,7 +1223,7 @@ int kv_dpm_enable(struct radeon_device *rdev)
int kv_dpm_late_enable(struct radeon_device *rdev) int kv_dpm_late_enable(struct radeon_device *rdev)
{ {
int ret; int ret = 0;
if (rdev->irq.installed && if (rdev->irq.installed &&
r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {

View File

@ -3945,7 +3945,6 @@ static void ni_parse_pplib_clock_info(struct radeon_device *rdev,
struct rv7xx_power_info *pi = rv770_get_pi(rdev); struct rv7xx_power_info *pi = rv770_get_pi(rdev);
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
struct ni_ps *ps = ni_get_ps(rps); struct ni_ps *ps = ni_get_ps(rps);
u16 vddc;
struct rv7xx_pl *pl = &ps->performance_levels[index]; struct rv7xx_pl *pl = &ps->performance_levels[index];
ps->performance_level_count = index + 1; ps->performance_level_count = index + 1;
@ -3961,8 +3960,8 @@ static void ni_parse_pplib_clock_info(struct radeon_device *rdev,
/* patch up vddc if necessary */ /* patch up vddc if necessary */
if (pl->vddc == 0xff01) { if (pl->vddc == 0xff01) {
if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0) if (pi->max_vddc)
pl->vddc = vddc; pl->vddc = pi->max_vddc;
} }
if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
@ -4322,7 +4321,8 @@ void ni_dpm_print_power_state(struct radeon_device *rdev,
void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
struct seq_file *m) struct seq_file *m)
{ {
struct radeon_ps *rps = rdev->pm.dpm.current_ps; struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
struct radeon_ps *rps = &eg_pi->current_rps;
struct ni_ps *ps = ni_get_ps(rps); struct ni_ps *ps = ni_get_ps(rps);
struct rv7xx_pl *pl; struct rv7xx_pl *pl;
u32 current_index = u32 current_index =

View File

@ -3991,6 +3991,10 @@ restart_ih:
break; break;
} }
break; break;
case 124: /* UVD */
DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
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 */
case 178: /* CP_INT in IB2 */ case 178: /* CP_INT in IB2 */

View File

@ -1555,7 +1555,7 @@ static struct radeon_asic btc_asic = {
.get_sclk = &btc_dpm_get_sclk, .get_sclk = &btc_dpm_get_sclk,
.get_mclk = &btc_dpm_get_mclk, .get_mclk = &btc_dpm_get_mclk,
.print_power_state = &rv770_dpm_print_power_state, .print_power_state = &rv770_dpm_print_power_state,
.debugfs_print_current_performance_level = &rv770_dpm_debugfs_print_current_performance_level, .debugfs_print_current_performance_level = &btc_dpm_debugfs_print_current_performance_level,
.force_performance_level = &rv770_dpm_force_performance_level, .force_performance_level = &rv770_dpm_force_performance_level,
.vblank_too_short = &btc_dpm_vblank_too_short, .vblank_too_short = &btc_dpm_vblank_too_short,
}, },

View File

@ -551,6 +551,8 @@ void btc_dpm_fini(struct radeon_device *rdev);
u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low); u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low);
u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low); u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low);
bool btc_dpm_vblank_too_short(struct radeon_device *rdev); bool btc_dpm_vblank_too_short(struct radeon_device *rdev);
void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
struct seq_file *m);
int sumo_dpm_init(struct radeon_device *rdev); int sumo_dpm_init(struct radeon_device *rdev);
int sumo_dpm_enable(struct radeon_device *rdev); int sumo_dpm_enable(struct radeon_device *rdev);
int sumo_dpm_late_enable(struct radeon_device *rdev); int sumo_dpm_late_enable(struct radeon_device *rdev);

View File

@ -2174,7 +2174,6 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev,
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
struct rv7xx_ps *ps = rv770_get_ps(rps); struct rv7xx_ps *ps = rv770_get_ps(rps);
u32 sclk, mclk; u32 sclk, mclk;
u16 vddc;
struct rv7xx_pl *pl; struct rv7xx_pl *pl;
switch (index) { switch (index) {
@ -2214,8 +2213,8 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev,
/* patch up vddc if necessary */ /* patch up vddc if necessary */
if (pl->vddc == 0xff01) { if (pl->vddc == 0xff01) {
if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0) if (pi->max_vddc)
pl->vddc = vddc; pl->vddc = pi->max_vddc;
} }
if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {

View File

@ -6338,6 +6338,10 @@ restart_ih:
break; break;
} }
break; break;
case 124: /* UVD */
DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
break;
case 146: case 146:
case 147: case 147:
addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);

View File

@ -6472,7 +6472,8 @@ void si_dpm_fini(struct radeon_device *rdev)
void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
struct seq_file *m) struct seq_file *m)
{ {
struct radeon_ps *rps = rdev->pm.dpm.current_ps; struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
struct radeon_ps *rps = &eg_pi->current_rps;
struct ni_ps *ps = ni_get_ps(rps); struct ni_ps *ps = ni_get_ps(rps);
struct rv7xx_pl *pl; struct rv7xx_pl *pl;
u32 current_index = u32 current_index =

View File

@ -1807,7 +1807,7 @@ void sumo_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev
struct seq_file *m) struct seq_file *m)
{ {
struct sumo_power_info *pi = sumo_get_pi(rdev); struct sumo_power_info *pi = sumo_get_pi(rdev);
struct radeon_ps *rps = rdev->pm.dpm.current_ps; struct radeon_ps *rps = &pi->current_rps;
struct sumo_ps *ps = sumo_get_ps(rps); struct sumo_ps *ps = sumo_get_ps(rps);
struct sumo_pl *pl; struct sumo_pl *pl;
u32 current_index = u32 current_index =

View File

@ -1926,7 +1926,8 @@ void trinity_dpm_print_power_state(struct radeon_device *rdev,
void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
struct seq_file *m) struct seq_file *m)
{ {
struct radeon_ps *rps = rdev->pm.dpm.current_ps; struct trinity_power_info *pi = trinity_get_pi(rdev);
struct radeon_ps *rps = &pi->current_rps;
struct trinity_ps *ps = trinity_get_ps(rps); struct trinity_ps *ps = trinity_get_ps(rps);
struct trinity_pl *pl; struct trinity_pl *pl;
u32 current_index = u32 current_index =

View File

@ -57,7 +57,6 @@ void uvd_v2_2_fence_emit(struct radeon_device *rdev,
radeon_ring_write(ring, 0); radeon_ring_write(ring, 0);
radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
radeon_ring_write(ring, 2); radeon_ring_write(ring, 2);
return;
} }
/** /**

View File

@ -199,6 +199,9 @@ int drm_err(const char *func, const char *format, ...);
#define DRM_INFO(fmt, ...) \ #define DRM_INFO(fmt, ...) \
printk(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__) printk(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__)
#define DRM_INFO_ONCE(fmt, ...) \
printk_once(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__)
/** /**
* Debug output. * Debug output.
* *