Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm merge (part 1) from Dave Airlie: "So first of all my tree and uapi stuff has a conflict mess, its my fault as the nouveau stuff didn't hit -next as were trying to rebase regressions out of it before we merged. Highlights: - SH mobile modesetting driver and associated helpers - some DRM core documentation - i915 modesetting rework, haswell hdmi, haswell and vlv fixes, write combined pte writing, ilk rc6 support, - nouveau: major driver rework into a hw core driver, makes features like SLI a lot saner to implement, - psb: add eDP/DP support for Cedarview - radeon: 2 layer page tables, async VM pte updates, better PLL selection for > 2 screens, better ACPI interactions The rest is general grab bag of fixes. So why part 1? well I have the exynos pull req which came in a bit late but was waiting for me to do something they shouldn't have and it looks fairly safe, and David Howells has some more header cleanups he'd like me to pull, that seem like a good idea, but I'd like to get this merge out of the way so -next dosen't get blocked." Tons of conflicts mostly due to silly include line changes, but mostly mindless. A few other small semantic conflicts too, noted from Dave's pre-merged branch. * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (447 commits) drm/nv98/crypt: fix fuc build with latest envyas drm/nouveau/devinit: fixup various issues with subdev ctor/init ordering drm/nv41/vm: fix and enable use of "real" pciegart drm/nv44/vm: fix and enable use of "real" pciegart drm/nv04/dmaobj: fixup vm target handling in preparation for nv4x pcie drm/nouveau: store supported dma mask in vmmgr drm/nvc0/ibus: initial implementation of subdev drm/nouveau/therm: add support for fan-control modes drm/nouveau/hwmon: rename pwm0* to pmw1* to follow hwmon's rules drm/nouveau/therm: calculate the pwm divisor on nv50+ drm/nouveau/fan: rewrite the fan tachometer driver to get more precision, faster drm/nouveau/therm: move thermal-related functions to the therm subdev drm/nouveau/bios: parse the pwm divisor from the perf table drm/nouveau/therm: use the EXTDEV table to detect i2c monitoring devices drm/nouveau/therm: rework thermal table parsing drm/nouveau/gpio: expose the PWM/TOGGLE parameter found in the gpio vbios table drm/nouveau: fix pm initialization order drm/nouveau/bios: check that fixed tvdac gpio data is valid before using it drm/nouveau: log channel debug/error messages from client object rather than drm client drm/nouveau: have drm debugging macros build on top of core macros ...
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
#
|
||||
ccflags-y += -I$(srctree)/include/drm
|
||||
|
||||
gma500_gfx-y += gem_glue.o \
|
||||
gma500_gfx-y += \
|
||||
accel_2d.o \
|
||||
backlight.o \
|
||||
framebuffer.o \
|
||||
@@ -30,7 +30,8 @@ gma500_gfx-$(CONFIG_DRM_GMA3600) += cdv_device.o \
|
||||
cdv_intel_crt.o \
|
||||
cdv_intel_display.o \
|
||||
cdv_intel_hdmi.o \
|
||||
cdv_intel_lvds.o
|
||||
cdv_intel_lvds.o \
|
||||
cdv_intel_dp.o
|
||||
|
||||
gma500_gfx-$(CONFIG_DRM_GMA600) += oaktrail_device.o \
|
||||
oaktrail_crtc.o \
|
||||
|
@@ -26,10 +26,55 @@
|
||||
#include "intel_bios.h"
|
||||
#include "power.h"
|
||||
|
||||
static void do_gma_backlight_set(struct drm_device *dev)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||
backlight_update_status(dev_priv->backlight_device);
|
||||
#endif
|
||||
}
|
||||
|
||||
void gma_backlight_enable(struct drm_device *dev)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||
dev_priv->backlight_enabled = true;
|
||||
if (dev_priv->backlight_device) {
|
||||
dev_priv->backlight_device->props.brightness = dev_priv->backlight_level;
|
||||
do_gma_backlight_set(dev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void gma_backlight_disable(struct drm_device *dev)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||
dev_priv->backlight_enabled = false;
|
||||
if (dev_priv->backlight_device) {
|
||||
dev_priv->backlight_device->props.brightness = 0;
|
||||
do_gma_backlight_set(dev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void gma_backlight_set(struct drm_device *dev, int v)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||
dev_priv->backlight_level = v;
|
||||
if (dev_priv->backlight_device && dev_priv->backlight_enabled) {
|
||||
dev_priv->backlight_device->props.brightness = v;
|
||||
do_gma_backlight_set(dev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int gma_backlight_init(struct drm_device *dev)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||
dev_priv->backlight_enabled = true;
|
||||
return dev_priv->ops->backlight_init(dev);
|
||||
#else
|
||||
return 0;
|
||||
|
@@ -58,10 +58,17 @@ static int cdv_output_init(struct drm_device *dev)
|
||||
cdv_intel_lvds_init(dev, &dev_priv->mode_dev);
|
||||
|
||||
/* These bits indicate HDMI not SDVO on CDV */
|
||||
if (REG_READ(SDVOB) & SDVO_DETECTED)
|
||||
if (REG_READ(SDVOB) & SDVO_DETECTED) {
|
||||
cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
|
||||
if (REG_READ(SDVOC) & SDVO_DETECTED)
|
||||
if (REG_READ(DP_B) & DP_DETECTED)
|
||||
cdv_intel_dp_init(dev, &dev_priv->mode_dev, DP_B);
|
||||
}
|
||||
|
||||
if (REG_READ(SDVOC) & SDVO_DETECTED) {
|
||||
cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC);
|
||||
if (REG_READ(DP_C) & DP_DETECTED)
|
||||
cdv_intel_dp_init(dev, &dev_priv->mode_dev, DP_C);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -163,6 +170,7 @@ static int cdv_backlight_init(struct drm_device *dev)
|
||||
cdv_get_brightness(cdv_backlight_device);
|
||||
backlight_update_status(cdv_backlight_device);
|
||||
dev_priv->backlight_device = cdv_backlight_device;
|
||||
dev_priv->backlight_enabled = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -449,6 +457,7 @@ static void cdv_get_core_freq(struct drm_device *dev)
|
||||
case 6:
|
||||
case 7:
|
||||
dev_priv->core_freq = 266;
|
||||
break;
|
||||
default:
|
||||
dev_priv->core_freq = 0;
|
||||
}
|
||||
@@ -488,6 +497,65 @@ static void cdv_hotplug_enable(struct drm_device *dev, bool on)
|
||||
}
|
||||
}
|
||||
|
||||
static const char *force_audio_names[] = {
|
||||
"off",
|
||||
"auto",
|
||||
"on",
|
||||
};
|
||||
|
||||
void cdv_intel_attach_force_audio_property(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||
struct drm_property *prop;
|
||||
int i;
|
||||
|
||||
prop = dev_priv->force_audio_property;
|
||||
if (prop == NULL) {
|
||||
prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
|
||||
"audio",
|
||||
ARRAY_SIZE(force_audio_names));
|
||||
if (prop == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
|
||||
drm_property_add_enum(prop, i, i-1, force_audio_names[i]);
|
||||
|
||||
dev_priv->force_audio_property = prop;
|
||||
}
|
||||
drm_connector_attach_property(connector, prop, 0);
|
||||
}
|
||||
|
||||
|
||||
static const char *broadcast_rgb_names[] = {
|
||||
"Full",
|
||||
"Limited 16:235",
|
||||
};
|
||||
|
||||
void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||
struct drm_property *prop;
|
||||
int i;
|
||||
|
||||
prop = dev_priv->broadcast_rgb_property;
|
||||
if (prop == NULL) {
|
||||
prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
|
||||
"Broadcast RGB",
|
||||
ARRAY_SIZE(broadcast_rgb_names));
|
||||
if (prop == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++)
|
||||
drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]);
|
||||
|
||||
dev_priv->broadcast_rgb_property = prop;
|
||||
}
|
||||
|
||||
drm_connector_attach_property(connector, prop, 0);
|
||||
}
|
||||
|
||||
/* Cedarview */
|
||||
static const struct psb_offset cdv_regmap[2] = {
|
||||
{
|
||||
|
@@ -57,15 +57,26 @@ struct cdv_intel_clock_t {
|
||||
struct cdv_intel_limit_t {
|
||||
struct cdv_intel_range_t dot, vco, n, m, m1, m2, p, p1;
|
||||
struct cdv_intel_p2_t p2;
|
||||
bool (*find_pll)(const struct cdv_intel_limit_t *, struct drm_crtc *,
|
||||
int, int, struct cdv_intel_clock_t *);
|
||||
};
|
||||
|
||||
static bool cdv_intel_find_best_PLL(const struct cdv_intel_limit_t *limit,
|
||||
struct drm_crtc *crtc, int target, int refclk,
|
||||
struct cdv_intel_clock_t *best_clock);
|
||||
static bool cdv_intel_find_dp_pll(const struct cdv_intel_limit_t *limit, struct drm_crtc *crtc, int target,
|
||||
int refclk,
|
||||
struct cdv_intel_clock_t *best_clock);
|
||||
|
||||
#define CDV_LIMIT_SINGLE_LVDS_96 0
|
||||
#define CDV_LIMIT_SINGLE_LVDS_100 1
|
||||
#define CDV_LIMIT_DAC_HDMI_27 2
|
||||
#define CDV_LIMIT_DAC_HDMI_96 3
|
||||
#define CDV_LIMIT_DP_27 4
|
||||
#define CDV_LIMIT_DP_100 5
|
||||
|
||||
static const struct cdv_intel_limit_t cdv_intel_limits[] = {
|
||||
{ /* CDV_SIGNLE_LVDS_96MHz */
|
||||
{ /* CDV_SINGLE_LVDS_96MHz */
|
||||
.dot = {.min = 20000, .max = 115500},
|
||||
.vco = {.min = 1800000, .max = 3600000},
|
||||
.n = {.min = 2, .max = 6},
|
||||
@@ -76,6 +87,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
|
||||
.p1 = {.min = 2, .max = 10},
|
||||
.p2 = {.dot_limit = 200000,
|
||||
.p2_slow = 14, .p2_fast = 14},
|
||||
.find_pll = cdv_intel_find_best_PLL,
|
||||
},
|
||||
{ /* CDV_SINGLE_LVDS_100MHz */
|
||||
.dot = {.min = 20000, .max = 115500},
|
||||
@@ -90,6 +102,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
|
||||
* is 80-224Mhz. Prefer single channel as much as possible.
|
||||
*/
|
||||
.p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14},
|
||||
.find_pll = cdv_intel_find_best_PLL,
|
||||
},
|
||||
{ /* CDV_DAC_HDMI_27MHz */
|
||||
.dot = {.min = 20000, .max = 400000},
|
||||
@@ -101,6 +114,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
|
||||
.p = {.min = 5, .max = 90},
|
||||
.p1 = {.min = 1, .max = 9},
|
||||
.p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
|
||||
.find_pll = cdv_intel_find_best_PLL,
|
||||
},
|
||||
{ /* CDV_DAC_HDMI_96MHz */
|
||||
.dot = {.min = 20000, .max = 400000},
|
||||
@@ -112,7 +126,32 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
|
||||
.p = {.min = 5, .max = 100},
|
||||
.p1 = {.min = 1, .max = 10},
|
||||
.p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
|
||||
.find_pll = cdv_intel_find_best_PLL,
|
||||
},
|
||||
{ /* CDV_DP_27MHz */
|
||||
.dot = {.min = 160000, .max = 272000},
|
||||
.vco = {.min = 1809000, .max = 3564000},
|
||||
.n = {.min = 1, .max = 1},
|
||||
.m = {.min = 67, .max = 132},
|
||||
.m1 = {.min = 0, .max = 0},
|
||||
.m2 = {.min = 65, .max = 130},
|
||||
.p = {.min = 5, .max = 90},
|
||||
.p1 = {.min = 1, .max = 9},
|
||||
.p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 10},
|
||||
.find_pll = cdv_intel_find_dp_pll,
|
||||
},
|
||||
{ /* CDV_DP_100MHz */
|
||||
.dot = {.min = 160000, .max = 272000},
|
||||
.vco = {.min = 1800000, .max = 3600000},
|
||||
.n = {.min = 2, .max = 6},
|
||||
.m = {.min = 60, .max = 164},
|
||||
.m1 = {.min = 0, .max = 0},
|
||||
.m2 = {.min = 58, .max = 162},
|
||||
.p = {.min = 5, .max = 100},
|
||||
.p1 = {.min = 1, .max = 10},
|
||||
.p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 10},
|
||||
.find_pll = cdv_intel_find_dp_pll,
|
||||
}
|
||||
};
|
||||
|
||||
#define _wait_for(COND, MS, W) ({ \
|
||||
@@ -132,7 +171,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
|
||||
#define wait_for(COND, MS) _wait_for(COND, MS, 1)
|
||||
|
||||
|
||||
static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val)
|
||||
int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -159,7 +198,7 @@ static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val)
|
||||
int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val)
|
||||
{
|
||||
int ret;
|
||||
static bool dpio_debug = true;
|
||||
@@ -201,7 +240,7 @@ static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val)
|
||||
/* Reset the DPIO configuration register. The BIOS does this at every
|
||||
* mode set.
|
||||
*/
|
||||
static void cdv_sb_reset(struct drm_device *dev)
|
||||
void cdv_sb_reset(struct drm_device *dev)
|
||||
{
|
||||
|
||||
REG_WRITE(DPIO_CFG, 0);
|
||||
@@ -216,7 +255,7 @@ static void cdv_sb_reset(struct drm_device *dev)
|
||||
*/
|
||||
static int
|
||||
cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
|
||||
struct cdv_intel_clock_t *clock, bool is_lvds)
|
||||
struct cdv_intel_clock_t *clock, bool is_lvds, u32 ddi_select)
|
||||
{
|
||||
struct psb_intel_crtc *psb_crtc = to_psb_intel_crtc(crtc);
|
||||
int pipe = psb_crtc->pipe;
|
||||
@@ -259,7 +298,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
|
||||
ref_value &= ~(REF_CLK_MASK);
|
||||
|
||||
/* use DPLL_A for pipeB on CRT/HDMI */
|
||||
if (pipe == 1 && !is_lvds) {
|
||||
if (pipe == 1 && !is_lvds && !(ddi_select & DP_MASK)) {
|
||||
DRM_DEBUG_KMS("use DPLLA for pipe B\n");
|
||||
ref_value |= REF_CLK_DPLLA;
|
||||
} else {
|
||||
@@ -336,30 +375,33 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
lane_reg = PSB_LANE0;
|
||||
cdv_sb_read(dev, lane_reg, &lane_value);
|
||||
lane_value &= ~(LANE_PLL_MASK);
|
||||
lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
|
||||
cdv_sb_write(dev, lane_reg, lane_value);
|
||||
if (ddi_select) {
|
||||
if ((ddi_select & DDI_MASK) == DDI0_SELECT) {
|
||||
lane_reg = PSB_LANE0;
|
||||
cdv_sb_read(dev, lane_reg, &lane_value);
|
||||
lane_value &= ~(LANE_PLL_MASK);
|
||||
lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
|
||||
cdv_sb_write(dev, lane_reg, lane_value);
|
||||
|
||||
lane_reg = PSB_LANE1;
|
||||
cdv_sb_read(dev, lane_reg, &lane_value);
|
||||
lane_value &= ~(LANE_PLL_MASK);
|
||||
lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
|
||||
cdv_sb_write(dev, lane_reg, lane_value);
|
||||
|
||||
lane_reg = PSB_LANE2;
|
||||
cdv_sb_read(dev, lane_reg, &lane_value);
|
||||
lane_value &= ~(LANE_PLL_MASK);
|
||||
lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
|
||||
cdv_sb_write(dev, lane_reg, lane_value);
|
||||
|
||||
lane_reg = PSB_LANE3;
|
||||
cdv_sb_read(dev, lane_reg, &lane_value);
|
||||
lane_value &= ~(LANE_PLL_MASK);
|
||||
lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
|
||||
cdv_sb_write(dev, lane_reg, lane_value);
|
||||
lane_reg = PSB_LANE1;
|
||||
cdv_sb_read(dev, lane_reg, &lane_value);
|
||||
lane_value &= ~(LANE_PLL_MASK);
|
||||
lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
|
||||
cdv_sb_write(dev, lane_reg, lane_value);
|
||||
} else {
|
||||
lane_reg = PSB_LANE2;
|
||||
cdv_sb_read(dev, lane_reg, &lane_value);
|
||||
lane_value &= ~(LANE_PLL_MASK);
|
||||
lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
|
||||
cdv_sb_write(dev, lane_reg, lane_value);
|
||||
|
||||
lane_reg = PSB_LANE3;
|
||||
cdv_sb_read(dev, lane_reg, &lane_value);
|
||||
lane_value &= ~(LANE_PLL_MASK);
|
||||
lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
|
||||
cdv_sb_write(dev, lane_reg, lane_value);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -396,6 +438,12 @@ static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc,
|
||||
limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
|
||||
else
|
||||
limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100];
|
||||
} else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
|
||||
psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
|
||||
if (refclk == 27000)
|
||||
limit = &cdv_intel_limits[CDV_LIMIT_DP_27];
|
||||
else
|
||||
limit = &cdv_intel_limits[CDV_LIMIT_DP_100];
|
||||
} else {
|
||||
if (refclk == 27000)
|
||||
limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27];
|
||||
@@ -438,13 +486,12 @@ static bool cdv_intel_PLL_is_valid(struct drm_crtc *crtc,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target,
|
||||
int refclk,
|
||||
struct cdv_intel_clock_t *best_clock)
|
||||
static bool cdv_intel_find_best_PLL(const struct cdv_intel_limit_t *limit,
|
||||
struct drm_crtc *crtc, int target, int refclk,
|
||||
struct cdv_intel_clock_t *best_clock)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct cdv_intel_clock_t clock;
|
||||
const struct cdv_intel_limit_t *limit = cdv_intel_limit(crtc, refclk);
|
||||
int err = target;
|
||||
|
||||
|
||||
@@ -498,6 +545,49 @@ static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target,
|
||||
return err != target;
|
||||
}
|
||||
|
||||
static bool cdv_intel_find_dp_pll(const struct cdv_intel_limit_t *limit, struct drm_crtc *crtc, int target,
|
||||
int refclk,
|
||||
struct cdv_intel_clock_t *best_clock)
|
||||
{
|
||||
struct cdv_intel_clock_t clock;
|
||||
if (refclk == 27000) {
|
||||
if (target < 200000) {
|
||||
clock.p1 = 2;
|
||||
clock.p2 = 10;
|
||||
clock.n = 1;
|
||||
clock.m1 = 0;
|
||||
clock.m2 = 118;
|
||||
} else {
|
||||
clock.p1 = 1;
|
||||
clock.p2 = 10;
|
||||
clock.n = 1;
|
||||
clock.m1 = 0;
|
||||
clock.m2 = 98;
|
||||
}
|
||||
} else if (refclk == 100000) {
|
||||
if (target < 200000) {
|
||||
clock.p1 = 2;
|
||||
clock.p2 = 10;
|
||||
clock.n = 5;
|
||||
clock.m1 = 0;
|
||||
clock.m2 = 160;
|
||||
} else {
|
||||
clock.p1 = 1;
|
||||
clock.p2 = 10;
|
||||
clock.n = 5;
|
||||
clock.m1 = 0;
|
||||
clock.m2 = 133;
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
clock.m = clock.m2 + 2;
|
||||
clock.p = clock.p1 * clock.p2;
|
||||
clock.vco = (refclk * clock.m) / clock.n;
|
||||
clock.dot = clock.vco / clock.p;
|
||||
memcpy(best_clock, &clock, sizeof(struct cdv_intel_clock_t));
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cdv_intel_pipe_set_base(struct drm_crtc *crtc,
|
||||
int x, int y, struct drm_framebuffer *old_fb)
|
||||
{
|
||||
@@ -791,7 +881,7 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
if (psb_intel_crtc->active)
|
||||
return;
|
||||
break;
|
||||
|
||||
psb_intel_crtc->active = true;
|
||||
|
||||
@@ -835,17 +925,15 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
REG_WRITE(map->status, temp);
|
||||
REG_READ(map->status);
|
||||
|
||||
cdv_intel_update_watermark(dev, crtc);
|
||||
cdv_intel_crtc_load_lut(crtc);
|
||||
|
||||
/* Give the overlay scaler a chance to enable
|
||||
* if it's on this pipe */
|
||||
/* psb_intel_crtc_dpms_video(crtc, true); TODO */
|
||||
psb_intel_crtc->crtc_enable = true;
|
||||
break;
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
if (!psb_intel_crtc->active)
|
||||
return;
|
||||
break;
|
||||
|
||||
psb_intel_crtc->active = false;
|
||||
|
||||
@@ -892,10 +980,9 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
|
||||
/* Wait for the clocks to turn off. */
|
||||
udelay(150);
|
||||
cdv_intel_update_watermark(dev, crtc);
|
||||
psb_intel_crtc->crtc_enable = false;
|
||||
break;
|
||||
}
|
||||
cdv_intel_update_watermark(dev, crtc);
|
||||
/*Set FIFO Watermarks*/
|
||||
REG_WRITE(DSPARB, 0x3F3E);
|
||||
}
|
||||
@@ -952,9 +1039,12 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
u32 dpll = 0, dspcntr, pipeconf;
|
||||
bool ok;
|
||||
bool is_crt = false, is_lvds = false, is_tv = false;
|
||||
bool is_hdmi = false;
|
||||
bool is_hdmi = false, is_dp = false;
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
struct drm_connector *connector;
|
||||
const struct cdv_intel_limit_t *limit;
|
||||
u32 ddi_select = 0;
|
||||
bool is_edp = false;
|
||||
|
||||
list_for_each_entry(connector, &mode_config->connector_list, head) {
|
||||
struct psb_intel_encoder *psb_intel_encoder =
|
||||
@@ -964,6 +1054,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
|| connector->encoder->crtc != crtc)
|
||||
continue;
|
||||
|
||||
ddi_select = psb_intel_encoder->ddi_select;
|
||||
switch (psb_intel_encoder->type) {
|
||||
case INTEL_OUTPUT_LVDS:
|
||||
is_lvds = true;
|
||||
@@ -977,6 +1068,15 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
case INTEL_OUTPUT_HDMI:
|
||||
is_hdmi = true;
|
||||
break;
|
||||
case INTEL_OUTPUT_DISPLAYPORT:
|
||||
is_dp = true;
|
||||
break;
|
||||
case INTEL_OUTPUT_EDP:
|
||||
is_edp = true;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("invalid output type.\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -986,6 +1086,20 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
else
|
||||
/* high-end sku, 27/100 mhz */
|
||||
refclk = 27000;
|
||||
if (is_dp || is_edp) {
|
||||
/*
|
||||
* Based on the spec the low-end SKU has only CRT/LVDS. So it is
|
||||
* unnecessary to consider it for DP/eDP.
|
||||
* On the high-end SKU, it will use the 27/100M reference clk
|
||||
* for DP/eDP. When using SSC clock, the ref clk is 100MHz.Otherwise
|
||||
* it will be 27MHz. From the VBIOS code it seems that the pipe A choose
|
||||
* 27MHz for DP/eDP while the Pipe B chooses the 100MHz.
|
||||
*/
|
||||
if (pipe == 0)
|
||||
refclk = 27000;
|
||||
else
|
||||
refclk = 100000;
|
||||
}
|
||||
|
||||
if (is_lvds && dev_priv->lvds_use_ssc) {
|
||||
refclk = dev_priv->lvds_ssc_freq * 1000;
|
||||
@@ -993,8 +1107,10 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
}
|
||||
|
||||
drm_mode_debug_printmodeline(adjusted_mode);
|
||||
|
||||
limit = cdv_intel_limit(crtc, refclk);
|
||||
|
||||
ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
|
||||
ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk,
|
||||
&clock);
|
||||
if (!ok) {
|
||||
dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
|
||||
@@ -1009,6 +1125,15 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
}
|
||||
/* dpll |= PLL_REF_INPUT_DREFCLK; */
|
||||
|
||||
if (is_dp || is_edp) {
|
||||
cdv_intel_dp_set_m_n(crtc, mode, adjusted_mode);
|
||||
} else {
|
||||
REG_WRITE(PIPE_GMCH_DATA_M(pipe), 0);
|
||||
REG_WRITE(PIPE_GMCH_DATA_N(pipe), 0);
|
||||
REG_WRITE(PIPE_DP_LINK_M(pipe), 0);
|
||||
REG_WRITE(PIPE_DP_LINK_N(pipe), 0);
|
||||
}
|
||||
|
||||
dpll |= DPLL_SYNCLOCK_ENABLE;
|
||||
/* if (is_lvds)
|
||||
dpll |= DPLLB_MODE_LVDS;
|
||||
@@ -1019,6 +1144,31 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
/* setup pipeconf */
|
||||
pipeconf = REG_READ(map->conf);
|
||||
|
||||
pipeconf &= ~(PIPE_BPC_MASK);
|
||||
if (is_edp) {
|
||||
switch (dev_priv->edp.bpp) {
|
||||
case 24:
|
||||
pipeconf |= PIPE_8BPC;
|
||||
break;
|
||||
case 18:
|
||||
pipeconf |= PIPE_6BPC;
|
||||
break;
|
||||
case 30:
|
||||
pipeconf |= PIPE_10BPC;
|
||||
break;
|
||||
default:
|
||||
pipeconf |= PIPE_8BPC;
|
||||
break;
|
||||
}
|
||||
} else if (is_lvds) {
|
||||
/* the BPC will be 6 if it is 18-bit LVDS panel */
|
||||
if ((REG_READ(LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
|
||||
pipeconf |= PIPE_8BPC;
|
||||
else
|
||||
pipeconf |= PIPE_6BPC;
|
||||
} else
|
||||
pipeconf |= PIPE_8BPC;
|
||||
|
||||
/* Set up the display plane register */
|
||||
dspcntr = DISPPLANE_GAMMA_ENABLE;
|
||||
|
||||
@@ -1033,7 +1183,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
REG_WRITE(map->dpll, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE);
|
||||
REG_READ(map->dpll);
|
||||
|
||||
cdv_dpll_set_clock_cdv(dev, crtc, &clock, is_lvds);
|
||||
cdv_dpll_set_clock_cdv(dev, crtc, &clock, is_lvds, ddi_select);
|
||||
|
||||
udelay(150);
|
||||
|
||||
|
1950
drivers/gpu/drm/gma500/cdv_intel_dp.c
Normal file
1950
drivers/gpu/drm/gma500/cdv_intel_dp.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -139,8 +139,6 @@ static enum drm_connector_status cdv_hdmi_detect(
|
||||
{
|
||||
struct psb_intel_encoder *psb_intel_encoder =
|
||||
psb_intel_attached_encoder(connector);
|
||||
struct psb_intel_connector *psb_intel_connector =
|
||||
to_psb_intel_connector(connector);
|
||||
struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
|
||||
struct edid *edid = NULL;
|
||||
enum drm_connector_status status = connector_status_disconnected;
|
||||
@@ -157,8 +155,6 @@ static enum drm_connector_status cdv_hdmi_detect(
|
||||
hdmi_priv->has_hdmi_audio =
|
||||
drm_detect_monitor_audio(edid);
|
||||
}
|
||||
|
||||
psb_intel_connector->base.display_info.raw_edid = NULL;
|
||||
kfree(edid);
|
||||
}
|
||||
return status;
|
||||
@@ -352,9 +348,11 @@ void cdv_hdmi_init(struct drm_device *dev,
|
||||
switch (reg) {
|
||||
case SDVOB:
|
||||
ddc_bus = GPIOE;
|
||||
psb_intel_encoder->ddi_select = DDI0_SELECT;
|
||||
break;
|
||||
case SDVOC:
|
||||
ddc_bus = GPIOD;
|
||||
psb_intel_encoder->ddi_select = DDI1_SELECT;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("unknown reg 0x%x for HDMI\n", reg);
|
||||
|
@@ -506,16 +506,8 @@ static int cdv_intel_lvds_set_property(struct drm_connector *connector,
|
||||
property,
|
||||
value))
|
||||
return -1;
|
||||
else {
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv =
|
||||
encoder->dev->dev_private;
|
||||
struct backlight_device *bd =
|
||||
dev_priv->backlight_device;
|
||||
bd->props.brightness = value;
|
||||
backlight_update_status(bd);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
gma_backlight_set(encoder->dev, value);
|
||||
} else if (!strcmp(property->name, "DPMS") && encoder) {
|
||||
struct drm_encoder_helper_funcs *helpers =
|
||||
encoder->helper_private;
|
||||
|
@@ -764,6 +764,13 @@ static void psb_setup_outputs(struct drm_device *dev)
|
||||
crtc_mask = dev_priv->ops->hdmi_mask;
|
||||
clone_mask = (1 << INTEL_OUTPUT_HDMI);
|
||||
break;
|
||||
case INTEL_OUTPUT_DISPLAYPORT:
|
||||
crtc_mask = (1 << 0) | (1 << 1);
|
||||
clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
|
||||
break;
|
||||
case INTEL_OUTPUT_EDP:
|
||||
crtc_mask = (1 << 1);
|
||||
clone_mask = (1 << INTEL_OUTPUT_EDP);
|
||||
}
|
||||
encoder->possible_crtcs = crtc_mask;
|
||||
encoder->possible_clones =
|
||||
|
@@ -36,7 +36,12 @@ int psb_gem_init_object(struct drm_gem_object *obj)
|
||||
void psb_gem_free_object(struct drm_gem_object *obj)
|
||||
{
|
||||
struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
|
||||
drm_gem_object_release_wrap(obj);
|
||||
|
||||
/* Remove the list map if one is present */
|
||||
if (obj->map_list.map)
|
||||
drm_gem_free_mmap_offset(obj);
|
||||
drm_gem_object_release(obj);
|
||||
|
||||
/* This must occur last as it frees up the memory of the GEM object */
|
||||
psb_gtt_free_range(obj->dev, gtt);
|
||||
}
|
||||
@@ -77,7 +82,7 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
|
||||
|
||||
/* Make it mmapable */
|
||||
if (!obj->map_list.map) {
|
||||
ret = gem_create_mmap_offset(obj);
|
||||
ret = drm_gem_create_mmap_offset(obj);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
@@ -1,90 +0,0 @@
|
||||
/**************************************************************************
|
||||
* Copyright (c) 2011, Intel Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm.h>
|
||||
#include "gem_glue.h"
|
||||
|
||||
void drm_gem_object_release_wrap(struct drm_gem_object *obj)
|
||||
{
|
||||
/* Remove the list map if one is present */
|
||||
if (obj->map_list.map) {
|
||||
struct drm_gem_mm *mm = obj->dev->mm_private;
|
||||
struct drm_map_list *list = &obj->map_list;
|
||||
drm_ht_remove_item(&mm->offset_hash, &list->hash);
|
||||
drm_mm_put_block(list->file_offset_node);
|
||||
kfree(list->map);
|
||||
list->map = NULL;
|
||||
}
|
||||
drm_gem_object_release(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* gem_create_mmap_offset - invent an mmap offset
|
||||
* @obj: our object
|
||||
*
|
||||
* Standard implementation of offset generation for mmap as is
|
||||
* duplicated in several drivers. This belongs in GEM.
|
||||
*/
|
||||
int gem_create_mmap_offset(struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->dev;
|
||||
struct drm_gem_mm *mm = dev->mm_private;
|
||||
struct drm_map_list *list;
|
||||
struct drm_local_map *map;
|
||||
int ret;
|
||||
|
||||
list = &obj->map_list;
|
||||
list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
|
||||
if (list->map == NULL)
|
||||
return -ENOMEM;
|
||||
map = list->map;
|
||||
map->type = _DRM_GEM;
|
||||
map->size = obj->size;
|
||||
map->handle = obj;
|
||||
|
||||
list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
|
||||
obj->size / PAGE_SIZE, 0, 0);
|
||||
if (!list->file_offset_node) {
|
||||
dev_err(dev->dev, "failed to allocate offset for bo %d\n",
|
||||
obj->name);
|
||||
ret = -ENOSPC;
|
||||
goto free_it;
|
||||
}
|
||||
list->file_offset_node = drm_mm_get_block(list->file_offset_node,
|
||||
obj->size / PAGE_SIZE, 0);
|
||||
if (!list->file_offset_node) {
|
||||
ret = -ENOMEM;
|
||||
goto free_it;
|
||||
}
|
||||
list->hash.key = list->file_offset_node->start;
|
||||
ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "failed to add to map hash\n");
|
||||
goto free_mm;
|
||||
}
|
||||
return 0;
|
||||
|
||||
free_mm:
|
||||
drm_mm_put_block(list->file_offset_node);
|
||||
free_it:
|
||||
kfree(list->map);
|
||||
list->map = NULL;
|
||||
return ret;
|
||||
}
|
@@ -1,2 +0,0 @@
|
||||
extern void drm_gem_object_release_wrap(struct drm_gem_object *obj);
|
||||
extern int gem_create_mmap_offset(struct drm_gem_object *obj);
|
@@ -54,6 +54,98 @@ static void *find_section(struct bdb_header *bdb, int section_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_edp(struct drm_psb_private *dev_priv, struct bdb_header *bdb)
|
||||
{
|
||||
struct bdb_edp *edp;
|
||||
struct edp_power_seq *edp_pps;
|
||||
struct edp_link_params *edp_link_params;
|
||||
uint8_t panel_type;
|
||||
|
||||
edp = find_section(bdb, BDB_EDP);
|
||||
|
||||
dev_priv->edp.bpp = 18;
|
||||
if (!edp) {
|
||||
if (dev_priv->edp.support) {
|
||||
DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported, assume %dbpp panel color depth.\n",
|
||||
dev_priv->edp.bpp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
panel_type = dev_priv->panel_type;
|
||||
switch ((edp->color_depth >> (panel_type * 2)) & 3) {
|
||||
case EDP_18BPP:
|
||||
dev_priv->edp.bpp = 18;
|
||||
break;
|
||||
case EDP_24BPP:
|
||||
dev_priv->edp.bpp = 24;
|
||||
break;
|
||||
case EDP_30BPP:
|
||||
dev_priv->edp.bpp = 30;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the eDP sequencing and link info */
|
||||
edp_pps = &edp->power_seqs[panel_type];
|
||||
edp_link_params = &edp->link_params[panel_type];
|
||||
|
||||
dev_priv->edp.pps = *edp_pps;
|
||||
|
||||
DRM_DEBUG_KMS("EDP timing in vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
|
||||
dev_priv->edp.pps.t1_t3, dev_priv->edp.pps.t8,
|
||||
dev_priv->edp.pps.t9, dev_priv->edp.pps.t10,
|
||||
dev_priv->edp.pps.t11_t12);
|
||||
|
||||
dev_priv->edp.rate = edp_link_params->rate ? DP_LINK_BW_2_7 :
|
||||
DP_LINK_BW_1_62;
|
||||
switch (edp_link_params->lanes) {
|
||||
case 0:
|
||||
dev_priv->edp.lanes = 1;
|
||||
break;
|
||||
case 1:
|
||||
dev_priv->edp.lanes = 2;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
dev_priv->edp.lanes = 4;
|
||||
break;
|
||||
}
|
||||
DRM_DEBUG_KMS("VBT reports EDP: Lane_count %d, Lane_rate %d, Bpp %d\n",
|
||||
dev_priv->edp.lanes, dev_priv->edp.rate, dev_priv->edp.bpp);
|
||||
|
||||
switch (edp_link_params->preemphasis) {
|
||||
case 0:
|
||||
dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
|
||||
break;
|
||||
case 1:
|
||||
dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
|
||||
break;
|
||||
case 2:
|
||||
dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
|
||||
break;
|
||||
case 3:
|
||||
dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
|
||||
break;
|
||||
}
|
||||
switch (edp_link_params->vswing) {
|
||||
case 0:
|
||||
dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_400;
|
||||
break;
|
||||
case 1:
|
||||
dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_600;
|
||||
break;
|
||||
case 2:
|
||||
dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_800;
|
||||
break;
|
||||
case 3:
|
||||
dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_1200;
|
||||
break;
|
||||
}
|
||||
DRM_DEBUG_KMS("VBT reports EDP: VSwing %d, Preemph %d\n",
|
||||
dev_priv->edp.vswing, dev_priv->edp.preemphasis);
|
||||
}
|
||||
|
||||
static u16
|
||||
get_blocksize(void *p)
|
||||
{
|
||||
@@ -154,6 +246,8 @@ static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
|
||||
return;
|
||||
|
||||
dev_priv->lvds_dither = lvds_options->pixel_dither;
|
||||
dev_priv->panel_type = lvds_options->panel_type;
|
||||
|
||||
if (lvds_options->panel_type == 0xff)
|
||||
return;
|
||||
|
||||
@@ -340,6 +434,9 @@ parse_driver_features(struct drm_psb_private *dev_priv,
|
||||
if (!driver)
|
||||
return;
|
||||
|
||||
if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
|
||||
dev_priv->edp.support = 1;
|
||||
|
||||
/* This bit means to use 96Mhz for DPLL_A or not */
|
||||
if (driver->primary_lfp_id)
|
||||
dev_priv->dplla_96mhz = true;
|
||||
@@ -437,6 +534,9 @@ int psb_intel_init_bios(struct drm_device *dev)
|
||||
size_t size;
|
||||
int i;
|
||||
|
||||
|
||||
dev_priv->panel_type = 0xff;
|
||||
|
||||
/* XXX Should this validation be moved to intel_opregion.c? */
|
||||
if (dev_priv->opregion.vbt) {
|
||||
struct vbt_header *vbt = dev_priv->opregion.vbt;
|
||||
@@ -477,6 +577,7 @@ int psb_intel_init_bios(struct drm_device *dev)
|
||||
parse_sdvo_device_mapping(dev_priv, bdb);
|
||||
parse_device_mapping(dev_priv, bdb);
|
||||
parse_backlight_data(dev_priv, bdb);
|
||||
parse_edp(dev_priv, bdb);
|
||||
|
||||
if (bios)
|
||||
pci_unmap_rom(pdev, bios);
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#define _I830_BIOS_H_
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_dp_helper.h>
|
||||
|
||||
struct vbt_header {
|
||||
u8 signature[20]; /**< Always starts with 'VBT$' */
|
||||
@@ -93,6 +94,7 @@ struct vbios_data {
|
||||
#define BDB_SDVO_LVDS_PNP_IDS 24
|
||||
#define BDB_SDVO_LVDS_POWER_SEQ 25
|
||||
#define BDB_TV_OPTIONS 26
|
||||
#define BDB_EDP 27
|
||||
#define BDB_LVDS_OPTIONS 40
|
||||
#define BDB_LVDS_LFP_DATA_PTRS 41
|
||||
#define BDB_LVDS_LFP_DATA 42
|
||||
@@ -391,6 +393,11 @@ struct bdb_sdvo_lvds_options {
|
||||
u8 panel_misc_bits_4;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BDB_DRIVER_FEATURE_NO_LVDS 0
|
||||
#define BDB_DRIVER_FEATURE_INT_LVDS 1
|
||||
#define BDB_DRIVER_FEATURE_SDVO_LVDS 2
|
||||
#define BDB_DRIVER_FEATURE_EDP 3
|
||||
|
||||
struct bdb_driver_features {
|
||||
u8 boot_dev_algorithm:1;
|
||||
u8 block_display_switch:1;
|
||||
@@ -431,6 +438,45 @@ struct bdb_driver_features {
|
||||
u8 custom_vbt_version;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define EDP_18BPP 0
|
||||
#define EDP_24BPP 1
|
||||
#define EDP_30BPP 2
|
||||
#define EDP_RATE_1_62 0
|
||||
#define EDP_RATE_2_7 1
|
||||
#define EDP_LANE_1 0
|
||||
#define EDP_LANE_2 1
|
||||
#define EDP_LANE_4 3
|
||||
#define EDP_PREEMPHASIS_NONE 0
|
||||
#define EDP_PREEMPHASIS_3_5dB 1
|
||||
#define EDP_PREEMPHASIS_6dB 2
|
||||
#define EDP_PREEMPHASIS_9_5dB 3
|
||||
#define EDP_VSWING_0_4V 0
|
||||
#define EDP_VSWING_0_6V 1
|
||||
#define EDP_VSWING_0_8V 2
|
||||
#define EDP_VSWING_1_2V 3
|
||||
|
||||
struct edp_power_seq {
|
||||
u16 t1_t3;
|
||||
u16 t8;
|
||||
u16 t9;
|
||||
u16 t10;
|
||||
u16 t11_t12;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct edp_link_params {
|
||||
u8 rate:4;
|
||||
u8 lanes:4;
|
||||
u8 preemphasis:4;
|
||||
u8 vswing:4;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct bdb_edp {
|
||||
struct edp_power_seq power_seqs[16];
|
||||
u32 color_depth;
|
||||
u32 sdrrs_msa_timing_delay;
|
||||
struct edp_link_params link_params[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
extern int psb_intel_init_bios(struct drm_device *dev);
|
||||
extern void psb_intel_destroy_bios(struct drm_device *dev);
|
||||
|
||||
|
@@ -299,17 +299,8 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
|
||||
if (drm_connector_property_set_value(connector, property,
|
||||
value))
|
||||
goto set_prop_error;
|
||||
else {
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct backlight_device *psb_bd;
|
||||
|
||||
psb_bd = mdfld_get_backlight_device();
|
||||
if (psb_bd) {
|
||||
psb_bd->props.brightness = value;
|
||||
mdfld_set_brightness(psb_bd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
gma_backlight_set(encoder->dev, value);
|
||||
}
|
||||
set_prop_done:
|
||||
return 0;
|
||||
|
@@ -118,20 +118,20 @@ static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
|
||||
dev_priv->platform_rev_id);
|
||||
}
|
||||
|
||||
struct vbt_header {
|
||||
struct mid_vbt_header {
|
||||
u32 signature;
|
||||
u8 revision;
|
||||
} __packed;
|
||||
|
||||
/* The same for r0 and r1 */
|
||||
struct vbt_r0 {
|
||||
struct vbt_header vbt_header;
|
||||
struct mid_vbt_header vbt_header;
|
||||
u8 size;
|
||||
u8 checksum;
|
||||
} __packed;
|
||||
|
||||
struct vbt_r10 {
|
||||
struct vbt_header vbt_header;
|
||||
struct mid_vbt_header vbt_header;
|
||||
u8 checksum;
|
||||
u16 size;
|
||||
u8 panel_count;
|
||||
@@ -281,7 +281,7 @@ static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
u32 addr;
|
||||
u8 __iomem *vbt_virtual;
|
||||
struct vbt_header vbt_header;
|
||||
struct mid_vbt_header vbt_header;
|
||||
struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
|
||||
int ret = -1;
|
||||
|
||||
|
@@ -252,7 +252,6 @@ static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
|
||||
if (edid) {
|
||||
drm_mode_connector_update_edid_property(connector, edid);
|
||||
ret = drm_add_edid_modes(connector, edid);
|
||||
connector->display_info.raw_edid = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -166,8 +166,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
|
||||
|
||||
if (config_enabled(CONFIG_BACKLIGHT_CLASS_DEVICE)) {
|
||||
int max = bd->props.max_brightness;
|
||||
bd->props.brightness = bclp * max / 255;
|
||||
backlight_update_status(bd);
|
||||
gma_backlight_set(dev, bclp * max / 255);
|
||||
}
|
||||
|
||||
asle->cblv = (bclp * 0x64) / 0xff | ASLE_CBLV_VALID;
|
||||
|
@@ -290,6 +290,7 @@ static void psb_get_core_freq(struct drm_device *dev)
|
||||
case 6:
|
||||
case 7:
|
||||
dev_priv->core_freq = 266;
|
||||
break;
|
||||
default:
|
||||
dev_priv->core_freq = 0;
|
||||
}
|
||||
|
@@ -24,10 +24,10 @@
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_global.h>
|
||||
#include "gem_glue.h"
|
||||
#include <drm/gma_drm.h>
|
||||
#include "psb_reg.h"
|
||||
#include "psb_intel_drv.h"
|
||||
#include "intel_bios.h"
|
||||
#include "gtt.h"
|
||||
#include "power.h"
|
||||
#include "opregion.h"
|
||||
@@ -613,6 +613,8 @@ struct drm_psb_private {
|
||||
*/
|
||||
struct backlight_device *backlight_device;
|
||||
struct drm_property *backlight_property;
|
||||
bool backlight_enabled;
|
||||
int backlight_level;
|
||||
uint32_t blc_adj1;
|
||||
uint32_t blc_adj2;
|
||||
|
||||
@@ -640,6 +642,19 @@ struct drm_psb_private {
|
||||
int mdfld_panel_id;
|
||||
|
||||
bool dplla_96mhz; /* DPLL data from the VBT */
|
||||
|
||||
struct {
|
||||
int rate;
|
||||
int lanes;
|
||||
int preemphasis;
|
||||
int vswing;
|
||||
|
||||
bool initialized;
|
||||
bool support;
|
||||
int bpp;
|
||||
struct edp_power_seq pps;
|
||||
} edp;
|
||||
uint8_t panel_type;
|
||||
};
|
||||
|
||||
|
||||
@@ -796,6 +811,9 @@ extern int psb_fbdev_init(struct drm_device *dev);
|
||||
/* backlight.c */
|
||||
int gma_backlight_init(struct drm_device *dev);
|
||||
void gma_backlight_exit(struct drm_device *dev);
|
||||
void gma_backlight_disable(struct drm_device *dev);
|
||||
void gma_backlight_enable(struct drm_device *dev);
|
||||
void gma_backlight_set(struct drm_device *dev, int v);
|
||||
|
||||
/* oaktrail_crtc.c */
|
||||
extern const struct drm_crtc_helper_funcs oaktrail_helper_funcs;
|
||||
|
@@ -29,10 +29,6 @@
|
||||
* Display related stuff
|
||||
*/
|
||||
|
||||
/* store information about an Ixxx DVO */
|
||||
/* The i830->i865 use multiple DVOs with multiple i2cs */
|
||||
/* the i915, i945 have a single sDVO i2c bus - which is different */
|
||||
#define MAX_OUTPUTS 6
|
||||
/* maximum connectors per crtcs in the mode set */
|
||||
#define INTELFB_CONN_LIMIT 4
|
||||
|
||||
@@ -69,6 +65,8 @@
|
||||
#define INTEL_OUTPUT_HDMI 6
|
||||
#define INTEL_OUTPUT_MIPI 7
|
||||
#define INTEL_OUTPUT_MIPI2 8
|
||||
#define INTEL_OUTPUT_DISPLAYPORT 9
|
||||
#define INTEL_OUTPUT_EDP 10
|
||||
|
||||
#define INTEL_DVO_CHIP_NONE 0
|
||||
#define INTEL_DVO_CHIP_LVDS 1
|
||||
@@ -133,6 +131,11 @@ struct psb_intel_encoder {
|
||||
void (*hot_plug)(struct psb_intel_encoder *);
|
||||
int crtc_mask;
|
||||
int clone_mask;
|
||||
u32 ddi_select; /* Channel info */
|
||||
#define DDI0_SELECT 0x01
|
||||
#define DDI1_SELECT 0x02
|
||||
#define DP_MASK 0x8000
|
||||
#define DDI_MASK 0x03
|
||||
void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */
|
||||
|
||||
/* FIXME: Either make SDVO and LVDS store it's i2c here or give CDV it's
|
||||
@@ -190,7 +193,6 @@ struct psb_intel_crtc {
|
||||
u32 mode_flags;
|
||||
|
||||
bool active;
|
||||
bool crtc_enable;
|
||||
|
||||
/* Saved Crtc HW states */
|
||||
struct psb_intel_crtc_state *crtc_state;
|
||||
@@ -285,4 +287,20 @@ extern void gma_intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
|
||||
extern void gma_intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
|
||||
extern void gma_intel_teardown_gmbus(struct drm_device *dev);
|
||||
|
||||
/* DP support */
|
||||
extern void cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int output_reg);
|
||||
extern void cdv_intel_dp_set_m_n(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
|
||||
extern void psb_intel_attach_force_audio_property(struct drm_connector *connector);
|
||||
extern void psb_intel_attach_broadcast_rgb_property(struct drm_connector *connector);
|
||||
|
||||
extern int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val);
|
||||
extern int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val);
|
||||
extern void cdv_sb_reset(struct drm_device *dev);
|
||||
|
||||
extern void cdv_intel_attach_force_audio_property(struct drm_connector *connector);
|
||||
extern void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector);
|
||||
|
||||
#endif /* __INTEL_DRV_H__ */
|
||||
|
@@ -630,17 +630,8 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
|
||||
property,
|
||||
value))
|
||||
goto set_prop_error;
|
||||
else {
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *devp =
|
||||
encoder->dev->dev_private;
|
||||
struct backlight_device *bd = devp->backlight_device;
|
||||
if (bd) {
|
||||
bd->props.brightness = value;
|
||||
backlight_update_status(bd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
gma_backlight_set(encoder->dev, value);
|
||||
} else if (!strcmp(property->name, "DPMS")) {
|
||||
struct drm_encoder_helper_funcs *hfuncs
|
||||
= encoder->helper_private;
|
||||
|
@@ -173,15 +173,46 @@
|
||||
#define PP_SEQUENCE_ON (1 << 28)
|
||||
#define PP_SEQUENCE_OFF (2 << 28)
|
||||
#define PP_SEQUENCE_MASK 0x30000000
|
||||
#define PP_CYCLE_DELAY_ACTIVE (1 << 27)
|
||||
#define PP_SEQUENCE_STATE_ON_IDLE (1 << 3)
|
||||
#define PP_SEQUENCE_STATE_MASK 0x0000000f
|
||||
|
||||
#define PP_CONTROL 0x61204
|
||||
#define POWER_TARGET_ON (1 << 0)
|
||||
#define PANEL_UNLOCK_REGS (0xabcd << 16)
|
||||
#define PANEL_UNLOCK_MASK (0xffff << 16)
|
||||
#define EDP_FORCE_VDD (1 << 3)
|
||||
#define EDP_BLC_ENABLE (1 << 2)
|
||||
#define PANEL_POWER_RESET (1 << 1)
|
||||
#define PANEL_POWER_OFF (0 << 0)
|
||||
#define PANEL_POWER_ON (1 << 0)
|
||||
|
||||
/* Poulsbo/Oaktrail */
|
||||
#define LVDSPP_ON 0x61208
|
||||
#define LVDSPP_OFF 0x6120c
|
||||
#define PP_CYCLE 0x61210
|
||||
|
||||
/* Cedartrail */
|
||||
#define PP_ON_DELAYS 0x61208 /* Cedartrail */
|
||||
#define PANEL_PORT_SELECT_MASK (3 << 30)
|
||||
#define PANEL_PORT_SELECT_LVDS (0 << 30)
|
||||
#define PANEL_PORT_SELECT_EDP (1 << 30)
|
||||
#define PANEL_POWER_UP_DELAY_MASK (0x1fff0000)
|
||||
#define PANEL_POWER_UP_DELAY_SHIFT 16
|
||||
#define PANEL_LIGHT_ON_DELAY_MASK (0x1fff)
|
||||
#define PANEL_LIGHT_ON_DELAY_SHIFT 0
|
||||
|
||||
#define PP_OFF_DELAYS 0x6120c /* Cedartrail */
|
||||
#define PANEL_POWER_DOWN_DELAY_MASK (0x1fff0000)
|
||||
#define PANEL_POWER_DOWN_DELAY_SHIFT 16
|
||||
#define PANEL_LIGHT_OFF_DELAY_MASK (0x1fff)
|
||||
#define PANEL_LIGHT_OFF_DELAY_SHIFT 0
|
||||
|
||||
#define PP_DIVISOR 0x61210 /* Cedartrail */
|
||||
#define PP_REFERENCE_DIVIDER_MASK (0xffffff00)
|
||||
#define PP_REFERENCE_DIVIDER_SHIFT 8
|
||||
#define PANEL_POWER_CYCLE_DELAY_MASK (0x1f)
|
||||
#define PANEL_POWER_CYCLE_DELAY_SHIFT 0
|
||||
|
||||
#define PFIT_CONTROL 0x61230
|
||||
#define PFIT_ENABLE (1 << 31)
|
||||
@@ -1282,6 +1313,10 @@ No status bits are changed.
|
||||
# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* Fixed value on CDV */
|
||||
# define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11)
|
||||
# define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6)
|
||||
# define DPUNIT_PIPEB_GATE_DISABLE (1 << 30)
|
||||
# define DPUNIT_PIPEA_GATE_DISABLE (1 << 25)
|
||||
# define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24)
|
||||
# define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13)
|
||||
|
||||
#define RAMCLK_GATE_D 0x6210
|
||||
|
||||
@@ -1347,5 +1382,165 @@ No status bits are changed.
|
||||
#define LANE_PLL_ENABLE (0x3 << 20)
|
||||
#define LANE_PLL_PIPE(p) (((p) == 0) ? (1 << 21) : (0 << 21))
|
||||
|
||||
#define DP_B 0x64100
|
||||
#define DP_C 0x64200
|
||||
|
||||
#define DP_PORT_EN (1 << 31)
|
||||
#define DP_PIPEB_SELECT (1 << 30)
|
||||
#define DP_PIPE_MASK (1 << 30)
|
||||
|
||||
/* Link training mode - select a suitable mode for each stage */
|
||||
#define DP_LINK_TRAIN_PAT_1 (0 << 28)
|
||||
#define DP_LINK_TRAIN_PAT_2 (1 << 28)
|
||||
#define DP_LINK_TRAIN_PAT_IDLE (2 << 28)
|
||||
#define DP_LINK_TRAIN_OFF (3 << 28)
|
||||
#define DP_LINK_TRAIN_MASK (3 << 28)
|
||||
#define DP_LINK_TRAIN_SHIFT 28
|
||||
|
||||
/* Signal voltages. These are mostly controlled by the other end */
|
||||
#define DP_VOLTAGE_0_4 (0 << 25)
|
||||
#define DP_VOLTAGE_0_6 (1 << 25)
|
||||
#define DP_VOLTAGE_0_8 (2 << 25)
|
||||
#define DP_VOLTAGE_1_2 (3 << 25)
|
||||
#define DP_VOLTAGE_MASK (7 << 25)
|
||||
#define DP_VOLTAGE_SHIFT 25
|
||||
|
||||
/* Signal pre-emphasis levels, like voltages, the other end tells us what
|
||||
* they want
|
||||
*/
|
||||
#define DP_PRE_EMPHASIS_0 (0 << 22)
|
||||
#define DP_PRE_EMPHASIS_3_5 (1 << 22)
|
||||
#define DP_PRE_EMPHASIS_6 (2 << 22)
|
||||
#define DP_PRE_EMPHASIS_9_5 (3 << 22)
|
||||
#define DP_PRE_EMPHASIS_MASK (7 << 22)
|
||||
#define DP_PRE_EMPHASIS_SHIFT 22
|
||||
|
||||
/* How many wires to use. I guess 3 was too hard */
|
||||
#define DP_PORT_WIDTH_1 (0 << 19)
|
||||
#define DP_PORT_WIDTH_2 (1 << 19)
|
||||
#define DP_PORT_WIDTH_4 (3 << 19)
|
||||
#define DP_PORT_WIDTH_MASK (7 << 19)
|
||||
|
||||
/* Mystic DPCD version 1.1 special mode */
|
||||
#define DP_ENHANCED_FRAMING (1 << 18)
|
||||
|
||||
/** locked once port is enabled */
|
||||
#define DP_PORT_REVERSAL (1 << 15)
|
||||
|
||||
/** sends the clock on lane 15 of the PEG for debug */
|
||||
#define DP_CLOCK_OUTPUT_ENABLE (1 << 13)
|
||||
|
||||
#define DP_SCRAMBLING_DISABLE (1 << 12)
|
||||
#define DP_SCRAMBLING_DISABLE_IRONLAKE (1 << 7)
|
||||
|
||||
/** limit RGB values to avoid confusing TVs */
|
||||
#define DP_COLOR_RANGE_16_235 (1 << 8)
|
||||
|
||||
/** Turn on the audio link */
|
||||
#define DP_AUDIO_OUTPUT_ENABLE (1 << 6)
|
||||
|
||||
/** vs and hs sync polarity */
|
||||
#define DP_SYNC_VS_HIGH (1 << 4)
|
||||
#define DP_SYNC_HS_HIGH (1 << 3)
|
||||
|
||||
/** A fantasy */
|
||||
#define DP_DETECTED (1 << 2)
|
||||
|
||||
/** The aux channel provides a way to talk to the
|
||||
* signal sink for DDC etc. Max packet size supported
|
||||
* is 20 bytes in each direction, hence the 5 fixed
|
||||
* data registers
|
||||
*/
|
||||
#define DPB_AUX_CH_CTL 0x64110
|
||||
#define DPB_AUX_CH_DATA1 0x64114
|
||||
#define DPB_AUX_CH_DATA2 0x64118
|
||||
#define DPB_AUX_CH_DATA3 0x6411c
|
||||
#define DPB_AUX_CH_DATA4 0x64120
|
||||
#define DPB_AUX_CH_DATA5 0x64124
|
||||
|
||||
#define DPC_AUX_CH_CTL 0x64210
|
||||
#define DPC_AUX_CH_DATA1 0x64214
|
||||
#define DPC_AUX_CH_DATA2 0x64218
|
||||
#define DPC_AUX_CH_DATA3 0x6421c
|
||||
#define DPC_AUX_CH_DATA4 0x64220
|
||||
#define DPC_AUX_CH_DATA5 0x64224
|
||||
|
||||
#define DP_AUX_CH_CTL_SEND_BUSY (1 << 31)
|
||||
#define DP_AUX_CH_CTL_DONE (1 << 30)
|
||||
#define DP_AUX_CH_CTL_INTERRUPT (1 << 29)
|
||||
#define DP_AUX_CH_CTL_TIME_OUT_ERROR (1 << 28)
|
||||
#define DP_AUX_CH_CTL_TIME_OUT_400us (0 << 26)
|
||||
#define DP_AUX_CH_CTL_TIME_OUT_600us (1 << 26)
|
||||
#define DP_AUX_CH_CTL_TIME_OUT_800us (2 << 26)
|
||||
#define DP_AUX_CH_CTL_TIME_OUT_1600us (3 << 26)
|
||||
#define DP_AUX_CH_CTL_TIME_OUT_MASK (3 << 26)
|
||||
#define DP_AUX_CH_CTL_RECEIVE_ERROR (1 << 25)
|
||||
#define DP_AUX_CH_CTL_MESSAGE_SIZE_MASK (0x1f << 20)
|
||||
#define DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT 20
|
||||
#define DP_AUX_CH_CTL_PRECHARGE_2US_MASK (0xf << 16)
|
||||
#define DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT 16
|
||||
#define DP_AUX_CH_CTL_AUX_AKSV_SELECT (1 << 15)
|
||||
#define DP_AUX_CH_CTL_MANCHESTER_TEST (1 << 14)
|
||||
#define DP_AUX_CH_CTL_SYNC_TEST (1 << 13)
|
||||
#define DP_AUX_CH_CTL_DEGLITCH_TEST (1 << 12)
|
||||
#define DP_AUX_CH_CTL_PRECHARGE_TEST (1 << 11)
|
||||
#define DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK (0x7ff)
|
||||
#define DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT 0
|
||||
|
||||
/*
|
||||
* Computing GMCH M and N values for the Display Port link
|
||||
*
|
||||
* GMCH M/N = dot clock * bytes per pixel / ls_clk * # of lanes
|
||||
*
|
||||
* ls_clk (we assume) is the DP link clock (1.62 or 2.7 GHz)
|
||||
*
|
||||
* The GMCH value is used internally
|
||||
*
|
||||
* bytes_per_pixel is the number of bytes coming out of the plane,
|
||||
* which is after the LUTs, so we want the bytes for our color format.
|
||||
* For our current usage, this is always 3, one byte for R, G and B.
|
||||
*/
|
||||
|
||||
#define _PIPEA_GMCH_DATA_M 0x70050
|
||||
#define _PIPEB_GMCH_DATA_M 0x71050
|
||||
|
||||
/* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */
|
||||
#define PIPE_GMCH_DATA_M_TU_SIZE_MASK (0x3f << 25)
|
||||
#define PIPE_GMCH_DATA_M_TU_SIZE_SHIFT 25
|
||||
|
||||
#define PIPE_GMCH_DATA_M_MASK (0xffffff)
|
||||
|
||||
#define _PIPEA_GMCH_DATA_N 0x70054
|
||||
#define _PIPEB_GMCH_DATA_N 0x71054
|
||||
#define PIPE_GMCH_DATA_N_MASK (0xffffff)
|
||||
|
||||
/*
|
||||
* Computing Link M and N values for the Display Port link
|
||||
*
|
||||
* Link M / N = pixel_clock / ls_clk
|
||||
*
|
||||
* (the DP spec calls pixel_clock the 'strm_clk')
|
||||
*
|
||||
* The Link value is transmitted in the Main Stream
|
||||
* Attributes and VB-ID.
|
||||
*/
|
||||
|
||||
#define _PIPEA_DP_LINK_M 0x70060
|
||||
#define _PIPEB_DP_LINK_M 0x71060
|
||||
#define PIPEA_DP_LINK_M_MASK (0xffffff)
|
||||
|
||||
#define _PIPEA_DP_LINK_N 0x70064
|
||||
#define _PIPEB_DP_LINK_N 0x71064
|
||||
#define PIPEA_DP_LINK_N_MASK (0xffffff)
|
||||
|
||||
#define PIPE_GMCH_DATA_M(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_M, _PIPEB_GMCH_DATA_M)
|
||||
#define PIPE_GMCH_DATA_N(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_N, _PIPEB_GMCH_DATA_N)
|
||||
#define PIPE_DP_LINK_M(pipe) _PIPE(pipe, _PIPEA_DP_LINK_M, _PIPEB_DP_LINK_M)
|
||||
#define PIPE_DP_LINK_N(pipe) _PIPE(pipe, _PIPEA_DP_LINK_N, _PIPEB_DP_LINK_N)
|
||||
|
||||
#define PIPE_BPC_MASK (7 << 5)
|
||||
#define PIPE_8BPC (0 << 5)
|
||||
#define PIPE_10BPC (1 << 5)
|
||||
#define PIPE_6BPC (2 << 5)
|
||||
|
||||
#endif
|
||||
|
@@ -1291,7 +1291,6 @@ psb_intel_sdvo_get_analog_edid(struct drm_connector *connector)
|
||||
|
||||
return drm_get_edid(connector,
|
||||
&dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static enum drm_connector_status
|
||||
@@ -1342,7 +1341,6 @@ psb_intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
|
||||
}
|
||||
} else
|
||||
status = connector_status_disconnected;
|
||||
connector->display_info.raw_edid = NULL;
|
||||
kfree(edid);
|
||||
}
|
||||
|
||||
@@ -1403,7 +1401,6 @@ psb_intel_sdvo_detect(struct drm_connector *connector, bool force)
|
||||
ret = connector_status_disconnected;
|
||||
else
|
||||
ret = connector_status_connected;
|
||||
connector->display_info.raw_edid = NULL;
|
||||
kfree(edid);
|
||||
} else
|
||||
ret = connector_status_connected;
|
||||
@@ -1452,7 +1449,6 @@ static void psb_intel_sdvo_get_ddc_modes(struct drm_connector *connector)
|
||||
drm_add_edid_modes(connector, edid);
|
||||
}
|
||||
|
||||
connector->display_info.raw_edid = NULL;
|
||||
kfree(edid);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user