Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "Just a few straggling fixes I hoovered up, and an intel fixes pull from Daniel which fixes some regressions, and some mgag200 fixes from Matrox." * 'drm-next' of git://people.freedesktop.org/~airlied/linux: drm/mgag200: Fix framebuffer base address programming drm/mgag200: Convert counter delays to jiffies drm/mgag200: Fix writes into MGA1064_PIX_CLK_CTL register drm/mgag200: Don't change unrelated registers during modeset drm: Only print a debug message when the polled connector has changed drm: Make the HPD status updates debug logs more readable drm: Use names of ioctls in debug traces drm: Remove pointless '-' characters from drm_fb_helper documentation drm: Add kernel-doc for drm_fb_helper_funcs->initial_config drm: refactor call to request_module drm: Don't prune modes loudly when a connector is disconnected drm: Add missing break in the command line mode parsing code drm/i915: clear the stolen fb before resuming Revert "drm/i915: Calculate correct stolen size for GEN7+" drm/i915: hsw: fix link training for eDP on port-A Revert "drm/i915: revert eDP bpp clamping code changes" drm: don't check modeset locks in panic handler drm/i915: Fix pipe enabled mask for pipe C in WM calculations drm/mm: fix dump table BUG drm/i915: Always normalize return timeout for wait_timeout_ioctl
This commit is contained in:
commit
fea0f9ff56
@ -78,6 +78,10 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev)
|
|||||||
{
|
{
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
|
/* Locking is currently fubar in the panic handler. */
|
||||||
|
if (oops_in_progress)
|
||||||
|
return;
|
||||||
|
|
||||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||||
WARN_ON(!mutex_is_locked(&crtc->mutex));
|
WARN_ON(!mutex_is_locked(&crtc->mutex));
|
||||||
|
|
||||||
@ -246,6 +250,7 @@ char *drm_get_connector_status_name(enum drm_connector_status status)
|
|||||||
else
|
else
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(drm_get_connector_status_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_mode_object_get - allocate a new modeset identifier
|
* drm_mode_object_get - allocate a new modeset identifier
|
||||||
|
@ -121,6 +121,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
|||||||
connector->helper_private;
|
connector->helper_private;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int mode_flags = 0;
|
int mode_flags = 0;
|
||||||
|
bool verbose_prune = true;
|
||||||
|
|
||||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
|
||||||
drm_get_connector_name(connector));
|
drm_get_connector_name(connector));
|
||||||
@ -149,6 +150,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
|||||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
|
||||||
connector->base.id, drm_get_connector_name(connector));
|
connector->base.id, drm_get_connector_name(connector));
|
||||||
drm_mode_connector_update_edid_property(connector, NULL);
|
drm_mode_connector_update_edid_property(connector, NULL);
|
||||||
|
verbose_prune = false;
|
||||||
goto prune;
|
goto prune;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +184,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
|||||||
}
|
}
|
||||||
|
|
||||||
prune:
|
prune:
|
||||||
drm_mode_prune_invalid(dev, &connector->modes, true);
|
drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
|
||||||
|
|
||||||
if (list_empty(&connector->modes))
|
if (list_empty(&connector->modes))
|
||||||
return 0;
|
return 0;
|
||||||
@ -1005,12 +1007,20 @@ static void output_poll_execute(struct work_struct *work)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
connector->status = connector->funcs->detect(connector, false);
|
connector->status = connector->funcs->detect(connector, false);
|
||||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
|
if (old_status != connector->status) {
|
||||||
connector->base.id,
|
const char *old, *new;
|
||||||
drm_get_connector_name(connector),
|
|
||||||
old_status, connector->status);
|
old = drm_get_connector_status_name(old_status);
|
||||||
if (old_status != connector->status)
|
new = drm_get_connector_status_name(connector->status);
|
||||||
|
|
||||||
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
|
||||||
|
"status updated from %s to %s\n",
|
||||||
|
connector->base.id,
|
||||||
|
drm_get_connector_name(connector),
|
||||||
|
old, new);
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&dev->mode_config.mutex);
|
mutex_unlock(&dev->mode_config.mutex);
|
||||||
@ -1083,10 +1093,11 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
|
|||||||
old_status = connector->status;
|
old_status = connector->status;
|
||||||
|
|
||||||
connector->status = connector->funcs->detect(connector, false);
|
connector->status = connector->funcs->detect(connector, false);
|
||||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
|
||||||
connector->base.id,
|
connector->base.id,
|
||||||
drm_get_connector_name(connector),
|
drm_get_connector_name(connector),
|
||||||
old_status, connector->status);
|
drm_get_connector_status_name(old_status),
|
||||||
|
drm_get_connector_status_name(connector->status));
|
||||||
if (old_status != connector->status)
|
if (old_status != connector->status)
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ static int drm_version(struct drm_device *dev, void *data,
|
|||||||
struct drm_file *file_priv);
|
struct drm_file *file_priv);
|
||||||
|
|
||||||
#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
|
#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
|
||||||
[DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0}
|
[DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
|
||||||
|
|
||||||
/** Ioctl table */
|
/** Ioctl table */
|
||||||
static const struct drm_ioctl_desc drm_ioctls[] = {
|
static const struct drm_ioctl_desc drm_ioctls[] = {
|
||||||
@ -375,7 +375,7 @@ long drm_ioctl(struct file *filp,
|
|||||||
{
|
{
|
||||||
struct drm_file *file_priv = filp->private_data;
|
struct drm_file *file_priv = filp->private_data;
|
||||||
struct drm_device *dev;
|
struct drm_device *dev;
|
||||||
const struct drm_ioctl_desc *ioctl;
|
const struct drm_ioctl_desc *ioctl = NULL;
|
||||||
drm_ioctl_t *func;
|
drm_ioctl_t *func;
|
||||||
unsigned int nr = DRM_IOCTL_NR(cmd);
|
unsigned int nr = DRM_IOCTL_NR(cmd);
|
||||||
int retcode = -EINVAL;
|
int retcode = -EINVAL;
|
||||||
@ -392,11 +392,6 @@ long drm_ioctl(struct file *filp,
|
|||||||
atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
|
atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
|
||||||
++file_priv->ioctl_count;
|
++file_priv->ioctl_count;
|
||||||
|
|
||||||
DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
|
|
||||||
task_pid_nr(current), cmd, nr,
|
|
||||||
(long)old_encode_dev(file_priv->minor->device),
|
|
||||||
file_priv->authenticated);
|
|
||||||
|
|
||||||
if ((nr >= DRM_CORE_IOCTL_COUNT) &&
|
if ((nr >= DRM_CORE_IOCTL_COUNT) &&
|
||||||
((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
|
((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
|
||||||
goto err_i1;
|
goto err_i1;
|
||||||
@ -417,6 +412,11 @@ long drm_ioctl(struct file *filp,
|
|||||||
} else
|
} else
|
||||||
goto err_i1;
|
goto err_i1;
|
||||||
|
|
||||||
|
DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
|
||||||
|
task_pid_nr(current),
|
||||||
|
(long)old_encode_dev(file_priv->minor->device),
|
||||||
|
file_priv->authenticated, ioctl->name);
|
||||||
|
|
||||||
/* Do not trust userspace, use our own definition */
|
/* Do not trust userspace, use our own definition */
|
||||||
func = ioctl->func;
|
func = ioctl->func;
|
||||||
/* is there a local override? */
|
/* is there a local override? */
|
||||||
@ -471,6 +471,12 @@ long drm_ioctl(struct file *filp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
err_i1:
|
err_i1:
|
||||||
|
if (!ioctl)
|
||||||
|
DRM_DEBUG("invalid iotcl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
|
||||||
|
task_pid_nr(current),
|
||||||
|
(long)old_encode_dev(file_priv->minor->device),
|
||||||
|
file_priv->authenticated, cmd, nr);
|
||||||
|
|
||||||
if (kdata != stack_kdata)
|
if (kdata != stack_kdata)
|
||||||
kfree(kdata);
|
kfree(kdata);
|
||||||
atomic_dec(&dev->ioctl_count);
|
atomic_dec(&dev->ioctl_count);
|
||||||
|
@ -54,16 +54,12 @@ int drm_i2c_encoder_init(struct drm_device *dev,
|
|||||||
struct i2c_adapter *adap,
|
struct i2c_adapter *adap,
|
||||||
const struct i2c_board_info *info)
|
const struct i2c_board_info *info)
|
||||||
{
|
{
|
||||||
char modalias[sizeof(I2C_MODULE_PREFIX)
|
|
||||||
+ I2C_NAME_SIZE];
|
|
||||||
struct module *module = NULL;
|
struct module *module = NULL;
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct drm_i2c_encoder_driver *encoder_drv;
|
struct drm_i2c_encoder_driver *encoder_drv;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
snprintf(modalias, sizeof(modalias),
|
request_module("%s%s", I2C_MODULE_PREFIX, info->type);
|
||||||
"%s%s", I2C_MODULE_PREFIX, info->type);
|
|
||||||
request_module(modalias);
|
|
||||||
|
|
||||||
client = i2c_new_device(adap, info);
|
client = i2c_new_device(adap, info);
|
||||||
if (!client) {
|
if (!client) {
|
||||||
|
@ -755,33 +755,35 @@ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
|
|||||||
EXPORT_SYMBOL(drm_mm_debug_table);
|
EXPORT_SYMBOL(drm_mm_debug_table);
|
||||||
|
|
||||||
#if defined(CONFIG_DEBUG_FS)
|
#if defined(CONFIG_DEBUG_FS)
|
||||||
|
static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry)
|
||||||
|
{
|
||||||
|
unsigned long hole_start, hole_end, hole_size;
|
||||||
|
|
||||||
|
if (entry->hole_follows) {
|
||||||
|
hole_start = drm_mm_hole_node_start(entry);
|
||||||
|
hole_end = drm_mm_hole_node_end(entry);
|
||||||
|
hole_size = hole_end - hole_start;
|
||||||
|
seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n",
|
||||||
|
hole_start, hole_end, hole_size);
|
||||||
|
return hole_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
|
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
|
||||||
{
|
{
|
||||||
struct drm_mm_node *entry;
|
struct drm_mm_node *entry;
|
||||||
unsigned long total_used = 0, total_free = 0, total = 0;
|
unsigned long total_used = 0, total_free = 0, total = 0;
|
||||||
unsigned long hole_start, hole_end, hole_size;
|
|
||||||
|
|
||||||
hole_start = drm_mm_hole_node_start(&mm->head_node);
|
total_free += drm_mm_dump_hole(m, &mm->head_node);
|
||||||
hole_end = drm_mm_hole_node_end(&mm->head_node);
|
|
||||||
hole_size = hole_end - hole_start;
|
|
||||||
if (hole_size)
|
|
||||||
seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n",
|
|
||||||
hole_start, hole_end, hole_size);
|
|
||||||
total_free += hole_size;
|
|
||||||
|
|
||||||
drm_mm_for_each_node(entry, mm) {
|
drm_mm_for_each_node(entry, mm) {
|
||||||
seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n",
|
seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n",
|
||||||
entry->start, entry->start + entry->size,
|
entry->start, entry->start + entry->size,
|
||||||
entry->size);
|
entry->size);
|
||||||
total_used += entry->size;
|
total_used += entry->size;
|
||||||
if (entry->hole_follows) {
|
total_free += drm_mm_dump_hole(m, entry);
|
||||||
hole_start = drm_mm_hole_node_start(entry);
|
|
||||||
hole_end = drm_mm_hole_node_end(entry);
|
|
||||||
hole_size = hole_end - hole_start;
|
|
||||||
seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n",
|
|
||||||
hole_start, hole_end, hole_size);
|
|
||||||
total_free += hole_size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
total = total_free + total_used;
|
total = total_free + total_used;
|
||||||
|
|
||||||
|
@ -1143,6 +1143,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
|||||||
was_digit = false;
|
was_digit = false;
|
||||||
} else
|
} else
|
||||||
goto done;
|
goto done;
|
||||||
|
break;
|
||||||
case '0' ... '9':
|
case '0' ... '9':
|
||||||
was_digit = true;
|
was_digit = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1045,6 +1045,8 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
|
|||||||
if (timeout) {
|
if (timeout) {
|
||||||
struct timespec sleep_time = timespec_sub(now, before);
|
struct timespec sleep_time = timespec_sub(now, before);
|
||||||
*timeout = timespec_sub(*timeout, sleep_time);
|
*timeout = timespec_sub(*timeout, sleep_time);
|
||||||
|
if (!timespec_valid(timeout)) /* i.e. negative time remains */
|
||||||
|
set_normalized_timespec(timeout, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (end) {
|
switch (end) {
|
||||||
@ -1053,8 +1055,6 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
|
|||||||
case -ERESTARTSYS: /* Signal */
|
case -ERESTARTSYS: /* Signal */
|
||||||
return (int)end;
|
return (int)end;
|
||||||
case 0: /* Timeout */
|
case 0: /* Timeout */
|
||||||
if (timeout)
|
|
||||||
set_normalized_timespec(timeout, 0, 0);
|
|
||||||
return -ETIME;
|
return -ETIME;
|
||||||
default: /* Completed */
|
default: /* Completed */
|
||||||
WARN_ON(end < 0); /* We're not aware of other errors */
|
WARN_ON(end < 0); /* We're not aware of other errors */
|
||||||
@ -2377,10 +2377,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
|
||||||
ret = __wait_seqno(ring, seqno, reset_counter, true, timeout);
|
ret = __wait_seqno(ring, seqno, reset_counter, true, timeout);
|
||||||
if (timeout) {
|
if (timeout)
|
||||||
WARN_ON(!timespec_valid(timeout));
|
|
||||||
args->timeout_ns = timespec_to_ns(timeout);
|
args->timeout_ns = timespec_to_ns(timeout);
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -709,15 +709,6 @@ static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl)
|
|||||||
return snb_gmch_ctl << 25; /* 32 MB units */
|
return snb_gmch_ctl << 25; /* 32 MB units */
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t gen7_get_stolen_size(u16 snb_gmch_ctl)
|
|
||||||
{
|
|
||||||
static const int stolen_decoder[] = {
|
|
||||||
0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352};
|
|
||||||
snb_gmch_ctl >>= IVB_GMCH_GMS_SHIFT;
|
|
||||||
snb_gmch_ctl &= IVB_GMCH_GMS_MASK;
|
|
||||||
return stolen_decoder[snb_gmch_ctl] << 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int gen6_gmch_probe(struct drm_device *dev,
|
static int gen6_gmch_probe(struct drm_device *dev,
|
||||||
size_t *gtt_total,
|
size_t *gtt_total,
|
||||||
size_t *stolen,
|
size_t *stolen,
|
||||||
@ -747,11 +738,7 @@ static int gen6_gmch_probe(struct drm_device *dev,
|
|||||||
pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
|
pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
|
||||||
gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl);
|
gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl);
|
||||||
|
|
||||||
if (IS_GEN7(dev) && !IS_VALLEYVIEW(dev))
|
*stolen = gen6_get_stolen_size(snb_gmch_ctl);
|
||||||
*stolen = gen7_get_stolen_size(snb_gmch_ctl);
|
|
||||||
else
|
|
||||||
*stolen = gen6_get_stolen_size(snb_gmch_ctl);
|
|
||||||
|
|
||||||
*gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT;
|
*gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT;
|
||||||
|
|
||||||
/* For Modern GENs the PTEs and register space are split in the BAR */
|
/* For Modern GENs the PTEs and register space are split in the BAR */
|
||||||
|
@ -46,8 +46,6 @@
|
|||||||
#define SNB_GMCH_GGMS_MASK 0x3
|
#define SNB_GMCH_GGMS_MASK 0x3
|
||||||
#define SNB_GMCH_GMS_SHIFT 3 /* Graphics Mode Select */
|
#define SNB_GMCH_GMS_SHIFT 3 /* Graphics Mode Select */
|
||||||
#define SNB_GMCH_GMS_MASK 0x1f
|
#define SNB_GMCH_GMS_MASK 0x1f
|
||||||
#define IVB_GMCH_GMS_SHIFT 4
|
|
||||||
#define IVB_GMCH_GMS_MASK 0xf
|
|
||||||
|
|
||||||
|
|
||||||
/* PCI config space */
|
/* PCI config space */
|
||||||
|
@ -1265,6 +1265,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
|
|||||||
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
|
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
|
||||||
intel_dp_start_link_train(intel_dp);
|
intel_dp_start_link_train(intel_dp);
|
||||||
intel_dp_complete_link_train(intel_dp);
|
intel_dp_complete_link_train(intel_dp);
|
||||||
|
if (port != PORT_A)
|
||||||
|
intel_dp_stop_link_train(intel_dp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1326,6 +1328,9 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
|
|||||||
} else if (type == INTEL_OUTPUT_EDP) {
|
} else if (type == INTEL_OUTPUT_EDP) {
|
||||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||||
|
|
||||||
|
if (port == PORT_A)
|
||||||
|
intel_dp_stop_link_train(intel_dp);
|
||||||
|
|
||||||
ironlake_edp_backlight_on(intel_dp);
|
ironlake_edp_backlight_on(intel_dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,6 +702,9 @@ intel_dp_compute_config(struct intel_encoder *encoder,
|
|||||||
/* Walk through all bpp values. Luckily they're all nicely spaced with 2
|
/* Walk through all bpp values. Luckily they're all nicely spaced with 2
|
||||||
* bpc in between. */
|
* bpc in between. */
|
||||||
bpp = min_t(int, 8*3, pipe_config->pipe_bpp);
|
bpp = min_t(int, 8*3, pipe_config->pipe_bpp);
|
||||||
|
if (is_edp(intel_dp) && dev_priv->edp.bpp)
|
||||||
|
bpp = min_t(int, bpp, dev_priv->edp.bpp);
|
||||||
|
|
||||||
for (; bpp >= 6*3; bpp -= 2*3) {
|
for (; bpp >= 6*3; bpp -= 2*3) {
|
||||||
mode_rate = intel_dp_link_required(target_clock, bpp);
|
mode_rate = intel_dp_link_required(target_clock, bpp);
|
||||||
|
|
||||||
@ -739,6 +742,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
|
|||||||
intel_dp->link_bw = bws[clock];
|
intel_dp->link_bw = bws[clock];
|
||||||
intel_dp->lane_count = lane_count;
|
intel_dp->lane_count = lane_count;
|
||||||
adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
|
adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
|
||||||
|
pipe_config->pipe_bpp = bpp;
|
||||||
pipe_config->pixel_target_clock = target_clock;
|
pipe_config->pixel_target_clock = target_clock;
|
||||||
|
|
||||||
DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
|
DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
|
||||||
@ -751,20 +755,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
|
|||||||
target_clock, adjusted_mode->clock,
|
target_clock, adjusted_mode->clock,
|
||||||
&pipe_config->dp_m_n);
|
&pipe_config->dp_m_n);
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX: We have a strange regression where using the vbt edp bpp value
|
|
||||||
* for the link bw computation results in black screens, the panel only
|
|
||||||
* works when we do the computation at the usual 24bpp (but still
|
|
||||||
* requires us to use 18bpp). Until that's fully debugged, stay
|
|
||||||
* bug-for-bug compatible with the old code.
|
|
||||||
*/
|
|
||||||
if (is_edp(intel_dp) && dev_priv->edp.bpp) {
|
|
||||||
DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n",
|
|
||||||
bpp, dev_priv->edp.bpp);
|
|
||||||
bpp = min_t(int, bpp, dev_priv->edp.bpp);
|
|
||||||
}
|
|
||||||
pipe_config->pipe_bpp = bpp;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1389,6 +1379,7 @@ static void intel_enable_dp(struct intel_encoder *encoder)
|
|||||||
ironlake_edp_panel_on(intel_dp);
|
ironlake_edp_panel_on(intel_dp);
|
||||||
ironlake_edp_panel_vdd_off(intel_dp, true);
|
ironlake_edp_panel_vdd_off(intel_dp, true);
|
||||||
intel_dp_complete_link_train(intel_dp);
|
intel_dp_complete_link_train(intel_dp);
|
||||||
|
intel_dp_stop_link_train(intel_dp);
|
||||||
ironlake_edp_backlight_on(intel_dp);
|
ironlake_edp_backlight_on(intel_dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1711,10 +1702,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
|
|||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
enum port port = intel_dig_port->port;
|
enum port port = intel_dig_port->port;
|
||||||
int ret;
|
int ret;
|
||||||
uint32_t temp;
|
|
||||||
|
|
||||||
if (HAS_DDI(dev)) {
|
if (HAS_DDI(dev)) {
|
||||||
temp = I915_READ(DP_TP_CTL(port));
|
uint32_t temp = I915_READ(DP_TP_CTL(port));
|
||||||
|
|
||||||
if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
|
if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
|
||||||
temp |= DP_TP_CTL_SCRAMBLE_DISABLE;
|
temp |= DP_TP_CTL_SCRAMBLE_DISABLE;
|
||||||
@ -1724,18 +1714,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
|
|||||||
temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
|
temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
|
||||||
switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
|
switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
|
||||||
case DP_TRAINING_PATTERN_DISABLE:
|
case DP_TRAINING_PATTERN_DISABLE:
|
||||||
|
|
||||||
if (port != PORT_A) {
|
|
||||||
temp |= DP_TP_CTL_LINK_TRAIN_IDLE;
|
|
||||||
I915_WRITE(DP_TP_CTL(port), temp);
|
|
||||||
|
|
||||||
if (wait_for((I915_READ(DP_TP_STATUS(port)) &
|
|
||||||
DP_TP_STATUS_IDLE_DONE), 1))
|
|
||||||
DRM_ERROR("Timed out waiting for DP idle patterns\n");
|
|
||||||
|
|
||||||
temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
temp |= DP_TP_CTL_LINK_TRAIN_NORMAL;
|
temp |= DP_TP_CTL_LINK_TRAIN_NORMAL;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1811,6 +1789,37 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
|
||||||
|
{
|
||||||
|
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
|
||||||
|
struct drm_device *dev = intel_dig_port->base.base.dev;
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
enum port port = intel_dig_port->port;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
if (!HAS_DDI(dev))
|
||||||
|
return;
|
||||||
|
|
||||||
|
val = I915_READ(DP_TP_CTL(port));
|
||||||
|
val &= ~DP_TP_CTL_LINK_TRAIN_MASK;
|
||||||
|
val |= DP_TP_CTL_LINK_TRAIN_IDLE;
|
||||||
|
I915_WRITE(DP_TP_CTL(port), val);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On PORT_A we can have only eDP in SST mode. There the only reason
|
||||||
|
* we need to set idle transmission mode is to work around a HW issue
|
||||||
|
* where we enable the pipe while not in idle link-training mode.
|
||||||
|
* In this case there is requirement to wait for a minimum number of
|
||||||
|
* idle patterns to be sent.
|
||||||
|
*/
|
||||||
|
if (port == PORT_A)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wait_for((I915_READ(DP_TP_STATUS(port)) & DP_TP_STATUS_IDLE_DONE),
|
||||||
|
1))
|
||||||
|
DRM_ERROR("Timed out waiting for DP idle patterns\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Enable corresponding port and start training pattern 1 */
|
/* Enable corresponding port and start training pattern 1 */
|
||||||
void
|
void
|
||||||
intel_dp_start_link_train(struct intel_dp *intel_dp)
|
intel_dp_start_link_train(struct intel_dp *intel_dp)
|
||||||
@ -1953,10 +1962,19 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
|
|||||||
++tries;
|
++tries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intel_dp_set_idle_link_train(intel_dp);
|
||||||
|
|
||||||
|
intel_dp->DP = DP;
|
||||||
|
|
||||||
if (channel_eq)
|
if (channel_eq)
|
||||||
DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
|
DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
|
||||||
|
|
||||||
intel_dp_set_link_train(intel_dp, DP, DP_TRAINING_PATTERN_DISABLE);
|
}
|
||||||
|
|
||||||
|
void intel_dp_stop_link_train(struct intel_dp *intel_dp)
|
||||||
|
{
|
||||||
|
intel_dp_set_link_train(intel_dp, intel_dp->DP,
|
||||||
|
DP_TRAINING_PATTERN_DISABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2164,6 +2182,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
|
|||||||
drm_get_encoder_name(&intel_encoder->base));
|
drm_get_encoder_name(&intel_encoder->base));
|
||||||
intel_dp_start_link_train(intel_dp);
|
intel_dp_start_link_train(intel_dp);
|
||||||
intel_dp_complete_link_train(intel_dp);
|
intel_dp_complete_link_train(intel_dp);
|
||||||
|
intel_dp_stop_link_train(intel_dp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,6 +499,7 @@ extern void intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
|
|||||||
extern void intel_dp_init_link_config(struct intel_dp *intel_dp);
|
extern void intel_dp_init_link_config(struct intel_dp *intel_dp);
|
||||||
extern void intel_dp_start_link_train(struct intel_dp *intel_dp);
|
extern void intel_dp_start_link_train(struct intel_dp *intel_dp);
|
||||||
extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
|
extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
|
||||||
|
extern void intel_dp_stop_link_train(struct intel_dp *intel_dp);
|
||||||
extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
|
extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
|
||||||
extern void intel_dp_encoder_destroy(struct drm_encoder *encoder);
|
extern void intel_dp_encoder_destroy(struct drm_encoder *encoder);
|
||||||
extern void intel_dp_check_link_status(struct intel_dp *intel_dp);
|
extern void intel_dp_check_link_status(struct intel_dp *intel_dp);
|
||||||
|
@ -262,10 +262,22 @@ void intel_fbdev_fini(struct drm_device *dev)
|
|||||||
void intel_fbdev_set_suspend(struct drm_device *dev, int state)
|
void intel_fbdev_set_suspend(struct drm_device *dev, int state)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
if (!dev_priv->fbdev)
|
struct intel_fbdev *ifbdev = dev_priv->fbdev;
|
||||||
|
struct fb_info *info;
|
||||||
|
|
||||||
|
if (!ifbdev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fb_set_suspend(dev_priv->fbdev->helper.fbdev, state);
|
info = ifbdev->helper.fbdev;
|
||||||
|
|
||||||
|
/* On resume from hibernation: If the object is shmemfs backed, it has
|
||||||
|
* been restored from swap. If the object is stolen however, it will be
|
||||||
|
* full of whatever garbage was left in there.
|
||||||
|
*/
|
||||||
|
if (!state && ifbdev->ifb.obj->stolen)
|
||||||
|
memset_io(info->screen_base, 0, info->screen_size);
|
||||||
|
|
||||||
|
fb_set_suspend(info, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_LICENSE("GPL and additional rights");
|
MODULE_LICENSE("GPL and additional rights");
|
||||||
|
@ -1301,17 +1301,17 @@ static void valleyview_update_wm(struct drm_device *dev)
|
|||||||
|
|
||||||
vlv_update_drain_latency(dev);
|
vlv_update_drain_latency(dev);
|
||||||
|
|
||||||
if (g4x_compute_wm0(dev, 0,
|
if (g4x_compute_wm0(dev, PIPE_A,
|
||||||
&valleyview_wm_info, latency_ns,
|
&valleyview_wm_info, latency_ns,
|
||||||
&valleyview_cursor_wm_info, latency_ns,
|
&valleyview_cursor_wm_info, latency_ns,
|
||||||
&planea_wm, &cursora_wm))
|
&planea_wm, &cursora_wm))
|
||||||
enabled |= 1;
|
enabled |= 1 << PIPE_A;
|
||||||
|
|
||||||
if (g4x_compute_wm0(dev, 1,
|
if (g4x_compute_wm0(dev, PIPE_B,
|
||||||
&valleyview_wm_info, latency_ns,
|
&valleyview_wm_info, latency_ns,
|
||||||
&valleyview_cursor_wm_info, latency_ns,
|
&valleyview_cursor_wm_info, latency_ns,
|
||||||
&planeb_wm, &cursorb_wm))
|
&planeb_wm, &cursorb_wm))
|
||||||
enabled |= 2;
|
enabled |= 1 << PIPE_B;
|
||||||
|
|
||||||
if (single_plane_enabled(enabled) &&
|
if (single_plane_enabled(enabled) &&
|
||||||
g4x_compute_srwm(dev, ffs(enabled) - 1,
|
g4x_compute_srwm(dev, ffs(enabled) - 1,
|
||||||
@ -1357,17 +1357,17 @@ static void g4x_update_wm(struct drm_device *dev)
|
|||||||
int plane_sr, cursor_sr;
|
int plane_sr, cursor_sr;
|
||||||
unsigned int enabled = 0;
|
unsigned int enabled = 0;
|
||||||
|
|
||||||
if (g4x_compute_wm0(dev, 0,
|
if (g4x_compute_wm0(dev, PIPE_A,
|
||||||
&g4x_wm_info, latency_ns,
|
&g4x_wm_info, latency_ns,
|
||||||
&g4x_cursor_wm_info, latency_ns,
|
&g4x_cursor_wm_info, latency_ns,
|
||||||
&planea_wm, &cursora_wm))
|
&planea_wm, &cursora_wm))
|
||||||
enabled |= 1;
|
enabled |= 1 << PIPE_A;
|
||||||
|
|
||||||
if (g4x_compute_wm0(dev, 1,
|
if (g4x_compute_wm0(dev, PIPE_B,
|
||||||
&g4x_wm_info, latency_ns,
|
&g4x_wm_info, latency_ns,
|
||||||
&g4x_cursor_wm_info, latency_ns,
|
&g4x_cursor_wm_info, latency_ns,
|
||||||
&planeb_wm, &cursorb_wm))
|
&planeb_wm, &cursorb_wm))
|
||||||
enabled |= 2;
|
enabled |= 1 << PIPE_B;
|
||||||
|
|
||||||
if (single_plane_enabled(enabled) &&
|
if (single_plane_enabled(enabled) &&
|
||||||
g4x_compute_srwm(dev, ffs(enabled) - 1,
|
g4x_compute_srwm(dev, ffs(enabled) - 1,
|
||||||
@ -1716,7 +1716,7 @@ static void ironlake_update_wm(struct drm_device *dev)
|
|||||||
unsigned int enabled;
|
unsigned int enabled;
|
||||||
|
|
||||||
enabled = 0;
|
enabled = 0;
|
||||||
if (g4x_compute_wm0(dev, 0,
|
if (g4x_compute_wm0(dev, PIPE_A,
|
||||||
&ironlake_display_wm_info,
|
&ironlake_display_wm_info,
|
||||||
ILK_LP0_PLANE_LATENCY,
|
ILK_LP0_PLANE_LATENCY,
|
||||||
&ironlake_cursor_wm_info,
|
&ironlake_cursor_wm_info,
|
||||||
@ -1727,10 +1727,10 @@ static void ironlake_update_wm(struct drm_device *dev)
|
|||||||
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
|
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
|
||||||
" plane %d, " "cursor: %d\n",
|
" plane %d, " "cursor: %d\n",
|
||||||
plane_wm, cursor_wm);
|
plane_wm, cursor_wm);
|
||||||
enabled |= 1;
|
enabled |= 1 << PIPE_A;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g4x_compute_wm0(dev, 1,
|
if (g4x_compute_wm0(dev, PIPE_B,
|
||||||
&ironlake_display_wm_info,
|
&ironlake_display_wm_info,
|
||||||
ILK_LP0_PLANE_LATENCY,
|
ILK_LP0_PLANE_LATENCY,
|
||||||
&ironlake_cursor_wm_info,
|
&ironlake_cursor_wm_info,
|
||||||
@ -1741,7 +1741,7 @@ static void ironlake_update_wm(struct drm_device *dev)
|
|||||||
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
|
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
|
||||||
" plane %d, cursor: %d\n",
|
" plane %d, cursor: %d\n",
|
||||||
plane_wm, cursor_wm);
|
plane_wm, cursor_wm);
|
||||||
enabled |= 2;
|
enabled |= 1 << PIPE_B;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1801,7 +1801,7 @@ static void sandybridge_update_wm(struct drm_device *dev)
|
|||||||
unsigned int enabled;
|
unsigned int enabled;
|
||||||
|
|
||||||
enabled = 0;
|
enabled = 0;
|
||||||
if (g4x_compute_wm0(dev, 0,
|
if (g4x_compute_wm0(dev, PIPE_A,
|
||||||
&sandybridge_display_wm_info, latency,
|
&sandybridge_display_wm_info, latency,
|
||||||
&sandybridge_cursor_wm_info, latency,
|
&sandybridge_cursor_wm_info, latency,
|
||||||
&plane_wm, &cursor_wm)) {
|
&plane_wm, &cursor_wm)) {
|
||||||
@ -1812,10 +1812,10 @@ static void sandybridge_update_wm(struct drm_device *dev)
|
|||||||
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
|
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
|
||||||
" plane %d, " "cursor: %d\n",
|
" plane %d, " "cursor: %d\n",
|
||||||
plane_wm, cursor_wm);
|
plane_wm, cursor_wm);
|
||||||
enabled |= 1;
|
enabled |= 1 << PIPE_A;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g4x_compute_wm0(dev, 1,
|
if (g4x_compute_wm0(dev, PIPE_B,
|
||||||
&sandybridge_display_wm_info, latency,
|
&sandybridge_display_wm_info, latency,
|
||||||
&sandybridge_cursor_wm_info, latency,
|
&sandybridge_cursor_wm_info, latency,
|
||||||
&plane_wm, &cursor_wm)) {
|
&plane_wm, &cursor_wm)) {
|
||||||
@ -1826,7 +1826,7 @@ static void sandybridge_update_wm(struct drm_device *dev)
|
|||||||
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
|
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
|
||||||
" plane %d, cursor: %d\n",
|
" plane %d, cursor: %d\n",
|
||||||
plane_wm, cursor_wm);
|
plane_wm, cursor_wm);
|
||||||
enabled |= 2;
|
enabled |= 1 << PIPE_B;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1904,7 +1904,7 @@ static void ivybridge_update_wm(struct drm_device *dev)
|
|||||||
unsigned int enabled;
|
unsigned int enabled;
|
||||||
|
|
||||||
enabled = 0;
|
enabled = 0;
|
||||||
if (g4x_compute_wm0(dev, 0,
|
if (g4x_compute_wm0(dev, PIPE_A,
|
||||||
&sandybridge_display_wm_info, latency,
|
&sandybridge_display_wm_info, latency,
|
||||||
&sandybridge_cursor_wm_info, latency,
|
&sandybridge_cursor_wm_info, latency,
|
||||||
&plane_wm, &cursor_wm)) {
|
&plane_wm, &cursor_wm)) {
|
||||||
@ -1915,10 +1915,10 @@ static void ivybridge_update_wm(struct drm_device *dev)
|
|||||||
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
|
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
|
||||||
" plane %d, " "cursor: %d\n",
|
" plane %d, " "cursor: %d\n",
|
||||||
plane_wm, cursor_wm);
|
plane_wm, cursor_wm);
|
||||||
enabled |= 1;
|
enabled |= 1 << PIPE_A;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g4x_compute_wm0(dev, 1,
|
if (g4x_compute_wm0(dev, PIPE_B,
|
||||||
&sandybridge_display_wm_info, latency,
|
&sandybridge_display_wm_info, latency,
|
||||||
&sandybridge_cursor_wm_info, latency,
|
&sandybridge_cursor_wm_info, latency,
|
||||||
&plane_wm, &cursor_wm)) {
|
&plane_wm, &cursor_wm)) {
|
||||||
@ -1929,10 +1929,10 @@ static void ivybridge_update_wm(struct drm_device *dev)
|
|||||||
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
|
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
|
||||||
" plane %d, cursor: %d\n",
|
" plane %d, cursor: %d\n",
|
||||||
plane_wm, cursor_wm);
|
plane_wm, cursor_wm);
|
||||||
enabled |= 2;
|
enabled |= 1 << PIPE_B;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g4x_compute_wm0(dev, 2,
|
if (g4x_compute_wm0(dev, PIPE_C,
|
||||||
&sandybridge_display_wm_info, latency,
|
&sandybridge_display_wm_info, latency,
|
||||||
&sandybridge_cursor_wm_info, latency,
|
&sandybridge_cursor_wm_info, latency,
|
||||||
&plane_wm, &cursor_wm)) {
|
&plane_wm, &cursor_wm)) {
|
||||||
@ -1943,7 +1943,7 @@ static void ivybridge_update_wm(struct drm_device *dev)
|
|||||||
DRM_DEBUG_KMS("FIFO watermarks For pipe C -"
|
DRM_DEBUG_KMS("FIFO watermarks For pipe C -"
|
||||||
" plane %d, cursor: %d\n",
|
" plane %d, cursor: %d\n",
|
||||||
plane_wm, cursor_wm);
|
plane_wm, cursor_wm);
|
||||||
enabled |= 3;
|
enabled |= 1 << PIPE_C;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -46,29 +46,26 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc)
|
|||||||
|
|
||||||
static inline void mga_wait_vsync(struct mga_device *mdev)
|
static inline void mga_wait_vsync(struct mga_device *mdev)
|
||||||
{
|
{
|
||||||
unsigned int count = 0;
|
unsigned long timeout = jiffies + HZ/10;
|
||||||
unsigned int status = 0;
|
unsigned int status = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
status = RREG32(MGAREG_Status);
|
status = RREG32(MGAREG_Status);
|
||||||
count++;
|
} while ((status & 0x08) && time_before(jiffies, timeout));
|
||||||
} while ((status & 0x08) && (count < 250000));
|
timeout = jiffies + HZ/10;
|
||||||
count = 0;
|
|
||||||
status = 0;
|
status = 0;
|
||||||
do {
|
do {
|
||||||
status = RREG32(MGAREG_Status);
|
status = RREG32(MGAREG_Status);
|
||||||
count++;
|
} while (!(status & 0x08) && time_before(jiffies, timeout));
|
||||||
} while (!(status & 0x08) && (count < 250000));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void mga_wait_busy(struct mga_device *mdev)
|
static inline void mga_wait_busy(struct mga_device *mdev)
|
||||||
{
|
{
|
||||||
unsigned int count = 0;
|
unsigned long timeout = jiffies + HZ;
|
||||||
unsigned int status = 0;
|
unsigned int status = 0;
|
||||||
do {
|
do {
|
||||||
status = RREG8(MGAREG_Status + 2);
|
status = RREG8(MGAREG_Status + 2);
|
||||||
count++;
|
} while ((status & 0x01) && time_before(jiffies, timeout));
|
||||||
} while ((status & 0x01) && (count < 500000));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -189,12 +186,12 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
|
|||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
|
tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
|
WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp |= MGA1064_REMHEADCTL_CLKDIS;
|
tmp |= MGA1064_REMHEADCTL_CLKDIS;
|
||||||
WREG_DAC(MGA1064_REMHEADCTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
/* select PLL Set C */
|
/* select PLL Set C */
|
||||||
tmp = RREG8(MGAREG_MEM_MISC_READ);
|
tmp = RREG8(MGAREG_MEM_MISC_READ);
|
||||||
@ -204,7 +201,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
|
|||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80;
|
tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
udelay(500);
|
udelay(500);
|
||||||
|
|
||||||
@ -212,7 +209,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
|
|||||||
WREG8(DAC_INDEX, MGA1064_VREF_CTL);
|
WREG8(DAC_INDEX, MGA1064_VREF_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp &= ~0x04;
|
tmp &= ~0x04;
|
||||||
WREG_DAC(MGA1064_VREF_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
udelay(50);
|
udelay(50);
|
||||||
|
|
||||||
@ -236,13 +233,13 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
|
|||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
|
tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
|
tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
|
WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp &= ~MGA1064_REMHEADCTL_CLKSL_MSK;
|
tmp &= ~MGA1064_REMHEADCTL_CLKSL_MSK;
|
||||||
tmp |= MGA1064_REMHEADCTL_CLKSL_PLL;
|
tmp |= MGA1064_REMHEADCTL_CLKSL_PLL;
|
||||||
WREG_DAC(MGA1064_REMHEADCTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
/* reset dotclock rate bit */
|
/* reset dotclock rate bit */
|
||||||
WREG8(MGAREG_SEQ_INDEX, 1);
|
WREG8(MGAREG_SEQ_INDEX, 1);
|
||||||
@ -253,7 +250,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
|
|||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
|
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
vcount = RREG8(MGAREG_VCOUNT);
|
vcount = RREG8(MGAREG_VCOUNT);
|
||||||
|
|
||||||
@ -318,7 +315,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
|
|||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
|
tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
tmp = RREG8(MGAREG_MEM_MISC_READ);
|
tmp = RREG8(MGAREG_MEM_MISC_READ);
|
||||||
tmp |= 0x3 << 2;
|
tmp |= 0x3 << 2;
|
||||||
@ -326,12 +323,12 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
|
|||||||
|
|
||||||
WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
|
WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
WREG_DAC(MGA1064_PIX_PLL_STAT, tmp & ~0x40);
|
WREG8(DAC_DATA, tmp & ~0x40);
|
||||||
|
|
||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
|
tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
WREG_DAC(MGA1064_EV_PIX_PLLC_M, m);
|
WREG_DAC(MGA1064_EV_PIX_PLLC_M, m);
|
||||||
WREG_DAC(MGA1064_EV_PIX_PLLC_N, n);
|
WREG_DAC(MGA1064_EV_PIX_PLLC_N, n);
|
||||||
@ -342,7 +339,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
|
|||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
|
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
udelay(500);
|
udelay(500);
|
||||||
|
|
||||||
@ -350,11 +347,11 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
|
|||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
|
tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
|
tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
|
WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
WREG_DAC(MGA1064_PIX_PLL_STAT, tmp | 0x40);
|
WREG8(DAC_DATA, tmp | 0x40);
|
||||||
|
|
||||||
tmp = RREG8(MGAREG_MEM_MISC_READ);
|
tmp = RREG8(MGAREG_MEM_MISC_READ);
|
||||||
tmp |= (0x3 << 2);
|
tmp |= (0x3 << 2);
|
||||||
@ -363,7 +360,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
|
|||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
|
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -416,7 +413,7 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
|
|||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
|
tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
tmp = RREG8(MGAREG_MEM_MISC_READ);
|
tmp = RREG8(MGAREG_MEM_MISC_READ);
|
||||||
tmp |= 0x3 << 2;
|
tmp |= 0x3 << 2;
|
||||||
@ -425,7 +422,7 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
|
|||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
|
tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
udelay(500);
|
udelay(500);
|
||||||
|
|
||||||
@ -439,13 +436,13 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
|
|||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
|
tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
|
tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
|
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
|
||||||
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
|
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
vcount = RREG8(MGAREG_VCOUNT);
|
vcount = RREG8(MGAREG_VCOUNT);
|
||||||
|
|
||||||
@ -515,12 +512,12 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
|
|||||||
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
|
tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
|
WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
|
||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp |= MGA1064_REMHEADCTL_CLKDIS;
|
tmp |= MGA1064_REMHEADCTL_CLKDIS;
|
||||||
WREG_DAC(MGA1064_REMHEADCTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
tmp = RREG8(MGAREG_MEM_MISC_READ);
|
tmp = RREG8(MGAREG_MEM_MISC_READ);
|
||||||
tmp |= (0x3<<2) | 0xc0;
|
tmp |= (0x3<<2) | 0xc0;
|
||||||
@ -530,7 +527,7 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
|
|||||||
tmp = RREG8(DAC_DATA);
|
tmp = RREG8(DAC_DATA);
|
||||||
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
|
tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
|
||||||
tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
|
tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
|
||||||
WREG_DAC(MGA1064_PIX_CLK_CTL, tmp);
|
WREG8(DAC_DATA, tmp);
|
||||||
|
|
||||||
udelay(500);
|
udelay(500);
|
||||||
|
|
||||||
@ -657,12 +654,26 @@ static void mga_g200wb_commit(struct drm_crtc *crtc)
|
|||||||
WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
|
WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is how the framebuffer base address is stored in g200 cards:
|
||||||
|
* Assume @offset is the gpu_addr variable of the framebuffer object
|
||||||
|
* Then addr is the number of _pixels_ (not bytes) from the start of
|
||||||
|
VRAM to the first pixel we want to display. (divided by 2 for 32bit
|
||||||
|
framebuffers)
|
||||||
|
* addr is stored in the CRTCEXT0, CRTCC and CRTCD registers
|
||||||
|
addr<20> -> CRTCEXT0<6>
|
||||||
|
addr<19-16> -> CRTCEXT0<3-0>
|
||||||
|
addr<15-8> -> CRTCC<7-0>
|
||||||
|
addr<7-0> -> CRTCD<7-0>
|
||||||
|
CRTCEXT0 has to be programmed last to trigger an update and make the
|
||||||
|
new addr variable take effect.
|
||||||
|
*/
|
||||||
void mga_set_start_address(struct drm_crtc *crtc, unsigned offset)
|
void mga_set_start_address(struct drm_crtc *crtc, unsigned offset)
|
||||||
{
|
{
|
||||||
struct mga_device *mdev = crtc->dev->dev_private;
|
struct mga_device *mdev = crtc->dev->dev_private;
|
||||||
u32 addr;
|
u32 addr;
|
||||||
int count;
|
int count;
|
||||||
|
u8 crtcext0;
|
||||||
|
|
||||||
while (RREG8(0x1fda) & 0x08);
|
while (RREG8(0x1fda) & 0x08);
|
||||||
while (!(RREG8(0x1fda) & 0x08));
|
while (!(RREG8(0x1fda) & 0x08));
|
||||||
@ -670,10 +681,17 @@ void mga_set_start_address(struct drm_crtc *crtc, unsigned offset)
|
|||||||
count = RREG8(MGAREG_VCOUNT) + 2;
|
count = RREG8(MGAREG_VCOUNT) + 2;
|
||||||
while (RREG8(MGAREG_VCOUNT) < count);
|
while (RREG8(MGAREG_VCOUNT) < count);
|
||||||
|
|
||||||
addr = offset >> 2;
|
WREG8(MGAREG_CRTCEXT_INDEX, 0);
|
||||||
|
crtcext0 = RREG8(MGAREG_CRTCEXT_DATA);
|
||||||
|
crtcext0 &= 0xB0;
|
||||||
|
addr = offset / 8;
|
||||||
|
/* Can't store addresses any higher than that...
|
||||||
|
but we also don't have more than 16MB of memory, so it should be fine. */
|
||||||
|
WARN_ON(addr > 0x1fffff);
|
||||||
|
crtcext0 |= (!!(addr & (1<<20)))<<6;
|
||||||
WREG_CRT(0x0d, (u8)(addr & 0xff));
|
WREG_CRT(0x0d, (u8)(addr & 0xff));
|
||||||
WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff);
|
WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff);
|
||||||
WREG_CRT(0xaf, (u8)(addr >> 16) & 0xf);
|
WREG_ECRT(0x0, ((u8)(addr >> 16) & 0xf) | crtcext0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -829,11 +847,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(dacvalue); i++) {
|
for (i = 0; i < sizeof(dacvalue); i++) {
|
||||||
if ((i <= 0x03) ||
|
if ((i <= 0x17) ||
|
||||||
(i == 0x07) ||
|
|
||||||
(i == 0x0b) ||
|
|
||||||
(i == 0x0f) ||
|
|
||||||
((i >= 0x13) && (i <= 0x17)) ||
|
|
||||||
(i == 0x1b) ||
|
(i == 0x1b) ||
|
||||||
(i == 0x1c) ||
|
(i == 0x1c) ||
|
||||||
((i >= 0x1f) && (i <= 0x29)) ||
|
((i >= 0x1f) && (i <= 0x29)) ||
|
||||||
|
@ -316,6 +316,7 @@ struct drm_ioctl_desc {
|
|||||||
int flags;
|
int flags;
|
||||||
drm_ioctl_t *func;
|
drm_ioctl_t *func;
|
||||||
unsigned int cmd_drv;
|
unsigned int cmd_drv;
|
||||||
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -324,7 +325,7 @@ struct drm_ioctl_desc {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
|
#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
|
||||||
[DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl}
|
[DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl, .name = #ioctl}
|
||||||
|
|
||||||
struct drm_magic_entry {
|
struct drm_magic_entry {
|
||||||
struct list_head head;
|
struct list_head head;
|
||||||
|
@ -50,13 +50,14 @@ struct drm_fb_helper_surface_size {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library
|
* struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library
|
||||||
* @gamma_set: - Set the given gamma lut register on the given crtc.
|
* @gamma_set: Set the given gamma lut register on the given crtc.
|
||||||
* @gamma_get: - Read the given gamma lut register on the given crtc, used to
|
* @gamma_get: Read the given gamma lut register on the given crtc, used to
|
||||||
* save the current lut when force-restoring the fbdev for e.g.
|
* save the current lut when force-restoring the fbdev for e.g.
|
||||||
* kdbg.
|
* kdbg.
|
||||||
* @fb_probe: - Driver callback to allocate and initialize the fbdev info
|
* @fb_probe: Driver callback to allocate and initialize the fbdev info
|
||||||
* structure. Futhermore it also needs to allocate the drm
|
* structure. Futhermore it also needs to allocate the drm
|
||||||
* framebuffer used to back the fbdev.
|
* framebuffer used to back the fbdev.
|
||||||
|
* @initial_config: Setup an initial fbdev display configuration
|
||||||
*
|
*
|
||||||
* Driver callbacks used by the fbdev emulation helper library.
|
* Driver callbacks used by the fbdev emulation helper library.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user