/drivers/video/drm/drm_atomic_helper.c |
---|
1065,7 → 1065,7 |
drm_atomic_helper_commit_modeset_enables(dev, state); |
// drm_atomic_helper_wait_for_vblanks(dev, state); |
drm_atomic_helper_wait_for_vblanks(dev, state); |
drm_atomic_helper_cleanup_planes(dev, state); |
/drivers/video/drm/drm_crtc.c |
---|
818,8 → 818,6 |
struct drm_cmdline_mode *mode = &connector->cmdline_mode; |
char *option = NULL; |
return; |
#if 0 |
if (fb_get_options(connector->name, &option)) |
return; |
855,7 → 853,6 |
mode->rb ? " reduced blanking" : "", |
mode->margins ? " with margins" : "", |
mode->interlace ? " interlaced" : ""); |
#endif |
} |
/** |
/drivers/video/drm/drm_dp_helper.c |
---|
23,7 → 23,7 |
#include <linux/kernel.h> |
#include <linux/module.h> |
//#include <linux/delay.h> |
//#include <linux/init.h> |
#include <linux/init.h> |
#include <linux/errno.h> |
#include <linux/sched.h> |
#include <linux/i2c.h> |
215,7 → 215,7 |
return -EIO; |
case DP_AUX_NATIVE_REPLY_DEFER: |
usleep(500); |
usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100); |
break; |
} |
} |
349,7 → 349,7 |
* power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink |
* Control Field" (register 0x600). |
*/ |
usleep(2000); |
usleep_range(1000, 2000); |
return 0; |
} |
578,7 → 578,7 |
* For now just defer for long enough to hopefully be |
* safe for all use-cases. |
*/ |
usleep_range(500, 600); |
usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100); |
continue; |
default: |
610,7 → 610,7 |
aux->i2c_defer_count++; |
if (defer_i2c < 7) |
defer_i2c++; |
usleep_range(400, 500); |
usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100); |
drm_dp_i2c_msg_write_status_update(msg); |
continue; |
/drivers/video/drm/drm_dp_mst_topology.c |
---|
26,6 → 26,7 |
#include <linux/wait.h> |
#include <linux/workqueue.h> |
#include <linux/delay.h> |
#include <linux/init.h> |
#include <linux/errno.h> |
#include <linux/sched.h> |
#include <linux/seq_file.h> |
2651,7 → 2652,7 |
INIT_LIST_HEAD(&mgr->destroy_connector_list); |
INIT_WORK(&mgr->work, drm_dp_mst_link_probe_work); |
INIT_WORK(&mgr->tx_work, drm_dp_tx_work); |
// init_waitqueue_head(&mgr->tx_waitq); |
init_waitqueue_head(&mgr->tx_waitq); |
mgr->dev = dev; |
mgr->aux = aux; |
mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes; |
/drivers/video/drm/drm_fb_helper.c |
---|
1324,8 → 1324,6 |
struct drm_display_mode *mode; |
bool prefer_non_interlace; |
return NULL; |
#if 0 |
cmdline_mode = &fb_helper_conn->connector->cmdline_mode; |
if (cmdline_mode->specified == false) |
return NULL; |
1369,7 → 1367,6 |
cmdline_mode); |
list_add(&mode->head, &fb_helper_conn->connector->modes); |
return mode; |
#endif |
} |
EXPORT_SYMBOL(drm_pick_cmdline_mode); |
/drivers/video/drm/drm_gem.c |
---|
751,10 → 751,6 |
struct drm_gem_object *obj = vma->vm_private_data; |
drm_gem_object_reference(obj); |
mutex_lock(&obj->dev->struct_mutex); |
drm_vm_open_locked(obj->dev, vma); |
mutex_unlock(&obj->dev->struct_mutex); |
} |
EXPORT_SYMBOL(drm_gem_vm_open); |
/drivers/video/drm/drm_irq.c |
---|
370,8 → 370,8 |
vblank->dev = dev; |
vblank->pipe = i; |
init_waitqueue_head(&vblank->queue); |
// setup_timer(&vblank->disable_timer, vblank_disable_fn, |
// (unsigned long)vblank); |
setup_timer(&vblank->disable_timer, vblank_disable_fn, |
(unsigned long)vblank); |
} |
DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n"); |
829,7 → 829,141 |
return cur_vblank; |
} |
EXPORT_SYMBOL(drm_vblank_count_and_time); |
/** |
* drm_crtc_vblank_count_and_time - retrieve "cooked" vblank counter value |
* and the system timestamp corresponding to that vblank counter value |
* @crtc: which counter to retrieve |
* @vblanktime: Pointer to struct timeval to receive the vblank timestamp. |
* |
* Fetches the "cooked" vblank count value that represents the number of |
* vblank events since the system was booted, including lost events due to |
* modesetting activity. Returns corresponding system timestamp of the time |
* of the vblank interval that corresponds to the current vblank counter value. |
* |
* This is the native KMS version of drm_vblank_count_and_time(). |
*/ |
u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, |
struct timeval *vblanktime) |
{ |
return drm_vblank_count_and_time(crtc->dev, drm_crtc_index(crtc), |
vblanktime); |
} |
EXPORT_SYMBOL(drm_crtc_vblank_count_and_time); |
static void send_vblank_event(struct drm_device *dev, |
struct drm_pending_vblank_event *e, |
unsigned long seq, struct timeval *now) |
{ |
assert_spin_locked(&dev->event_lock); |
e->event.sequence = seq; |
e->event.tv_sec = now->tv_sec; |
e->event.tv_usec = now->tv_usec; |
list_add_tail(&e->base.link, |
&e->base.file_priv->event_list); |
wake_up_interruptible(&e->base.file_priv->event_wait); |
} |
/** |
* drm_arm_vblank_event - arm vblank event after pageflip |
* @dev: DRM device |
* @pipe: CRTC index |
* @e: the event to prepare to send |
* |
* A lot of drivers need to generate vblank events for the very next vblank |
* interrupt. For example when the page flip interrupt happens when the page |
* flip gets armed, but not when it actually executes within the next vblank |
* period. This helper function implements exactly the required vblank arming |
* behaviour. |
* |
* Caller must hold event lock. Caller must also hold a vblank reference for |
* the event @e, which will be dropped when the next vblank arrives. |
* |
* This is the legacy version of drm_crtc_arm_vblank_event(). |
*/ |
void drm_arm_vblank_event(struct drm_device *dev, unsigned int pipe, |
struct drm_pending_vblank_event *e) |
{ |
assert_spin_locked(&dev->event_lock); |
e->pipe = pipe; |
e->event.sequence = drm_vblank_count(dev, pipe); |
list_add_tail(&e->base.link, &dev->vblank_event_list); |
} |
EXPORT_SYMBOL(drm_arm_vblank_event); |
/** |
* drm_crtc_arm_vblank_event - arm vblank event after pageflip |
* @crtc: the source CRTC of the vblank event |
* @e: the event to send |
* |
* A lot of drivers need to generate vblank events for the very next vblank |
* interrupt. For example when the page flip interrupt happens when the page |
* flip gets armed, but not when it actually executes within the next vblank |
* period. This helper function implements exactly the required vblank arming |
* behaviour. |
* |
* Caller must hold event lock. Caller must also hold a vblank reference for |
* the event @e, which will be dropped when the next vblank arrives. |
* |
* This is the native KMS version of drm_arm_vblank_event(). |
*/ |
void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, |
struct drm_pending_vblank_event *e) |
{ |
drm_arm_vblank_event(crtc->dev, drm_crtc_index(crtc), e); |
} |
EXPORT_SYMBOL(drm_crtc_arm_vblank_event); |
/** |
* drm_send_vblank_event - helper to send vblank event after pageflip |
* @dev: DRM device |
* @pipe: CRTC index |
* @e: the event to send |
* |
* Updates sequence # and timestamp on event, and sends it to userspace. |
* Caller must hold event lock. |
* |
* This is the legacy version of drm_crtc_send_vblank_event(). |
*/ |
void drm_send_vblank_event(struct drm_device *dev, unsigned int pipe, |
struct drm_pending_vblank_event *e) |
{ |
struct timeval now; |
unsigned int seq; |
if (dev->num_crtcs > 0) { |
seq = drm_vblank_count_and_time(dev, pipe, &now); |
} else { |
seq = 0; |
now = get_drm_timestamp(); |
} |
e->pipe = pipe; |
send_vblank_event(dev, e, seq, &now); |
} |
EXPORT_SYMBOL(drm_send_vblank_event); |
/** |
* drm_crtc_send_vblank_event - helper to send vblank event after pageflip |
* @crtc: the source CRTC of the vblank event |
* @e: the event to send |
* |
* Updates sequence # and timestamp on event, and sends it to userspace. |
* Caller must hold event lock. |
* |
* This is the native KMS version of drm_send_vblank_event(). |
*/ |
void drm_crtc_send_vblank_event(struct drm_crtc *crtc, |
struct drm_pending_vblank_event *e) |
{ |
drm_send_vblank_event(crtc->dev, drm_crtc_index(crtc), e); |
} |
EXPORT_SYMBOL(drm_crtc_send_vblank_event); |
/** |
* drm_vblank_enable - enable the vblank interrupt on a CRTC |
* @dev: DRM device |
* @pipe: CRTC index |
952,11 → 1086,8 |
if (atomic_dec_and_test(&vblank->refcount)) { |
if (drm_vblank_offdelay == 0) |
return; |
else if (dev->vblank_disable_immediate || drm_vblank_offdelay < 0) |
else |
vblank_disable_fn((unsigned long)vblank); |
else |
mod_timer(&vblank->disable_timer, |
jiffies + ((drm_vblank_offdelay * HZ)/1000)); |
} |
} |
EXPORT_SYMBOL(drm_vblank_put); |
987,24 → 1118,26 |
*/ |
void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe) |
{ |
#if 0 |
struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; |
int ret; |
u32 last; |
ret = drm_vblank_get(dev, crtc); |
if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", crtc, ret)) |
if (WARN_ON(pipe >= dev->num_crtcs)) |
return; |
last = drm_vblank_count(dev, crtc); |
ret = drm_vblank_get(dev, pipe); |
if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", pipe, ret)) |
return; |
ret = wait_event_timeout(dev->vblank[crtc].queue, |
last != drm_vblank_count(dev, crtc), |
last = drm_vblank_count(dev, pipe); |
ret = wait_event_timeout(vblank->queue, |
last != drm_vblank_count(dev, pipe), |
msecs_to_jiffies(100)); |
WARN(ret == 0, "vblank wait timed out on crtc %i\n", crtc); |
WARN(ret == 0, "vblank wait timed out on crtc %i\n", pipe); |
drm_vblank_put(dev, crtc); |
#endif |
drm_vblank_put(dev, pipe); |
} |
EXPORT_SYMBOL(drm_wait_one_vblank); |
1044,8 → 1177,40 |
unsigned long irqflags; |
unsigned int seq; |
if (WARN_ON(pipe >= dev->num_crtcs)) |
return; |
spin_lock_irqsave(&dev->event_lock, irqflags); |
spin_lock(&dev->vbl_lock); |
vblank_disable_and_save(dev, pipe); |
wake_up(&vblank->queue); |
/* |
* Prevent subsequent drm_vblank_get() from re-enabling |
* the vblank interrupt by bumping the refcount. |
*/ |
if (!vblank->inmodeset) { |
atomic_inc(&vblank->refcount); |
vblank->inmodeset = 1; |
} |
spin_unlock(&dev->vbl_lock); |
/* Send any queued vblank events, lest the natives grow disquiet */ |
seq = drm_vblank_count_and_time(dev, pipe, &now); |
list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { |
if (e->pipe != pipe) |
continue; |
DRM_DEBUG("Sending premature vblank event on disable: " |
"wanted %d, current %d\n", |
e->event.sequence, seq); |
list_del(&e->base.link); |
drm_vblank_put(dev, pipe); |
send_vblank_event(dev, e, seq, &now); |
} |
spin_unlock_irqrestore(&dev->event_lock, irqflags); |
} |
EXPORT_SYMBOL(drm_vblank_off); |
/** |
1116,8 → 1281,6 |
struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; |
unsigned long irqflags; |
dbgprintf("%s pipe %d dev->num_crtcs %d\n", pipe,dev->num_crtcs);\ |
if (WARN_ON(pipe >= dev->num_crtcs)) |
return; |
1240,7 → 1403,116 |
} |
EXPORT_SYMBOL(drm_vblank_post_modeset); |
static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe) |
{ |
struct drm_pending_vblank_event *e, *t; |
struct timeval now; |
unsigned int seq; |
assert_spin_locked(&dev->event_lock); |
seq = drm_vblank_count_and_time(dev, pipe, &now); |
list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { |
if (e->pipe != pipe) |
continue; |
if ((seq - e->event.sequence) > (1<<23)) |
continue; |
DRM_DEBUG("vblank event on %d, current %d\n", |
e->event.sequence, seq); |
list_del(&e->base.link); |
drm_vblank_put(dev, pipe); |
send_vblank_event(dev, e, seq, &now); |
} |
} |
/** |
* drm_handle_vblank - handle a vblank event |
* @dev: DRM device |
* @pipe: index of CRTC where this event occurred |
* |
* Drivers should call this routine in their vblank interrupt handlers to |
* update the vblank counter and send any signals that may be pending. |
* |
* This is the legacy version of drm_crtc_handle_vblank(). |
*/ |
bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe) |
{ |
struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; |
unsigned long irqflags; |
if (WARN_ON_ONCE(!dev->num_crtcs)) |
return false; |
if (WARN_ON(pipe >= dev->num_crtcs)) |
return false; |
spin_lock_irqsave(&dev->event_lock, irqflags); |
/* Need timestamp lock to prevent concurrent execution with |
* vblank enable/disable, as this would cause inconsistent |
* or corrupted timestamps and vblank counts. |
*/ |
spin_lock(&dev->vblank_time_lock); |
/* Vblank irq handling disabled. Nothing to do. */ |
if (!vblank->enabled) { |
spin_unlock(&dev->vblank_time_lock); |
spin_unlock_irqrestore(&dev->event_lock, irqflags); |
return false; |
} |
drm_update_vblank_count(dev, pipe, DRM_CALLED_FROM_VBLIRQ); |
spin_unlock(&dev->vblank_time_lock); |
wake_up(&vblank->queue); |
drm_handle_vblank_events(dev, pipe); |
spin_unlock_irqrestore(&dev->event_lock, irqflags); |
return true; |
} |
EXPORT_SYMBOL(drm_handle_vblank); |
/** |
* drm_crtc_handle_vblank - handle a vblank event |
* @crtc: where this event occurred |
* |
* Drivers should call this routine in their vblank interrupt handlers to |
* update the vblank counter and send any signals that may be pending. |
* |
* This is the native KMS version of drm_handle_vblank(). |
* |
* Returns: |
* True if the event was successfully handled, false on failure. |
*/ |
bool drm_crtc_handle_vblank(struct drm_crtc *crtc) |
{ |
return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc)); |
} |
EXPORT_SYMBOL(drm_crtc_handle_vblank); |
/** |
* drm_vblank_no_hw_counter - "No hw counter" implementation of .get_vblank_counter() |
* @dev: DRM device |
* @pipe: CRTC for which to read the counter |
* |
* Drivers can plug this into the .get_vblank_counter() function if |
* there is no useable hardware frame counter available. |
* |
* Returns: |
* 0 |
*/ |
u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe) |
{ |
return 0; |
} |
EXPORT_SYMBOL(drm_vblank_no_hw_counter); |
u64 div64_u64(u64 dividend, u64 divisor) |
{ |
u32 high, d; |
/drivers/video/drm/drm_mipi_dsi.c |
---|
32,7 → 32,7 |
#include <linux/module.h> |
//#include <linux/of_device.h> |
#include <linux/pm_runtime.h> |
//#include <linux/slab.h> |
#include <linux/slab.h> |
#include <video/mipi_display.h> |
/drivers/video/drm/drm_modes.c |
---|
1198,7 → 1198,215 |
} |
} |
EXPORT_SYMBOL(drm_mode_connector_list_update); |
/** |
* drm_mode_parse_command_line_for_connector - parse command line modeline for connector |
* @mode_option: optional per connector mode option |
* @connector: connector to parse modeline for |
* @mode: preallocated drm_cmdline_mode structure to fill out |
* |
* This parses @mode_option command line modeline for modes and options to |
* configure the connector. If @mode_option is NULL the default command line |
* modeline in fb_mode_option will be parsed instead. |
* |
* This uses the same parameters as the fb modedb.c, except for an extra |
* force-enable, force-enable-digital and force-disable bit at the end: |
* |
* <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd] |
* |
* The intermediate drm_cmdline_mode structure is required to store additional |
* options from the command line modline like the force-enable/disable flag. |
* |
* Returns: |
* True if a valid modeline has been parsed, false otherwise. |
*/ |
bool drm_mode_parse_command_line_for_connector(const char *mode_option, |
struct drm_connector *connector, |
struct drm_cmdline_mode *mode) |
{ |
const char *name; |
unsigned int namelen; |
bool res_specified = false, bpp_specified = false, refresh_specified = false; |
unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; |
bool yres_specified = false, cvt = false, rb = false; |
bool interlace = false, margins = false, was_digit = false; |
int i; |
enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; |
#ifdef CONFIG_FB |
if (!mode_option) |
mode_option = fb_mode_option; |
#endif |
if (!mode_option) { |
mode->specified = false; |
return false; |
} |
name = mode_option; |
namelen = strlen(name); |
for (i = namelen-1; i >= 0; i--) { |
switch (name[i]) { |
case '@': |
if (!refresh_specified && !bpp_specified && |
!yres_specified && !cvt && !rb && was_digit) { |
refresh = simple_strtol(&name[i+1], NULL, 10); |
refresh_specified = true; |
was_digit = false; |
} else |
goto done; |
break; |
case '-': |
if (!bpp_specified && !yres_specified && !cvt && |
!rb && was_digit) { |
bpp = simple_strtol(&name[i+1], NULL, 10); |
bpp_specified = true; |
was_digit = false; |
} else |
goto done; |
break; |
case 'x': |
if (!yres_specified && was_digit) { |
yres = simple_strtol(&name[i+1], NULL, 10); |
yres_specified = true; |
was_digit = false; |
} else |
goto done; |
break; |
case '0' ... '9': |
was_digit = true; |
break; |
case 'M': |
if (yres_specified || cvt || was_digit) |
goto done; |
cvt = true; |
break; |
case 'R': |
if (yres_specified || cvt || rb || was_digit) |
goto done; |
rb = true; |
break; |
case 'm': |
if (cvt || yres_specified || was_digit) |
goto done; |
margins = true; |
break; |
case 'i': |
if (cvt || yres_specified || was_digit) |
goto done; |
interlace = true; |
break; |
case 'e': |
if (yres_specified || bpp_specified || refresh_specified || |
was_digit || (force != DRM_FORCE_UNSPECIFIED)) |
goto done; |
force = DRM_FORCE_ON; |
break; |
case 'D': |
if (yres_specified || bpp_specified || refresh_specified || |
was_digit || (force != DRM_FORCE_UNSPECIFIED)) |
goto done; |
if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && |
(connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) |
force = DRM_FORCE_ON; |
else |
force = DRM_FORCE_ON_DIGITAL; |
break; |
case 'd': |
if (yres_specified || bpp_specified || refresh_specified || |
was_digit || (force != DRM_FORCE_UNSPECIFIED)) |
goto done; |
force = DRM_FORCE_OFF; |
break; |
default: |
goto done; |
} |
} |
if (i < 0 && yres_specified) { |
char *ch; |
xres = simple_strtol(name, &ch, 10); |
if ((ch != NULL) && (*ch == 'x')) |
res_specified = true; |
else |
i = ch - name; |
} else if (!yres_specified && was_digit) { |
/* catch mode that begins with digits but has no 'x' */ |
i = 0; |
} |
done: |
if (i >= 0) { |
printk(KERN_WARNING |
"parse error at position %i in video mode '%s'\n", |
i, name); |
mode->specified = false; |
return false; |
} |
if (res_specified) { |
mode->specified = true; |
mode->xres = xres; |
mode->yres = yres; |
} |
if (refresh_specified) { |
mode->refresh_specified = true; |
mode->refresh = refresh; |
} |
if (bpp_specified) { |
mode->bpp_specified = true; |
mode->bpp = bpp; |
} |
mode->rb = rb; |
mode->cvt = cvt; |
mode->interlace = interlace; |
mode->margins = margins; |
mode->force = force; |
return true; |
} |
EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector); |
/** |
* drm_mode_create_from_cmdline_mode - convert a command line modeline into a DRM display mode |
* @dev: DRM device to create the new mode for |
* @cmd: input command line modeline |
* |
* Returns: |
* Pointer to converted mode on success, NULL on error. |
*/ |
struct drm_display_mode * |
drm_mode_create_from_cmdline_mode(struct drm_device *dev, |
struct drm_cmdline_mode *cmd) |
{ |
struct drm_display_mode *mode; |
if (cmd->cvt) |
mode = drm_cvt_mode(dev, |
cmd->xres, cmd->yres, |
cmd->refresh_specified ? cmd->refresh : 60, |
cmd->rb, cmd->interlace, |
cmd->margins); |
else |
mode = drm_gtf_mode(dev, |
cmd->xres, cmd->yres, |
cmd->refresh_specified ? cmd->refresh : 60, |
cmd->interlace, |
cmd->margins); |
if (!mode) |
return NULL; |
mode->type |= DRM_MODE_TYPE_USERDEF; |
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
return mode; |
} |
EXPORT_SYMBOL(drm_mode_create_from_cmdline_mode); |
/** |
* drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo |
* @out: drm_mode_modeinfo struct to return to the user |
* @in: drm_display_mode to use |
/drivers/video/drm/drm_probe_helper.c |
---|
189,6 → 189,7 |
if (count == 0 && connector->status == connector_status_connected) |
count = drm_add_modes_noedid(connector, 1024, 768); |
count += drm_helper_probe_add_cmdline_mode(connector); |
if (count == 0) |
goto prune; |
/drivers/video/drm/i915/i915.asm |
---|
10,6 → 10,8 |
dd cmdline |
dd path |
SRV_CMDLINE equ 4 |
start: |
mov eax, 68 |
mov ebx, 16 |
16,9 → 18,26 |
mov ecx, sz_display |
int 0x40 |
test eax, eax |
jnz .done ; FIXME parse command line and |
; call service |
jz .load |
xor ebx, ebx |
push ebx ;.out_size |
push ebx ;.output |
push 4 ;.inp_size |
push cmdline ;.input |
push SRV_CMDLINE ;.code |
push eax ;.handle |
mov eax, 68 |
mov ebx, 17 |
mov ecx, esp ;[ioctl] |
int 0x40 |
mov eax, -1 |
int 0x40 |
.load: |
xor eax, eax |
mov ecx, 1024 |
mov edi, path |
32,7 → 51,7 |
mov ecx, path |
mov edx, cmdline |
int 0x40 |
.done: |
mov eax, -1 |
int 0x40 |
/drivers/video/drm/i915/i915_dma.c |
---|
852,6 → 852,14 |
if (ret) |
goto out_freecsr; |
/* WARNING: Apparently we must kick fbdev drivers before vgacon, |
* otherwise the vga fbdev driver falls over. */ |
ret = i915_kick_out_firmware_fb(dev_priv); |
if (ret) { |
DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); |
goto out_gtt; |
} |
ret = i915_kick_out_vgacon(dev_priv); |
if (ret) { |
DRM_ERROR("failed to remove conflicting VGA console\n"); |
927,11 → 935,11 |
intel_init_dpio(dev_priv); |
// if (INTEL_INFO(dev)->num_pipes) { |
// ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); |
// if (ret) |
// goto out_gem_unload; |
// } |
if (INTEL_INFO(dev)->num_pipes) { |
ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); |
if (ret) |
goto out_gem_unload; |
} |
intel_power_domains_init(dev_priv); |
/drivers/video/drm/i915/i915_drv.h |
---|
2691,6 → 2691,10 |
bool verbose_state_checks; |
bool nuclear_pageflip; |
int edp_vswing; |
/* Kolibri related */ |
int fbsize; |
char *log_file; |
char *cmdline_mode; |
}; |
extern struct i915_params i915 __read_mostly; |
/drivers/video/drm/i915/i915_gem.c |
---|
1010,11 → 1010,9 |
const bool irq_test_in_progress = |
ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring); |
int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; |
DEFINE_WAIT(wait); |
wait_queue_t wait; |
unsigned long timeout_expire; |
s64 before, now; |
wait_queue_t __wait; |
int ret; |
WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled"); |
1053,10 → 1051,9 |
goto out; |
} |
INIT_LIST_HEAD(&__wait.task_list); |
__wait.evnt = CreateEvent(NULL, MANUAL_DESTROY); |
INIT_LIST_HEAD(&wait.task_list); |
wait.evnt = CreateEvent(NULL, MANUAL_DESTROY); |
for (;;) { |
unsigned long flags; |
1082,25 → 1079,25 |
} |
spin_lock_irqsave(&ring->irq_queue.lock, flags); |
if (list_empty(&__wait.task_list)) |
__add_wait_queue(&ring->irq_queue, &__wait); |
if (list_empty(&wait.task_list)) |
__add_wait_queue(&ring->irq_queue, &wait); |
spin_unlock_irqrestore(&ring->irq_queue.lock, flags); |
WaitEventTimeout(__wait.evnt, 1); |
WaitEventTimeout(wait.evnt, 1); |
if (!list_empty(&__wait.task_list)) { |
if (!list_empty(&wait.task_list)) { |
spin_lock_irqsave(&ring->irq_queue.lock, flags); |
list_del_init(&__wait.task_list); |
list_del_init(&wait.task_list); |
spin_unlock_irqrestore(&ring->irq_queue.lock, flags); |
} |
}; |
DestroyEvent(__wait.evnt); |
if (!irq_test_in_progress) |
ring->irq_put(ring); |
// finish_wait(&ring->irq_queue, &wait); |
DestroyEvent(wait.evnt); |
out: |
now = ktime_get_raw_ns(); |
trace_i915_gem_request_wait_end(req); |
/drivers/video/drm/i915/i915_irq.c |
---|
29,6 → 29,7 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
#include <linux/slab.h> |
#include <linux/circ_buf.h> |
#include <drm/drmP.h> |
#include <drm/i915_drm.h> |
#include "i915_drv.h" |
1444,7 → 1445,7 |
*pin_mask |= BIT(i); |
// if (!intel_hpd_pin_to_port(i, &port)) |
continue; |
// continue; |
if (long_pulse_detect(port, dig_hotplug_reg)) |
*long_mask |= BIT(i); |
1594,8 → 1595,8 |
static bool intel_pipe_handle_vblank(struct drm_device *dev, enum pipe pipe) |
{ |
// if (!drm_handle_vblank(dev, pipe)) |
// return false; |
if (!drm_handle_vblank(dev, pipe)) |
return false; |
return true; |
} |
2281,6 → 2282,9 |
ret = IRQ_HANDLED; |
I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir); |
if (pipe_iir & GEN8_PIPE_VBLANK && |
intel_pipe_handle_vblank(dev, pipe)) |
/* intel_check_page_flip(dev, pipe)*/; |
if (INTEL_INFO(dev_priv)->gen >= 9) |
flip_done = pipe_iir & GEN9_PIPE_PLANE1_FLIP_DONE; |
2419,7 → 2423,7 |
atomic_inc(&dev_priv->gpu_error.reset_counter); |
} else { |
atomic_set_mask(I915_WEDGED, &error->reset_counter); |
atomic_or(I915_WEDGED, &error->reset_counter); |
} |
/* |
3009,6 → 3013,7 |
// return i915_handle_error(dev, true); |
} |
static void ibx_irq_reset(struct drm_device *dev) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
3933,6 → 3938,7 |
struct drm_i915_private *dev_priv = dev->dev_private; |
u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane); |
if (!intel_pipe_handle_vblank(dev, pipe)) |
return false; |
if ((iir & flip_pending) == 0) |
/drivers/video/drm/i915/i915_params.c |
---|
55,6 → 55,9 |
.edp_vswing = 0, |
.enable_guc_submission = false, |
.guc_log_level = -1, |
.fbsize = 16, |
.log_file = NULL, |
.cmdline_mode = NULL, |
}; |
module_param_named(modeset, i915.modeset, int, 0400); |
/drivers/video/drm/i915/intel_display.c |
---|
26,7 → 26,7 |
#include <linux/dmi.h> |
#include <linux/module.h> |
//#include <linux/input.h> |
#include <linux/input.h> |
#include <linux/i2c.h> |
#include <linux/kernel.h> |
#include <linux/slab.h> |
8065,7 → 8065,7 |
fb->modifier[0]); |
// plane_config->size = fb->pitches[0] * aligned_height; |
plane_config->size = i915_fbsize*1024*1024; |
plane_config->size = i915.fbsize*1024*1024; |
DRM_DEBUG_KMS("pipe/plane %c/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", |
pipe_name(pipe), plane, fb->width, fb->height, |
9131,7 → 9131,7 |
fb->modifier[0]); |
// plane_config->size = fb->pitches[0] * aligned_height; |
plane_config->size = i915_fbsize*1024*1024; |
plane_config->size = i915.fbsize*1024*1024; |
DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", |
pipe_name(pipe), fb->width, fb->height, |
9230,7 → 9230,7 |
fb->modifier[0]); |
// plane_config->size = fb->pitches[0] * aligned_height; |
plane_config->size = i915_fbsize*1024*1024; |
plane_config->size = i915.fbsize*1024*1024; |
DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", |
pipe_name(pipe), fb->width, fb->height, |
13250,8 → 13250,7 |
/* FIXME: add subpixel order */ |
// drm_atomic_helper_wait_for_vblanks(dev, state); |
drm_atomic_helper_wait_for_vblanks(dev, state); |
drm_atomic_helper_cleanup_planes(dev, state); |
if (any_ms) |
14826,7 → 14825,7 |
int sprite, ret; |
enum pipe pipe; |
struct intel_crtc *crtc; |
ENTER(); |
drm_mode_config_init(dev); |
dev->mode_config.min_width = 0; |
14949,9 → 14948,6 |
} |
} |
LEAVE(); |
} |
static void intel_enable_pipe_a(struct drm_device *dev) |
/drivers/video/drm/i915/intel_fbdev.c |
---|
34,7 → 34,7 |
#include <linux/sysrq.h> |
#include <linux/delay.h> |
#include <linux/fb.h> |
//#include <linux/init.h> |
#include <linux/init.h> |
//#include <linux/vga_switcheroo.h> |
#include <drm/drmP.h> |
/drivers/video/drm/i915/intel_sprite.c |
---|
80,7 → 80,6 |
*/ |
void intel_pipe_update_start(struct intel_crtc *crtc) |
{ |
ENTER(); |
struct drm_device *dev = crtc->base.dev; |
const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
enum pipe pipe = crtc->pipe; |
/drivers/video/drm/i915/kms_display.c |
---|
34,6 → 34,7 |
void disable_mouse(void) |
{}; |
struct mutex cursor_lock; |
static char *manufacturer_name(unsigned char *x) |
{ |
47,6 → 48,17 |
return name; |
} |
static int count_connector_modes(struct drm_connector* connector) |
{ |
struct drm_display_mode *mode; |
int count = 0; |
list_for_each_entry(mode, &connector->modes, head) |
count++; |
return count; |
}; |
static int set_mode(struct drm_device *dev, struct drm_connector *connector, |
struct drm_crtc *crtc, videomode_t *reqmode, bool strict) |
{ |
54,6 → 66,7 |
struct drm_mode_config *config = &dev->mode_config; |
struct drm_display_mode *mode = NULL, *tmpmode; |
struct drm_connector *tmpc; |
struct drm_framebuffer *fb = NULL; |
struct drm_mode_set set; |
const char *con_name; |
65,6 → 78,14 |
drm_modeset_lock_all(dev); |
list_for_each_entry(tmpc, &dev->mode_config.connector_list, head) |
{ |
const struct drm_connector_funcs *f = tmpc->funcs; |
if(tmpc == connector) |
continue; |
f->dpms(tmpc, DRM_MODE_DPMS_OFF); |
}; |
list_for_each_entry(tmpmode, &connector->modes, head) |
{ |
if( (tmpmode->hdisplay == reqmode->width) && |
95,8 → 116,18 |
do_set: |
con_name = connector->name; |
char con_edid[128]; |
memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
DRM_DEBUG_KMS("Manufacturer: %s Model %x Serial Number %u\n", |
manufacturer_name(con_edid + 0x08), |
(unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
(unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
+ (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s\n", |
reqmode->width, reqmode->height, crtc->base.id, |
con_name); |
180,16 → 211,135 |
return ret; |
} |
static int count_connector_modes(struct drm_connector* connector) |
static int set_mode_ex(struct drm_device *dev, |
struct drm_connector *connector, struct drm_display_mode *mode) |
{ |
struct drm_display_mode *mode; |
int count = 0; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct drm_connector *tmpc; |
struct drm_mode_config *config = &dev->mode_config; |
struct drm_framebuffer *fb = NULL; |
struct drm_mode_set set; |
char con_edid[128]; |
int stride; |
int ret; |
list_for_each_entry(mode, &connector->modes, head) |
ENTER(); |
drm_modeset_lock_all(dev); |
list_for_each_entry(tmpc, &dev->mode_config.connector_list, head) |
{ |
count++; |
const struct drm_connector_funcs *f = tmpc->funcs; |
if(tmpc == connector) |
continue; |
f->dpms(tmpc, DRM_MODE_DPMS_OFF); |
}; |
return count; |
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
fb = connector->encoder->crtc->primary->fb; |
if(fb == NULL) |
fb = main_framebuffer; |
fb->width = mode->hdisplay; |
fb->height = mode->vdisplay;; |
main_fb_obj->tiling_mode = I915_TILING_X; |
if( main_fb_obj->tiling_mode == I915_TILING_X) |
{ |
if(IS_GEN3(dev)) |
for (stride = 512; stride < mode->hdisplay * 4; stride <<= 1); |
else |
stride = ALIGN(mode->hdisplay * 4, 512); |
} |
else |
{ |
stride = ALIGN(mode->hdisplay * 4, 64); |
} |
fb->pitches[0] = |
fb->pitches[1] = |
fb->pitches[2] = |
fb->pitches[3] = stride; |
main_fb_obj->stride = stride; |
fb->bits_per_pixel = 32; |
fb->depth = 24; |
connector->encoder->crtc->enabled = true; |
i915_gem_object_put_fence(main_fb_obj); |
memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
DRM_DEBUG_KMS("set mode %dx%d: crtc %d connector %s\n" |
"monitor: %s model %x serial number %u\n", |
fb->width, fb->height, |
connector->encoder->crtc->base.id, connector->name, |
manufacturer_name(con_edid + 0x08), |
(unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
(unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
+ (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
DRM_DEBUG_KMS("use framebuffer %p %dx%d pitch %d format %x\n", |
fb,fb->width,fb->height,fb->pitches[0],fb->pixel_format); |
set.crtc = connector->encoder->crtc; |
set.x = 0; |
set.y = 0; |
set.mode = mode; |
set.connectors = &connector; |
set.num_connectors = 1; |
set.fb = fb; |
ret = drm_mode_set_config_internal(&set); |
if ( !ret ) |
{ |
struct drm_crtc *crtc = os_display->crtc; |
os_display->width = fb->width; |
os_display->height = fb->height; |
os_display->vrefresh = drm_mode_vrefresh(mode); |
sysSetScreen(fb->width, fb->height, fb->pitches[0]); |
os_display->connector = connector; |
os_display->crtc = connector->encoder->crtc; |
os_display->supported_modes = count_connector_modes(connector); |
crtc->cursor_x = os_display->width/2; |
crtc->cursor_y = os_display->height/2; |
select_cursor_kms(os_display->cursor); |
DRM_DEBUG_KMS("new mode %d x %d pitch %d\n", |
fb->width, fb->height, fb->pitches[0]); |
} |
else |
DRM_ERROR(" failed to set mode %d_%d on crtc %p\n", |
fb->width, fb->height, connector->encoder->crtc); |
drm_modeset_unlock_all(dev); |
LEAVE(); |
return ret; |
} |
static int set_cmdline_mode(struct drm_device *dev, struct drm_connector *connector) |
{ |
struct drm_display_mode *mode; |
int retval; |
mode = drm_mode_create_from_cmdline_mode(dev, &connector->cmdline_mode); |
if(mode == NULL) |
return EINVAL; |
retval = set_mode_ex(dev, connector, mode); |
drm_mode_destroy(dev, mode); |
return retval; |
}; |
static struct drm_crtc *get_possible_crtc(struct drm_device *dev, struct drm_encoder *encoder) |
210,18 → 360,14 |
return NULL; |
}; |
static int choose_config(struct drm_device *dev, struct drm_connector **boot_connector, |
struct drm_crtc **boot_crtc) |
static int check_connector(struct drm_device *dev, struct drm_connector *connector) |
{ |
struct drm_connector_helper_funcs *connector_funcs; |
struct drm_connector *connector; |
const struct drm_connector_helper_funcs *connector_funcs; |
struct drm_encoder *encoder; |
struct drm_crtc *crtc; |
list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
{ |
if( connector->status != connector_status_connected) |
continue; |
return -EINVAL; |
encoder = connector->encoder; |
234,7 → 380,7 |
{ |
DRM_DEBUG_KMS("CONNECTOR %s ID: %d no active encoders\n", |
connector->name, connector->base.id); |
continue; |
return -EINVAL; |
}; |
} |
244,27 → 390,63 |
if(crtc != NULL) |
{ |
*boot_connector = connector; |
*boot_crtc = crtc; |
encoder->crtc = crtc; |
return 0; |
} |
else |
DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id); |
return -EINVAL; |
} |
DRM_DEBUG_KMS("CONNECTOR %s ID:%d status:%d ENCODER %p ID: %d CRTC %p ID:%d\n", |
connector->name, connector->base.id, connector->status, |
encoder, encoder->base.id, crtc, crtc->base.id ); |
char con_edid[128]; |
static struct drm_connector* get_cmdline_connector(struct drm_device *dev, const char *cmdline) |
{ |
struct drm_connector *connector; |
memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
printf("Manufacturer: %s Model %x Serial Number %u\n", |
manufacturer_name(con_edid + 0x08), |
(unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
(unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
+ (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
{ |
int name_len = __builtin_strlen(connector->name); |
if (name_len == 0) |
continue; |
if (__builtin_strncmp(connector->name, cmdline, name_len)) |
continue; |
if(check_connector(dev, connector) == 0) |
return connector; |
} |
return NULL; |
} |
static int choose_config(struct drm_device *dev, struct drm_connector **boot_connector, |
struct drm_crtc **boot_crtc) |
{ |
const struct drm_connector_helper_funcs *connector_funcs; |
struct drm_connector *connector = NULL; |
struct drm_encoder *encoder = NULL; |
struct drm_crtc *crtc = NULL; |
if((i915.cmdline_mode != NULL) && (*i915.cmdline_mode != 0)) |
{ |
connector = get_cmdline_connector(dev, i915.cmdline_mode); |
if(connector != NULL) |
{ |
*boot_connector = connector; |
*boot_crtc = connector->encoder->crtc; |
return 0; |
} |
else |
DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id); |
} |
list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
{ |
if(check_connector(dev, connector) == 0) |
{ |
*boot_connector = connector; |
*boot_crtc = connector->encoder->crtc; |
return 0; |
}; |
}; |
return -ENOENT; |
}; |
275,10 → 457,6 |
list_for_each_entry(mode, &connector->modes, head) |
{ |
DRM_DEBUG_KMS("check mode w:%d h:%d %dHz\n", |
mode->hdisplay, mode->vdisplay, |
drm_mode_vrefresh(mode)); |
if( os_display->width == mode->hdisplay && |
os_display->height == mode->vdisplay && |
drm_mode_vrefresh(mode) == 60) |
305,14 → 483,12 |
ENTER(); |
mutex_lock(&dev->struct_mutex); |
mutex_lock(&dev->mode_config.mutex); |
ret = choose_config(dev, &connector, &crtc); |
if(ret) |
{ |
mutex_unlock(&dev->mode_config.mutex); |
DRM_DEBUG_KMS("No active connectors!\n"); |
mutex_unlock(&dev->mode_config.mutex); |
return -1; |
}; |
334,9 → 510,12 |
os_display->ddev = dev; |
os_display->connector = connector; |
os_display->crtc = crtc; |
os_display->supported_modes = count_connector_modes(connector); |
mutex_unlock(&dev->mode_config.mutex); |
mutex_init(&cursor_lock); |
mutex_lock(&dev->struct_mutex); |
ifl = safe_cli(); |
{ |
list_for_each_entry(cursor, &os_display->cursors, list) |
359,6 → 538,17 |
}; |
safe_sti(ifl); |
mutex_unlock(&dev->struct_mutex); |
ret = -1; |
if(connector->cmdline_mode.specified == true) |
ret = set_cmdline_mode(dev, connector); |
if(ret !=0) |
{ |
mutex_lock(&dev->mode_config.mutex); |
if( (usermode->width == 0) || |
(usermode->height == 0)) |
{ |
372,11 → 562,10 |
usermode->freq = drm_mode_vrefresh(mode); |
}; |
}; |
mutex_unlock(&dev->mode_config.mutex); |
mutex_unlock(&dev->struct_mutex); |
set_mode(dev, os_display->connector, os_display->crtc, usermode, false); |
}; |
#ifdef __HWA__ |
err = init_bitmaps(); |
384,10 → 573,70 |
LEAVE(); |
return 0; |
return ret; |
}; |
int set_cmdline_mode_ext(struct drm_device *dev, const char *cmdline) |
{ |
struct drm_connector_helper_funcs *connector_funcs; |
struct drm_connector *connector; |
struct drm_cmdline_mode cmd_mode; |
struct drm_display_mode *mode; |
char *mode_option; |
int retval = 0; |
char con_edid[128]; |
ENTER(); |
if((cmdline == NULL) || (*cmdline == 0)) |
return EINVAL; |
mutex_lock(&dev->mode_config.mutex); |
connector = get_cmdline_connector(dev, cmdline); |
mutex_unlock(&dev->mode_config.mutex); |
if(connector == NULL) |
return EINVAL; |
mode_option = __builtin_strchr(cmdline,':'); |
if(mode_option == NULL) |
return EINVAL; |
mode_option++; |
__builtin_memset(&cmd_mode, 0, sizeof(cmd_mode)); |
if( !drm_mode_parse_command_line_for_connector(mode_option, connector, &cmd_mode)) |
return EINVAL; |
DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", |
connector->name, |
cmd_mode.xres, cmd_mode.yres, |
cmd_mode.refresh_specified ? cmd_mode.refresh : 60, |
cmd_mode.rb ? " reduced blanking" : "", |
cmd_mode.margins ? " with margins" : "", |
cmd_mode.interlace ? " interlaced" : ""); |
mode = drm_mode_create_from_cmdline_mode(dev, &cmd_mode); |
if(mode == NULL) |
return EINVAL; |
memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
DRM_DEBUG_KMS("connector: %s monitor: %s model %x serial number %u\n", |
connector->name, |
manufacturer_name(con_edid + 0x08), |
(unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
(unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
+ (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
retval = set_mode_ex(dev, connector, mode); |
drm_mode_destroy(dev, mode); |
LEAVE(); |
return retval; |
} |
int get_videomodes(videomode_t *mode, int *count) |
{ |
int err = -1; |
571,10 → 820,11 |
cursor_t *old; |
old = os_display->cursor; |
mutex_lock(&cursor_lock); |
os_display->cursor = cursor; |
// intel_crtc->cursor_bo = cursor->cobj; |
if (!dev_priv->info.cursor_needs_physical) |
intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj); |
else |
583,6 → 833,7 |
intel_crtc->base.cursor->state->crtc_w = 64; |
intel_crtc->base.cursor->state->crtc_h = 64; |
intel_crtc->base.cursor->state->rotation = 0; |
mutex_unlock(&cursor_lock); |
move_cursor_kms(cursor, crtc->cursor_x, crtc->cursor_y); |
return old; |
/drivers/video/drm/i915/main.c |
---|
9,7 → 9,10 |
#include <linux/mod_devicetable.h> |
#include <linux/pci.h> |
#include "getopt.h" |
#include "bitmap.h" |
#include "i915_kos32.h" |
#define DRV_NAME "i915 v4.4" |
17,92 → 20,22 |
#define I915_DEV_INIT 1 |
#define I915_DEV_READY 2 |
struct pci_device { |
uint16_t domain; |
uint8_t bus; |
uint8_t dev; |
uint8_t func; |
uint16_t vendor_id; |
uint16_t device_id; |
uint16_t subvendor_id; |
uint16_t subdevice_id; |
uint32_t device_class; |
uint8_t revision; |
}; |
struct cmdtable |
{ |
char *key; |
int size; |
int *val; |
}; |
#define CMDENTRY(key, val) {(key), (sizeof(key)-1), &val} |
void parse_cmdline(char *cmdline, struct cmdtable *table, char *log, videomode_t *mode); |
int oops_in_progress; |
int i915_fbsize = 16; |
struct drm_device *main_device; |
struct drm_file *drm_file_handlers[256]; |
videomode_t usermode; |
static int my_atoi(char **cmd); |
static char* parse_mode(char *p, videomode_t *mode); |
void cpu_detect1(); |
int kmap_init(); |
int _stdcall display_handler(ioctl_t *io); |
int init_agp(void); |
void get_pci_info(struct pci_device *dev); |
int i915_getparam(struct drm_device *dev, void *data, |
struct drm_file *file_priv); |
int i915_mask_update(struct drm_device *dev, void *data, |
struct drm_file *file); |
struct cmdtable cmdtable[]= { |
CMDENTRY("-FB=", i915_fbsize), |
/* CMDENTRY("-pm=", i915.powersave), */ |
CMDENTRY("-rc6=", i915.enable_rc6), |
CMDENTRY("-fbc=", i915.enable_fbc), |
CMDENTRY("-ppgt=", i915.enable_ppgtt), |
{NULL, 0} |
}; |
static char log[256]; |
unsigned long volatile jiffies; |
int oops_in_progress; |
int x86_clflush_size; |
unsigned int tsc_khz; |
struct workqueue_struct *system_wq; |
int driver_wq_state; |
struct drm_device *main_device; |
struct drm_file *drm_file_handlers[256]; |
videomode_t usermode; |
extern int __getopt_initialized; |
int x86_clflush_size; |
unsigned int tsc_khz; |
int i915_modeset = 1; |
typedef union __attribute__((packed)) |
{ |
uint32_t val; |
struct |
{ |
uint8_t state; |
uint8_t code; |
uint16_t ctrl_key; |
}; |
}oskey_t; |
static inline oskey_t get_key(void) |
{ |
oskey_t val; |
asm volatile("int $0x40":"=a"(val):"a"(2)); |
return val; |
}; |
void i915_dpms(struct drm_device *dev, int mode); |
void i915_driver_thread() |
{ |
struct drm_i915_private *dev_priv = NULL; |
186,7 → 119,7 |
{ |
static pci_dev_t device; |
const struct pci_device_id *ent; |
char *safecmdline; |
int err = 0; |
if(action != 1) |
199,29 → 132,97 |
return 0; |
printf("\n%s build %s %s\nusage: i915 [options]\n" |
"-FB=<0-9> Set framebuffer size in megabytes (default: 16)\n", |
"-pm=<0,1> Enable powersavings, fbc, downclocking, etc. (default: 1 - true)\n", |
"-f\n" |
"--fbsize <0-9> Set framebuffer size in megabytes (default: 16)\n", |
DRV_NAME, __DATE__, __TIME__); |
printf("-rc6=<-1,0-7> Enable power-saving render C-state 6.\n" |
printf("--rc6 <-1,0-7> Enable power-saving render C-state 6.\n" |
" Different stages can be selected via bitmask values\n" |
" (0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6).\n" |
" For example, 3 would enable rc6 and deep rc6, and 7 would enable everything.\n" |
" (0 = disable; 1 = enable rc6; 2 = enable deep rc6;\n" |
" 4 = enable deepest rc6).\n" |
" For example, 3 would enable rc6 and deep rc6,\n" |
" and 7 would enable everything.\n" |
" default: -1 (use per-chip default)\n"); |
printf("-fbc=<-1,0,1> Enable frame buffer compression for power savings\n" |
printf("--fbc <-1,0,1> Enable frame buffer compression for power savings\n" |
" (default: -1 (use per-chip default))\n"); |
printf("-ppgt=<0,1> Enable PPGTT (default: true)\n"); |
printf("-l\n" |
"--log <path> path to log file\n"); |
printf("-m\n" |
"--mode <WxHxHz> set videomode\n"); |
printf("-v\n" |
"--video <CONNECTOR>:<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]\n" |
" set videomode for CONNECTOR\n"); |
printf("-l<path> path to log file\n"); |
printf("-m<WxHxHz> set videomode\n"); |
printf("cmdline %s\n", cmdline); |
if( cmdline && *cmdline ) |
parse_cmdline(cmdline, cmdtable, log, &usermode); |
{ |
int argc, i, c; |
char **argv; |
if( *log && !dbg_open(log)) |
safecmdline = __builtin_strdup(cmdline); |
printf("cmdline %s\n", safecmdline); |
argc = split_cmdline(safecmdline, NULL); |
argv = __builtin_malloc((argc+1)*sizeof(char*)); |
split_cmdline(safecmdline, argv); |
argv[argc] = NULL; |
while(1) |
{ |
printf("Can't open %s\nExit\n", log); |
static struct option long_options[] = |
{ |
{"log", required_argument, 0, 'l'}, |
{"mode", required_argument, 0, 'm'}, |
{"fbsize",required_argument, 0, 'f'}, |
{"video", required_argument, 0, 'v'}, |
{"rc6", required_argument, 0, OPTION_RC6}, |
{"fbc", required_argument, 0, OPTION_FBC}, |
{0, 0, 0, 0} |
}; |
int option_index = 0; |
c = getopt_long (argc, argv, "f:l:m:v:", |
long_options, &option_index); |
if (c == -1) |
break; |
switch(c) |
{ |
case OPTION_RC6: |
i915.enable_rc6 = my_atoi(&optarg); |
printf("i915.rc6 = %d\n",i915.enable_rc6); |
break; |
case OPTION_FBC: |
i915.enable_fbc = my_atoi(&optarg); |
printf("i915.fbc = %d\n",i915.enable_fbc); |
break; |
case 'f': |
i915.fbsize = my_atoi(&optarg); |
printf("i915.fbsize =%d\n",i915.fbsize); |
break; |
case 'l': |
i915.log_file = optarg; |
break; |
case 'm': |
parse_mode(optarg, &usermode); |
break; |
case 'v': |
i915.cmdline_mode = optarg; |
printf("i915.cmdline_mode =%s\n",i915.cmdline_mode); |
break; |
} |
} |
}; |
if( i915.log_file && !dbg_open(i915.log_file)) |
{ |
printf("Can't open %s\nExit\n", i915.log_file); |
return 0; |
} |
else |
230,7 → 231,6 |
} |
cpu_detect1(); |
// dbgprintf("\ncache line size %d\n", x86_clflush_size); |
err = enum_pci_devices(); |
if( unlikely(err != 0) ) |
272,7 → 272,55 |
return err; |
}; |
int do_command_line(const char* usercmd) |
{ |
char *cmdline; |
int argc, i, c; |
char **argv; |
if( (usercmd == NULL) || (*usercmd == 0) ) |
return 1; |
cmdline = __builtin_strdup(usercmd); |
printf("cmdline %s\n", cmdline); |
argc = split_cmdline(cmdline, NULL); |
argv = __builtin_malloc((argc+1)*sizeof(char*)); |
split_cmdline(cmdline, argv); |
argv[argc] = NULL; |
__getopt_initialized = 0; |
while(1) |
{ |
static struct option long_options[] = |
{ |
{"video", required_argument, 0, 'v'}, |
{0, 0, 0, 0} |
}; |
int option_index = 0; |
c = getopt_long (argc, argv, "v:", |
long_options, &option_index); |
if (c == -1) |
break; |
switch(c) |
{ |
case 'v': |
printf("cmdline_mode %s\n",optarg); |
set_cmdline_mode_ext(main_device, optarg); |
break; |
} |
} |
__builtin_free(argv); |
__builtin_free(cmdline); |
return 0; |
}; |
#define CURRENT_API 0x0200 /* 2.00 */ |
#define COMPATIBLE_API 0x0100 /* 1.00 */ |
284,8 → 332,8 |
#define SRV_ENUM_MODES 1 |
#define SRV_SET_MODE 2 |
#define SRV_GET_CAPS 3 |
#define SRV_CMDLINE 4 |
#define SRV_GET_PCI_INFO 20 |
#define SRV_I915_GET_PARAM 21 |
#define SRV_I915_GEM_CREATE 22 |
349,7 → 397,6 |
// inp, io->inp_size, io->out_size ); |
check_output(4); |
// check_input(*outp * sizeof(videomode_t)); |
if( i915_modeset) |
retval = get_videomodes((videomode_t*)inp, outp); |
break; |
357,7 → 404,6 |
// dbgprintf("SRV_SET_MODE inp %x inp_size %x\n", |
// inp, io->inp_size); |
check_input(sizeof(videomode_t)); |
if( i915_modeset ) |
retval = set_user_mode((videomode_t*)inp); |
break; |
365,6 → 411,10 |
retval = get_driver_caps((hwcaps_t*)inp); |
break; |
case SRV_CMDLINE: |
retval = do_command_line((char*)inp); |
break; |
case SRV_GET_PCI_INFO: |
get_pci_info((struct pci_device *)inp); |
retval = 0; |
779,7 → 829,7 |
} |
} |
char* parse_mode(char *p, videomode_t *mode) |
static char* parse_mode(char *p, videomode_t *mode) |
{ |
char c; |
806,89 → 856,6 |
return p; |
}; |
static char* parse_path(char *p, char *log) |
{ |
char c; |
while( (c = *p++) == ' '); |
p--; |
while((c = *p++) && (c != ' ')) |
*log++ = c; |
*log = 0; |
return p; |
}; |
void parse_cmdline(char *cmdline, struct cmdtable *table, char *log, videomode_t *mode) |
{ |
char *p = cmdline; |
char *p1; |
int val; |
char c = *p++; |
if( table ) |
{ |
while(table->key) |
{ |
if(p1 = strstr(cmdline, table->key)) |
{ |
p1+= table->size; |
*table->val = my_atoi(&p1); |
} |
table++; |
} |
} |
while( c ) |
{ |
if( c == '-') |
{ |
switch(*p++) |
{ |
case 'l': |
p = parse_path(p, log); |
break; |
case 'm': |
p = parse_mode(p, mode); |
break; |
}; |
}; |
c = *p++; |
}; |
}; |
char *strstr(const char *cs, const char *ct) |
{ |
int d0, d1; |
register char *__res; |
__asm__ __volatile__( |
"movl %6,%%edi\n\t" |
"repne\n\t" |
"scasb\n\t" |
"notl %%ecx\n\t" |
"decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */ |
"movl %%ecx,%%edx\n" |
"1:\tmovl %6,%%edi\n\t" |
"movl %%esi,%%eax\n\t" |
"movl %%edx,%%ecx\n\t" |
"repe\n\t" |
"cmpsb\n\t" |
"je 2f\n\t" /* also works for empty string, see above */ |
"xchgl %%eax,%%esi\n\t" |
"incl %%esi\n\t" |
"cmpb $0,-1(%%eax)\n\t" |
"jne 1b\n\t" |
"xorl %%eax,%%eax\n\t" |
"2:" |
: "=a" (__res), "=&c" (d0), "=&S" (d1) |
: "0" (0), "1" (0xffffffff), "2" (cs), "g" (ct) |
: "dx", "di"); |
return __res; |
} |
#include <linux/math64.h> |
u64 long_div(u64 dividend, u64 divisor) |
/drivers/video/drm/i915/utils.c |
---|
7,6 → 7,7 |
#include <linux/hdmi.h> |
#include <linux/seq_file.h> |
#include <linux/fence.h> |
#include "i915_kos32.h" |
struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags) |
{ |
847,3 → 848,184 |
return t; |
} |
char *strdup(const char *str) |
{ |
size_t len = strlen(str) + 1; |
char *copy = __builtin_malloc(len); |
if (copy) |
{ |
memcpy (copy, str, len); |
} |
return copy; |
} |
int split_cmdline(char *cmdline, char **argv) |
{ |
enum quote_state |
{ |
QUOTE_NONE, /* no " active in current parm */ |
QUOTE_DELIMITER, /* " was first char and must be last */ |
QUOTE_STARTED /* " was seen, look for a match */ |
}; |
enum quote_state state; |
unsigned int argc; |
char *p = cmdline; |
char *new_arg, *start; |
argc = 0; |
for(;;) |
{ |
/* skip over spaces and tabs */ |
if ( *p ) |
{ |
while (*p == ' ' || *p == '\t') |
++p; |
} |
if (*p == '\0') |
break; |
state = QUOTE_NONE; |
if( *p == '\"' ) |
{ |
p++; |
state = QUOTE_DELIMITER; |
} |
new_arg = start = p; |
for (;;) |
{ |
if( *p == '\"' ) |
{ |
p++; |
if( state == QUOTE_NONE ) |
{ |
state = QUOTE_STARTED; |
} |
else |
{ |
state = QUOTE_NONE; |
} |
continue; |
} |
if( *p == ' ' || *p == '\t' ) |
{ |
if( state == QUOTE_NONE ) |
{ |
break; |
} |
} |
if( *p == '\0' ) |
break; |
if( *p == '\\' ) |
{ |
if( p[1] == '\"' ) |
{ |
++p; |
if( p[-2] == '\\' ) |
{ |
continue; |
} |
} |
} |
if( argv ) |
{ |
*(new_arg++) = *p; |
} |
++p; |
}; |
if( argv ) |
{ |
argv[ argc ] = start; |
++argc; |
/* |
The *new = '\0' is req'd in case there was a \" to " |
translation. It must be after the *p check against |
'\0' because new and p could point to the same char |
in which case the scan would be terminated too soon. |
*/ |
if( *p == '\0' ) |
{ |
*new_arg = '\0'; |
break; |
} |
*new_arg = '\0'; |
++p; |
} |
else |
{ |
++argc; |
if( *p == '\0' ) |
{ |
break; |
} |
++p; |
} |
} |
return argc; |
}; |
char *strstr(const char *cs, const char *ct) |
{ |
int d0, d1; |
register char *__res; |
__asm__ __volatile__( |
"movl %6,%%edi\n\t" |
"repne\n\t" |
"scasb\n\t" |
"notl %%ecx\n\t" |
"decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */ |
"movl %%ecx,%%edx\n" |
"1:\tmovl %6,%%edi\n\t" |
"movl %%esi,%%eax\n\t" |
"movl %%edx,%%ecx\n\t" |
"repe\n\t" |
"cmpsb\n\t" |
"je 2f\n\t" /* also works for empty string, see above */ |
"xchgl %%eax,%%esi\n\t" |
"incl %%esi\n\t" |
"cmpb $0,-1(%%eax)\n\t" |
"jne 1b\n\t" |
"xorl %%eax,%%eax\n\t" |
"2:" |
: "=a" (__res), "=&c" (d0), "=&S" (d1) |
: "0" (0), "1" (0xffffffff), "2" (cs), "g" (ct) |
: "dx", "di"); |
return __res; |
} |
fb_get_options(const char *name, char **option) |
{ |
char *opt, *options = NULL; |
int retval = 1; |
int name_len; |
if(i915.cmdline_mode == NULL) |
return 1; |
name_len = __builtin_strlen(name); |
if (name_len ) |
{ |
opt = i915.cmdline_mode; |
if (!__builtin_strncmp(name, opt, name_len) && |
opt[name_len] == ':') |
{ |
options = opt + name_len + 1; |
retval = 0; |
} |
} |
if (option) |
*option = options; |
return retval; |
} |