Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
5f3dbedf
Commit
5f3dbedf
authored
Apr 03, 2009
by
Dave Airlie
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'drm-intel-next' of ../anholt-2.6 into drm-linus
parents
7a1fb5d0
1055f9dd
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
292 additions
and
123 deletions
+292
-123
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_gem.c
+1
-6
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/drm_sysfs.c
+1
-0
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_dma.c
+1
-8
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_drv.h
+5
-0
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem.c
+29
-9
drivers/gpu/drm/i915/i915_gem_debug.c
drivers/gpu/drm/i915/i915_gem_debug.c
+2
-0
drivers/gpu/drm/i915/i915_gem_debugfs.c
drivers/gpu/drm/i915/i915_gem_debugfs.c
+6
-0
drivers/gpu/drm/i915/i915_gem_tiling.c
drivers/gpu/drm/i915/i915_gem_tiling.c
+16
-0
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_irq.c
+62
-5
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_reg.h
+11
-0
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_crt.c
+2
-2
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_display.c
+21
-1
drivers/gpu/drm/i915/intel_modes.c
drivers/gpu/drm/i915/intel_modes.c
+1
-0
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_sdvo.c
+108
-85
drivers/gpu/drm/i915/intel_sdvo_regs.h
drivers/gpu/drm/i915/intel_sdvo_regs.h
+3
-0
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/i915/intel_tv.c
+23
-7
No files found.
drivers/gpu/drm/drm_gem.c
View file @
5f3dbedf
...
...
@@ -505,7 +505,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
struct
drm_local_map
*
map
=
NULL
;
struct
drm_gem_object
*
obj
;
struct
drm_hash_item
*
hash
;
unsigned
long
prot
;
int
ret
=
0
;
mutex_lock
(
&
dev
->
struct_mutex
);
...
...
@@ -538,11 +537,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
vma
->
vm_ops
=
obj
->
dev
->
driver
->
gem_vm_ops
;
vma
->
vm_private_data
=
map
->
handle
;
/* FIXME: use pgprot_writecombine when available */
prot
=
pgprot_val
(
vma
->
vm_page_prot
);
#ifdef CONFIG_X86
prot
|=
_PAGE_CACHE_WC
;
#endif
vma
->
vm_page_prot
=
__pgprot
(
prot
);
vma
->
vm_page_prot
=
pgprot_writecombine
(
vma
->
vm_page_prot
);
/* Take a ref for this mapping of the object, so that the fault
* handler can dereference the mmap offset's pointer to the object.
...
...
drivers/gpu/drm/drm_sysfs.c
View file @
5f3dbedf
...
...
@@ -451,6 +451,7 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
kobject_uevent_env
(
&
dev
->
primary
->
kdev
.
kobj
,
KOBJ_CHANGE
,
envp
);
}
EXPORT_SYMBOL
(
drm_sysfs_hotplug_event
);
/**
* drm_sysfs_device_add - adds a class device to sysfs for a character driver
...
...
drivers/gpu/drm/i915/i915_dma.c
View file @
5f3dbedf
...
...
@@ -922,7 +922,7 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
* Some of the preallocated space is taken by the GTT
* and popup. GTT is 1K per MB of aperture size, and popup is 4K.
*/
if
(
IS_G4X
(
dev
))
if
(
IS_G4X
(
dev
)
||
IS_IGD
(
dev
)
)
overhead
=
4096
;
else
overhead
=
(
*
aperture_size
/
1024
)
+
4096
;
...
...
@@ -1030,13 +1030,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
if
(
ret
)
goto
destroy_ringbuffer
;
/* FIXME: re-add hotplug support */
#if 0
ret = drm_hotplug_init(dev);
if (ret)
goto destroy_ringbuffer;
#endif
/* Always safe in the mode setting case. */
/* FIXME: do pre/post-mode set stuff in core KMS code */
dev
->
vblank_disable_allowed
=
1
;
...
...
drivers/gpu/drm/i915/i915_drv.h
View file @
5f3dbedf
...
...
@@ -159,6 +159,9 @@ typedef struct drm_i915_private {
u32
irq_mask_reg
;
u32
pipestat
[
2
];
u32
hotplug_supported_mask
;
struct
work_struct
hotplug_work
;
int
tex_lru_log_granularity
;
int
allow_batchbuffer
;
struct
mem_block
*
agp_heap
;
...
...
@@ -297,6 +300,7 @@ typedef struct drm_i915_private {
*
* A reference is held on the buffer while on this list.
*/
spinlock_t
active_list_lock
;
struct
list_head
active_list
;
/**
...
...
@@ -810,6 +814,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
IS_I915GM(dev)))
#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev))
#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
...
...
drivers/gpu/drm/i915/i915_gem.c
View file @
5f3dbedf
...
...
@@ -1072,6 +1072,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
case
-
EAGAIN
:
return
VM_FAULT_OOM
;
case
-
EFAULT
:
case
-
EINVAL
:
return
VM_FAULT_SIGBUS
;
default:
return
VM_FAULT_NOPAGE
;
...
...
@@ -1324,8 +1325,10 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
obj_priv
->
active
=
1
;
}
/* Move from whatever list we were on to the tail of execution. */
spin_lock
(
&
dev_priv
->
mm
.
active_list_lock
);
list_move_tail
(
&
obj_priv
->
list
,
&
dev_priv
->
mm
.
active_list
);
spin_unlock
(
&
dev_priv
->
mm
.
active_list_lock
);
obj_priv
->
last_rendering_seqno
=
seqno
;
}
...
...
@@ -1467,6 +1470,7 @@ i915_gem_retire_request(struct drm_device *dev,
/* Move any buffers on the active list that are no longer referenced
* by the ringbuffer to the flushing/inactive lists as appropriate.
*/
spin_lock
(
&
dev_priv
->
mm
.
active_list_lock
);
while
(
!
list_empty
(
&
dev_priv
->
mm
.
active_list
))
{
struct
drm_gem_object
*
obj
;
struct
drm_i915_gem_object
*
obj_priv
;
...
...
@@ -1481,7 +1485,7 @@ i915_gem_retire_request(struct drm_device *dev,
* this seqno.
*/
if
(
obj_priv
->
last_rendering_seqno
!=
request
->
seqno
)
return
;
goto
out
;
#if WATCH_LRU
DRM_INFO
(
"%s: retire %d moves to inactive list %p
\n
"
,
...
...
@@ -1493,6 +1497,8 @@ i915_gem_retire_request(struct drm_device *dev,
else
i915_gem_object_move_to_inactive
(
obj
);
}
out:
spin_unlock
(
&
dev_priv
->
mm
.
active_list_lock
);
}
/**
...
...
@@ -1990,20 +1996,23 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
int
regnum
=
obj_priv
->
fence_reg
;
uint32_t
val
;
uint32_t
pitch_val
;
uint32_t
fence_size_bits
;
if
((
obj_priv
->
gtt_offset
&
~
I
915
_FENCE_START_MASK
)
||
if
((
obj_priv
->
gtt_offset
&
~
I
830
_FENCE_START_MASK
)
||
(
obj_priv
->
gtt_offset
&
(
obj
->
size
-
1
)))
{
WARN
(
1
,
"%s: object 0x%08x not
1M
or size aligned
\n
"
,
WARN
(
1
,
"%s: object 0x%08x not
512K
or size aligned
\n
"
,
__func__
,
obj_priv
->
gtt_offset
);
return
;
}
pitch_val
=
(
obj_priv
->
stride
/
128
)
-
1
;
WARN_ON
(
pitch_val
&
~
0x0000000f
);
val
=
obj_priv
->
gtt_offset
;
if
(
obj_priv
->
tiling_mode
==
I915_TILING_Y
)
val
|=
1
<<
I830_FENCE_TILING_Y_SHIFT
;
val
|=
I830_FENCE_SIZE_BITS
(
obj
->
size
);
fence_size_bits
=
I830_FENCE_SIZE_BITS
(
obj
->
size
);
WARN_ON
(
fence_size_bits
&
~
0x00000f00
);
val
|=
fence_size_bits
;
val
|=
pitch_val
<<
I830_FENCE_PITCH_SHIFT
;
val
|=
I830_FENCE_REG_VALID
;
...
...
@@ -2194,7 +2203,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
return
-
EBUSY
;
if
(
alignment
==
0
)
alignment
=
i915_gem_get_gtt_alignment
(
obj
);
if
(
alignment
&
(
PAGE_SIZE
-
1
))
{
if
(
alignment
&
(
i915_gem_get_gtt_alignment
(
obj
)
-
1
))
{
DRM_ERROR
(
"Invalid object alignment requested %u
\n
"
,
alignment
);
return
-
EINVAL
;
}
...
...
@@ -2211,15 +2220,20 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
}
}
if
(
obj_priv
->
gtt_space
==
NULL
)
{
bool
lists_empty
;
/* If the gtt is empty and we're still having trouble
* fitting our object in, we're out of memory.
*/
#if WATCH_LRU
DRM_INFO
(
"%s: GTT full, evicting something
\n
"
,
__func__
);
#endif
if
(
list_empty
(
&
dev_priv
->
mm
.
inactive_list
)
&&
list_empty
(
&
dev_priv
->
mm
.
flushing_list
)
&&
list_empty
(
&
dev_priv
->
mm
.
active_list
))
{
spin_lock
(
&
dev_priv
->
mm
.
active_list_lock
);
lists_empty
=
(
list_empty
(
&
dev_priv
->
mm
.
inactive_list
)
&&
list_empty
(
&
dev_priv
->
mm
.
flushing_list
)
&&
list_empty
(
&
dev_priv
->
mm
.
active_list
));
spin_unlock
(
&
dev_priv
->
mm
.
active_list_lock
);
if
(
lists_empty
)
{
DRM_ERROR
(
"GTT full, but LRU list empty
\n
"
);
return
-
ENOMEM
;
}
...
...
@@ -3675,6 +3689,7 @@ i915_gem_idle(struct drm_device *dev)
i915_gem_retire_requests
(
dev
);
spin_lock
(
&
dev_priv
->
mm
.
active_list_lock
);
if
(
!
dev_priv
->
mm
.
wedged
)
{
/* Active and flushing should now be empty as we've
* waited for a sequence higher than any pending execbuffer
...
...
@@ -3701,6 +3716,7 @@ i915_gem_idle(struct drm_device *dev)
obj_priv
->
obj
->
write_domain
&=
~
I915_GEM_GPU_DOMAINS
;
i915_gem_object_move_to_inactive
(
obj_priv
->
obj
);
}
spin_unlock
(
&
dev_priv
->
mm
.
active_list_lock
);
while
(
!
list_empty
(
&
dev_priv
->
mm
.
flushing_list
))
{
struct
drm_i915_gem_object
*
obj_priv
;
...
...
@@ -3949,7 +3965,10 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
if
(
ret
!=
0
)
return
ret
;
spin_lock
(
&
dev_priv
->
mm
.
active_list_lock
);
BUG_ON
(
!
list_empty
(
&
dev_priv
->
mm
.
active_list
));
spin_unlock
(
&
dev_priv
->
mm
.
active_list_lock
);
BUG_ON
(
!
list_empty
(
&
dev_priv
->
mm
.
flushing_list
));
BUG_ON
(
!
list_empty
(
&
dev_priv
->
mm
.
inactive_list
));
BUG_ON
(
!
list_empty
(
&
dev_priv
->
mm
.
request_list
));
...
...
@@ -3993,6 +4012,7 @@ i915_gem_load(struct drm_device *dev)
{
drm_i915_private_t
*
dev_priv
=
dev
->
dev_private
;
spin_lock_init
(
&
dev_priv
->
mm
.
active_list_lock
);
INIT_LIST_HEAD
(
&
dev_priv
->
mm
.
active_list
);
INIT_LIST_HEAD
(
&
dev_priv
->
mm
.
flushing_list
);
INIT_LIST_HEAD
(
&
dev_priv
->
mm
.
inactive_list
);
...
...
drivers/gpu/drm/i915/i915_gem_debug.c
View file @
5f3dbedf
...
...
@@ -105,12 +105,14 @@ i915_dump_lru(struct drm_device *dev, const char *where)
struct
drm_i915_gem_object
*
obj_priv
;
DRM_INFO
(
"active list %s {
\n
"
,
where
);
spin_lock
(
&
dev_priv
->
mm
.
active_list_lock
);
list_for_each_entry
(
obj_priv
,
&
dev_priv
->
mm
.
active_list
,
list
)
{
DRM_INFO
(
" %p: %08x
\n
"
,
obj_priv
,
obj_priv
->
last_rendering_seqno
);
}
spin_unlock
(
&
dev_priv
->
mm
.
active_list_lock
);
DRM_INFO
(
"}
\n
"
);
DRM_INFO
(
"flushing list %s {
\n
"
,
where
);
list_for_each_entry
(
obj_priv
,
&
dev_priv
->
mm
.
flushing_list
,
...
...
drivers/gpu/drm/i915/i915_gem_debugfs.c
View file @
5f3dbedf
...
...
@@ -69,10 +69,13 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
struct
drm_device
*
dev
=
node
->
minor
->
dev
;
drm_i915_private_t
*
dev_priv
=
dev
->
dev_private
;
struct
drm_i915_gem_object
*
obj_priv
;
spinlock_t
*
lock
=
NULL
;
switch
(
list
)
{
case
ACTIVE_LIST
:
seq_printf
(
m
,
"Active:
\n
"
);
lock
=
&
dev_priv
->
mm
.
active_list_lock
;
spin_lock
(
lock
);
head
=
&
dev_priv
->
mm
.
active_list
;
break
;
case
INACTIVE_LIST
:
...
...
@@ -104,6 +107,9 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
seq_printf
(
m
,
" (fence: %d
\n
"
,
obj_priv
->
fence_reg
);
seq_printf
(
m
,
"
\n
"
);
}
if
(
lock
)
spin_unlock
(
lock
);
return
0
;
}
...
...
drivers/gpu/drm/i915/i915_gem_tiling.c
View file @
5f3dbedf
...
...
@@ -216,6 +216,22 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
else
tile_width
=
512
;
/* check maximum stride & object size */
if
(
IS_I965G
(
dev
))
{
/* i965 stores the end address of the gtt mapping in the fence
* reg, so dont bother to check the size */
if
(
stride
/
128
>
I965_FENCE_MAX_PITCH_VAL
)
return
false
;
}
else
if
(
IS_I9XX
(
dev
))
{
if
(
stride
/
tile_width
>
I830_FENCE_MAX_PITCH_VAL
||
size
>
(
I830_FENCE_MAX_SIZE_VAL
<<
20
))
return
false
;
}
else
{
if
(
stride
/
128
>
I830_FENCE_MAX_PITCH_VAL
||
size
>
(
I830_FENCE_MAX_SIZE_VAL
<<
19
))
return
false
;
}
/* 965+ just needs multiples of tile width */
if
(
IS_I965G
(
dev
))
{
if
(
stride
&
(
tile_width
-
1
))
...
...
drivers/gpu/drm/i915/i915_irq.c
View file @
5f3dbedf
...
...
@@ -48,10 +48,6 @@
/** Interrupts that we mask and unmask at runtime. */
#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
/** These are all of the interrupts used by the driver */
#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
I915_INTERRUPT_ENABLE_VAR)
#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\
PIPE_VBLANK_INTERRUPT_STATUS)
...
...
@@ -187,6 +183,19 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
return
I915_READ
(
reg
);
}
/*
* Handle hotplug events outside the interrupt handler proper.
*/
static
void
i915_hotplug_work_func
(
struct
work_struct
*
work
)
{
drm_i915_private_t
*
dev_priv
=
container_of
(
work
,
drm_i915_private_t
,
hotplug_work
);
struct
drm_device
*
dev
=
dev_priv
->
dev
;
/* Just fire off a uevent and let userspace tell us what to do */
drm_sysfs_hotplug_event
(
dev
);
}
irqreturn_t
i915_driver_irq_handler
(
DRM_IRQ_ARGS
)
{
struct
drm_device
*
dev
=
(
struct
drm_device
*
)
arg
;
...
...
@@ -244,6 +253,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
ret
=
IRQ_HANDLED
;
/* Consume port. Then clear IIR or we'll miss events */
if
((
I915_HAS_HOTPLUG
(
dev
))
&&
(
iir
&
I915_DISPLAY_PORT_INTERRUPT
))
{
u32
hotplug_status
=
I915_READ
(
PORT_HOTPLUG_STAT
);
DRM_DEBUG
(
"hotplug event received, stat 0x%08x
\n
"
,
hotplug_status
);
if
(
hotplug_status
&
dev_priv
->
hotplug_supported_mask
)
schedule_work
(
&
dev_priv
->
hotplug_work
);
I915_WRITE
(
PORT_HOTPLUG_STAT
,
hotplug_status
);
I915_READ
(
PORT_HOTPLUG_STAT
);
}
I915_WRITE
(
IIR
,
iir
);
new_iir
=
I915_READ
(
IIR
);
/* Flush posted writes */
...
...
@@ -528,17 +551,24 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
atomic_set
(
&
dev_priv
->
irq_received
,
0
);
if
(
I915_HAS_HOTPLUG
(
dev
))
{
I915_WRITE
(
PORT_HOTPLUG_EN
,
0
);
I915_WRITE
(
PORT_HOTPLUG_STAT
,
I915_READ
(
PORT_HOTPLUG_STAT
));
}
I915_WRITE
(
HWSTAM
,
0xeffe
);
I915_WRITE
(
PIPEASTAT
,
0
);
I915_WRITE
(
PIPEBSTAT
,
0
);
I915_WRITE
(
IMR
,
0xffffffff
);
I915_WRITE
(
IER
,
0x0
);
(
void
)
I915_READ
(
IER
);
INIT_WORK
(
&
dev_priv
->
hotplug_work
,
i915_hotplug_work_func
);
}
int
i915_driver_irq_postinstall
(
struct
drm_device
*
dev
)
{
drm_i915_private_t
*
dev_priv
=
(
drm_i915_private_t
*
)
dev
->
dev_private
;
u32
enable_mask
=
I915_INTERRUPT_ENABLE_FIX
|
I915_INTERRUPT_ENABLE_VAR
;
dev_priv
->
vblank_pipe
=
DRM_I915_VBLANK_PIPE_A
|
DRM_I915_VBLANK_PIPE_B
;
...
...
@@ -550,13 +580,35 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
dev_priv
->
pipestat
[
0
]
=
0
;
dev_priv
->
pipestat
[
1
]
=
0
;
if
(
I915_HAS_HOTPLUG
(
dev
))
{
u32
hotplug_en
=
I915_READ
(
PORT_HOTPLUG_EN
);
/* Leave other bits alone */
hotplug_en
|=
HOTPLUG_EN_MASK
;
I915_WRITE
(
PORT_HOTPLUG_EN
,
hotplug_en
);
dev_priv
->
hotplug_supported_mask
=
CRT_HOTPLUG_INT_STATUS
|
TV_HOTPLUG_INT_STATUS
|
SDVOC_HOTPLUG_INT_STATUS
|
SDVOB_HOTPLUG_INT_STATUS
;
if
(
IS_G4X
(
dev
))
{
dev_priv
->
hotplug_supported_mask
|=
HDMIB_HOTPLUG_INT_STATUS
|
HDMIC_HOTPLUG_INT_STATUS
|
HDMID_HOTPLUG_INT_STATUS
;
}
/* Enable in IER... */
enable_mask
|=
I915_DISPLAY_PORT_INTERRUPT
;
/* and unmask in IMR */
i915_enable_irq
(
dev_priv
,
I915_DISPLAY_PORT_INTERRUPT
);
}
/* Disable pipe interrupt enables, clear pending pipe status */
I915_WRITE
(
PIPEASTAT
,
I915_READ
(
PIPEASTAT
)
&
0x8000ffff
);
I915_WRITE
(
PIPEBSTAT
,
I915_READ
(
PIPEBSTAT
)
&
0x8000ffff
);
/* Clear pending interrupt status */
I915_WRITE
(
IIR
,
I915_READ
(
IIR
));
I915_WRITE
(
IER
,
I915_INTERRUPT_ENABLE_MASK
);
I915_WRITE
(
IER
,
enable_mask
);
I915_WRITE
(
IMR
,
dev_priv
->
irq_mask_reg
);
(
void
)
I915_READ
(
IER
);
...
...
@@ -575,6 +627,11 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
dev_priv
->
vblank_pipe
=
0
;
if
(
I915_HAS_HOTPLUG
(
dev
))
{
I915_WRITE
(
PORT_HOTPLUG_EN
,
0
);
I915_WRITE
(
PORT_HOTPLUG_STAT
,
I915_READ
(
PORT_HOTPLUG_STAT
));
}
I915_WRITE
(
HWSTAM
,
0xffffffff
);
I915_WRITE
(
PIPEASTAT
,
0
);
I915_WRITE
(
PIPEBSTAT
,
0
);
...
...
drivers/gpu/drm/i915/i915_reg.h
View file @
5f3dbedf
...
...
@@ -190,6 +190,8 @@
#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8)
#define I830_FENCE_PITCH_SHIFT 4
#define I830_FENCE_REG_VALID (1<<0)
#define I830_FENCE_MAX_PITCH_VAL 0x10
#define I830_FENCE_MAX_SIZE_VAL (1<<8)
#define I915_FENCE_START_MASK 0x0ff00000
#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8)
...
...
@@ -198,6 +200,7 @@
#define I965_FENCE_PITCH_SHIFT 2
#define I965_FENCE_TILING_Y_SHIFT 1
#define I965_FENCE_REG_VALID (1<<0)
#define I965_FENCE_MAX_PITCH_VAL 0x0400
/*
* Instruction and interrupt control regs
...
...
@@ -648,6 +651,14 @@
#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2)
#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
#define CRT_HOTPLUG_MASK (0x3fc)
/* Bits 9-2 */
#define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f
#define HOTPLUG_EN_MASK (HDMIB_HOTPLUG_INT_EN | \
HDMIC_HOTPLUG_INT_EN | \
HDMID_HOTPLUG_INT_EN | \
SDVOB_HOTPLUG_INT_EN | \
SDVOC_HOTPLUG_INT_EN | \
TV_HOTPLUG_INT_EN | \
CRT_HOTPLUG_INT_EN)
#define PORT_HOTPLUG_STAT 0x61114
...
...
drivers/gpu/drm/i915/intel_crt.c
View file @
5f3dbedf
...
...
@@ -41,7 +41,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
temp
=
I915_READ
(
ADPA
);
temp
&=
~
(
ADPA_HSYNC_CNTL_DISABLE
|
ADPA_VSYNC_CNTL_DISABLE
);
temp
&=
~
ADPA_DAC_ENABLE
;
temp
|=
ADPA_DAC_ENABLE
;
switch
(
mode
)
{
case
DRM_MODE_DPMS_ON
:
...
...
@@ -158,7 +158,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
else
tries
=
1
;
hotplug_en
=
I915_READ
(
PORT_HOTPLUG_EN
);
hotplug_en
&=
~
(
CRT_HOTPLUG_MASK
)
;
hotplug_en
&=
CRT_FORCE_HOTPLUG_MASK
;
hotplug_en
|=
CRT_HOTPLUG_FORCE_DETECT
;
if
(
IS_GM45
(
dev
))
...
...
drivers/gpu/drm/i915/intel_display.c
View file @
5f3dbedf
...
...
@@ -636,7 +636,7 @@ void
intel_wait_for_vblank
(
struct
drm_device
*
dev
)
{
/* Wait for 20ms, i.e. one cycle at 50hz. */
udelay
(
2000
0
);
mdelay
(
2
0
);
}
static
int
...
...
@@ -1106,6 +1106,26 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
return
-
EINVAL
;
}
/* SDVO TV has fixed PLL values depend on its clock range,
this mirrors vbios setting. */
if
(
is_sdvo
&&
is_tv
)
{
if
(
adjusted_mode
->
clock
>=
100000
&&
adjusted_mode
->
clock
<
140500
)
{
clock
.
p1
=
2
;
clock
.
p2
=
10
;
clock
.
n
=
3
;
clock
.
m1
=
16
;
clock
.
m2
=
8
;
}
else
if
(
adjusted_mode
->
clock
>=
140500
&&
adjusted_mode
->
clock
<=
200000
)
{
clock
.
p1
=
1
;
clock
.
p2
=
10
;
clock
.
n
=
6
;
clock
.
m1
=
12
;
clock
.
m2
=
8
;
}
}
if
(
IS_IGD
(
dev
))
fp
=
(
1
<<
clock
.
n
)
<<
16
|
clock
.
m1
<<
8
|
clock
.
m2
;
else
...
...
drivers/gpu/drm/i915/intel_modes.c
View file @
5f3dbedf
...
...
@@ -76,6 +76,7 @@ int intel_ddc_get_modes(struct intel_output *intel_output)
drm_mode_connector_update_edid_property
(
&
intel_output
->
base
,
edid
);
ret
=
drm_add_edid_modes
(
&
intel_output
->
base
,
edid
);
intel_output
->
base
.
display_info
.
raw_edid
=
NULL
;
kfree
(
edid
);
}
...
...
drivers/gpu/drm/i915/intel_sdvo.c
View file @
5f3dbedf
...
...
@@ -273,20 +273,20 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
struct
intel_sdvo_priv
*
sdvo_priv
=
intel_output
->
dev_priv
;
int
i
;
DRM_DEBUG
(
"%s: W: %02X "
,
SDVO_NAME
(
sdvo_priv
),
cmd
);
printk
(
KERN_DEBUG
"%s: W: %02X "
,
SDVO_NAME
(
sdvo_priv
),
cmd
);
for
(
i
=
0
;
i
<
args_len
;
i
++
)
printk
(
"%02X "
,
((
u8
*
)
args
)[
i
]);
printk
(
KERN_DEBUG
"%02X "
,
((
u8
*
)
args
)[
i
]);
for
(;
i
<
8
;
i
++
)
printk
(
" "
);
printk
(
KERN_DEBUG
" "
);
for
(
i
=
0
;
i
<
sizeof
(
sdvo_cmd_names
)
/
sizeof
(
sdvo_cmd_names
[
0
]);
i
++
)
{
if
(
cmd
==
sdvo_cmd_names
[
i
].
cmd
)
{
printk
(
"(%s)"
,
sdvo_cmd_names
[
i
].
name
);
printk
(
KERN_DEBUG
"(%s)"
,
sdvo_cmd_names
[
i
].
name
);
break
;
}
}
if
(
i
==
sizeof
(
sdvo_cmd_names
)
/
sizeof
(
sdvo_cmd_names
[
0
]))
printk
(
"(%02X)"
,
cmd
);
printk
(
"
\n
"
);
printk
(
KERN_DEBUG
"(%02X)"
,
cmd
);
printk
(
KERN_DEBUG
"
\n
"
);
}
#else
#define intel_sdvo_debug_write(o, c, a, l)
...
...
@@ -323,17 +323,18 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
u8
status
)
{
struct
intel_sdvo_priv
*
sdvo_priv
=
intel_output
->
dev_priv
;
int
i
;
DRM_DEBUG
(
"%s: R: "
,
SDVO_NAME
(
sdvo_priv
));
printk
(
KERN_DEBUG
"%s: R: "
,
SDVO_NAME
(
sdvo_priv
));
for
(
i
=
0
;
i
<
response_len
;
i
++
)
printk
(
"%02X "
,
((
u8
*
)
response
)[
i
]);
printk
(
KERN_DEBUG
"%02X "
,
((
u8
*
)
response
)[
i
]);
for
(;
i
<
8
;
i
++
)
printk
(
" "
);
printk
(
KERN_DEBUG
" "
);
if
(
status
<=
SDVO_CMD_STATUS_SCALING_NOT_SUPP
)
printk
(
"(%s)"
,
cmd_status_names
[
status
]);
printk
(
KERN_DEBUG
"(%s)"
,
cmd_status_names
[
status
]);
else
printk
(
"(??? %d)"
,
status
);
printk
(
"
\n
"
);
printk
(
KERN_DEBUG
"(??? %d)"
,
status
);
printk
(
KERN_DEBUG
"
\n
"
);
}
#else
#define intel_sdvo_debug_response(o, r, l, s)
...
...
@@ -588,9 +589,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,
struct
intel_sdvo_preferred_input_timing_args
args
;
uint8_t
status
;
memset
(
&
args
,
0
,
sizeof
(
args
));
args
.
clock
=
clock
;
args
.
width
=
width
;
args
.
height
=
height
;
args
.
interlace
=
0
;
args
.
scaled
=
0
;
intel_sdvo_write_cmd
(
output
,
SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING
,
&
args
,
sizeof
(
args
));
status
=
intel_sdvo_read_response
(
output
,
NULL
,
0
);
...
...
@@ -683,7 +687,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
dtd
->
part1
.
v_high
=
(((
height
>>
8
)
&
0xf
)
<<
4
)
|
((
v_blank_len
>>
8
)
&
0xf
);
dtd
->
part2
.
h_sync_off
=
h_sync_offset
;
dtd
->
part2
.
h_sync_off
=
h_sync_offset
&
0xff
;
dtd
->
part2
.
h_sync_width
=
h_sync_len
&
0xff
;
dtd
->
part2
.
v_sync_off_width
=
(
v_sync_offset
&
0xf
)
<<
4
|
(
v_sync_len
&
0xf
);
...
...
@@ -705,27 +709,10 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
static
void
intel_sdvo_get_mode_from_dtd
(
struct
drm_display_mode
*
mode
,
struct
intel_sdvo_dtd
*
dtd
)
{
uint16_t
width
,
height
;
uint16_t
h_blank_len
,
h_sync_len
,
v_blank_len
,
v_sync_len
;
uint16_t
h_sync_offset
,
v_sync_offset
;
width
=
mode
->
crtc_hdisplay
;
height
=
mode
->
crtc_vdisplay
;
/* do some mode translations */
h_blank_len
=
mode
->
crtc_hblank_end
-
mode
->
crtc_hblank_start
;
h_sync_len
=
mode
->
crtc_hsync_end
-
mode
->
crtc_hsync_start
;
v_blank_len
=
mode
->
crtc_vblank_end
-
mode
->
crtc_vblank_start
;
v_sync_len
=
mode
->
crtc_vsync_end
-
mode
->
crtc_vsync_start
;
h_sync_offset
=
mode
->
crtc_hsync_start
-
mode
->
crtc_hblank_start
;
v_sync_offset
=
mode
->
crtc_vsync_start
-
mode
->
crtc_vblank_start
;
mode
->
hdisplay
=
dtd
->
part1
.
h_active
;
mode
->
hdisplay
+=
((
dtd
->
part1
.
h_high
>>
4
)
&
0x0f
)
<<
8
;
mode
->
hsync_start
=
mode
->
hdisplay
+
dtd
->
part2
.
h_sync_off
;
mode
->
hsync_start
+=
(
dtd
->
part2
.
sync_off_width_high
&
0x
a
0
)
<<
2
;
mode
->
hsync_start
+=
(
dtd
->
part2
.
sync_off_width_high
&
0x
c
0
)
<<
2
;
mode
->
hsync_end
=
mode
->
hsync_start
+
dtd
->
part2
.
h_sync_width
;
mode
->
hsync_end
+=
(
dtd
->
part2
.
sync_off_width_high
&
0x30
)
<<
4
;
mode
->
htotal
=
mode
->
hdisplay
+
dtd
->
part1
.
h_blank
;
...
...
@@ -735,7 +722,7 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
mode
->
vdisplay
+=
((
dtd
->
part1
.
v_high
>>
4
)
&
0x0f
)
<<
8
;
mode
->
vsync_start
=
mode
->
vdisplay
;
mode
->
vsync_start
+=
(
dtd
->
part2
.
v_sync_off_width
>>
4
)
&
0xf
;
mode
->
vsync_start
+=
(
dtd
->
part2
.
sync_off_width_high
&
0x0
a
)
<<
2
;
mode
->
vsync_start
+=
(
dtd
->
part2
.
sync_off_width_high
&
0x0
c
)
<<
2
;
mode
->
vsync_start
+=
dtd
->
part2
.
v_sync_off_high
&
0xc0
;
mode
->
vsync_end
=
mode
->
vsync_start
+
(
dtd
->
part2
.
v_sync_off_width
&
0xf
);
...
...
@@ -745,7 +732,7 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
mode
->
clock
=
dtd
->
part1
.
clock
*
10
;
mode
->
flags
&=
(
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
);
mode
->
flags
&=
~
(
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
);
if
(
dtd
->
part2
.
dtd_flags
&
0x2
)
mode
->
flags
|=
DRM_MODE_FLAG_PHSYNC
;
if
(
dtd
->
part2
.
dtd_flags
&
0x4
)
...
...
@@ -924,6 +911,27 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
SDVO_HBUF_TX_VSYNC
);
}
static
void
intel_sdvo_set_tv_format
(
struct
intel_output
*
output
)
{
struct
intel_sdvo_priv
*
sdvo_priv
=
output
->
dev_priv
;
struct
intel_sdvo_tv_format
*
format
,
unset
;
u8
status
;
format
=
&
sdvo_priv
->
tv_format
;
memset
(
&
unset
,
0
,
sizeof
(
unset
));
if
(
memcmp
(
format
,
&
unset
,
sizeof
(
*
format
)))
{
DRM_DEBUG
(
"%s: Choosing default TV format of NTSC-M
\n
"
,
SDVO_NAME
(
sdvo_priv
));
format
->
ntsc_m
=
1
;
intel_sdvo_write_cmd
(
output
,
SDVO_CMD_SET_TV_FORMAT
,
format
,
sizeof
(
*
format
));
status
=
intel_sdvo_read_response
(
output
,
NULL
,
0
);
if
(
status
!=
SDVO_CMD_STATUS_SUCCESS
)
DRM_DEBUG
(
"%s: Failed to set TV format
\n
"
,
SDVO_NAME
(
sdvo_priv
));
}
}
static
bool
intel_sdvo_mode_fixup
(
struct
drm_encoder
*
encoder
,
struct
drm_display_mode
*
mode
,
struct
drm_display_mode
*
adjusted_mode
)
...
...
@@ -968,6 +976,12 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
&
input_dtd
);
intel_sdvo_get_mode_from_dtd
(
adjusted_mode
,
&
input_dtd
);
drm_mode_set_crtcinfo
(
adjusted_mode
,
0
);
mode
->
clock
=
adjusted_mode
->
clock
;
adjusted_mode
->
clock
*=
intel_sdvo_get_pixel_multiplier
(
mode
);
}
else
{
return
false
;
}
...
...
@@ -1012,7 +1026,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
sdvox
|=
SDVO_AUDIO_ENABLE
;
}
intel_sdvo_get_dtd_from_mode
(
&
input_dtd
,
mode
);
/* We have tried to get input timing in mode_fixup, and filled into
adjusted_mode */
if
(
sdvo_priv
->
is_tv
)
intel_sdvo_get_dtd_from_mode
(
&
input_dtd
,
adjusted_mode
);
else
intel_sdvo_get_dtd_from_mode
(
&
input_dtd
,
mode
);
/* If it's a TV, we already set the output timing in mode_fixup.
* Otherwise, the output timing is equal to the input timing.
...
...
@@ -1027,6 +1046,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
/* Set the input timing to the screen. Assume always input 0. */
intel_sdvo_set_target_input
(
output
,
true
,
false
);
if
(
sdvo_priv
->
is_tv
)
intel_sdvo_set_tv_format
(
output
);
/* We would like to use intel_sdvo_create_preferred_input_timing() to
* provide the device with a timing it can support, if it supports that
* feature. However, presumably we would need to adjust the CRTC to
...
...
@@ -1395,7 +1417,7 @@ static void
intel_sdvo_check_tv_format
(
struct
intel_output
*
output
)
{
struct
intel_sdvo_priv
*
dev_priv
=
output
->
dev_priv
;
struct
intel_sdvo_tv_format
format
,
unset
;
struct
intel_sdvo_tv_format
format
;
uint8_t
status
;
intel_sdvo_write_cmd
(
output
,
SDVO_CMD_GET_TV_FORMAT
,
NULL
,
0
);
...
...
@@ -1403,15 +1425,7 @@ intel_sdvo_check_tv_format(struct intel_output *output)
if
(
status
!=
SDVO_CMD_STATUS_SUCCESS
)
return
;
memset
(
&
unset
,
0
,
sizeof
(
unset
));
if
(
memcmp
(
&
format
,
&
unset
,
sizeof
(
format
)))
{
DRM_DEBUG
(
"%s: Choosing default TV format of NTSC-M
\n
"
,
SDVO_NAME
(
dev_priv
));
format
.
ntsc_m
=
true
;
intel_sdvo_write_cmd
(
output
,
SDVO_CMD_SET_TV_FORMAT
,
NULL
,
0
);
status
=
intel_sdvo_read_response
(
output
,
NULL
,
0
);
}
memcpy
(
&
dev_priv
->
tv_format
,
&
format
,
sizeof
(
format
));
}
/*
...
...
@@ -1420,68 +1434,70 @@ intel_sdvo_check_tv_format(struct intel_output *output)
* XXX: all 60Hz refresh?
*/
struct
drm_display_mode
sdvo_tv_modes
[]
=
{
{
DRM_MODE
(
"320x200"
,
DRM_MODE_TYPE_DRIVER
,
5815
680
,
321
,
384
,
416
,
200
,
0
,
232
,
201
,
233
,
4196112
,
0
,
{
DRM_MODE
(
"320x200"
,
DRM_MODE_TYPE_DRIVER
,
5815
,
320
,
321
,
384
,
416
,
0
,
200
,
201
,
232
,
233
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"320x240"
,
DRM_MODE_TYPE_DRIVER
,
6814
080
,
321
,
384
,
416
,
240
,
0
,
272
,
241
,
273
,
4196112
,
0
,
{
DRM_MODE
(
"320x240"
,
DRM_MODE_TYPE_DRIVER
,
6814
,
320
,
321
,
384
,
416
,
0
,
240
,
241
,
272
,
273
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"400x300"
,
DRM_MODE_TYPE_DRIVER
,
9910
080
,
401
,
464
,
496
,
300
,
0
,
332
,
301
,
333
,
4196112
,
0
,
{
DRM_MODE
(
"400x300"
,
DRM_MODE_TYPE_DRIVER
,
9910
,
400
,
401
,
464
,
496
,
0
,
300
,
301
,
332
,
333
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"640x350"
,
DRM_MODE_TYPE_DRIVER
,
16913
280
,
641
,
704
,
736
,
350
,
0
,
382
,
351
,
383
,
4196112
,
0
,
{
DRM_MODE
(
"640x350"
,
DRM_MODE_TYPE_DRIVER
,
16913
,
640
,
641
,
704
,
736
,
0
,
350
,
351
,
382
,
383
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"640x400"
,
DRM_MODE_TYPE_DRIVER
,
19121
280
,
641
,
704
,
736
,
400
,
0
,
432
,
401
,
433
,
4196112
,
0
,
{
DRM_MODE
(
"640x400"
,
DRM_MODE_TYPE_DRIVER
,
19121
,
640
,
641
,
704
,
736
,
0
,
400
,
401
,
432
,
433
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"640x4
00"
,
DRM_MODE_TYPE_DRIVER
,
19121280
,
641
,
704
,
736
,
400
,
0
,
432
,
401
,
433
,
4196112
,
0
,
{
DRM_MODE
(
"640x4
80"
,
DRM_MODE_TYPE_DRIVER
,
22654
,
640
,
641
,
704
,
736
,
0
,
480
,
481
,
512
,
513
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"704x480"
,
DRM_MODE_TYPE_DRIVER
,
24624
000
,
705
,
768
,
800
,
480
,
0
,
512
,
481
,
513
,
4196112
,
0
,
{
DRM_MODE
(
"704x480"
,
DRM_MODE_TYPE_DRIVER
,
24624
,
704
,
705
,
768
,
800
,
0
,
480
,
481
,
512
,
513
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"704x576"
,
DRM_MODE_TYPE_DRIVER
,
29232
000
,
705
,
768
,
800
,
576
,
0
,
608
,
577
,
609
,
4196112
,
0
,
{
DRM_MODE
(
"704x576"
,
DRM_MODE_TYPE_DRIVER
,
29232
,
704
,
705
,
768
,
800
,
0
,
576
,
577
,
608
,
609
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"720x350"
,
DRM_MODE_TYPE_DRIVER
,
18751
680
,
721
,
784
,
816
,
350
,
0
,
382
,
351
,
383
,
4196112
,
0
,
{
DRM_MODE
(
"720x350"
,
DRM_MODE_TYPE_DRIVER
,
18751
,
720
,
721
,
784
,
816
,
0
,
350
,
351
,
382
,
383
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"720x400"
,
DRM_MODE_TYPE_DRIVER
,
21199
680
,
721
,
784
,
816
,
400
,
0
,
432
,
401
,
433
,
4196112
,
0
,
{
DRM_MODE
(
"720x400"
,
DRM_MODE_TYPE_DRIVER
,
21199
,
720
,
721
,
784
,
816
,
0
,
400
,
401
,
432
,
433
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"720x480"
,
DRM_MODE_TYPE_DRIVER
,
25116
480
,
721
,
784
,
816
,
480
,
0
,
512
,
481
,
513
,
4196112
,
0
,
{
DRM_MODE
(
"720x480"
,
DRM_MODE_TYPE_DRIVER
,
25116
,
720
,
721
,
784
,
816
,
0
,
480
,
481
,
512
,
513
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"720x540"
,
DRM_MODE_TYPE_DRIVER
,
28054
080
,
721
,
784
,
816
,
540
,
0
,
572
,
541
,
573
,
4196112
,
0
,
{
DRM_MODE
(
"720x540"
,
DRM_MODE_TYPE_DRIVER
,
28054
,
720
,
721
,
784
,
816
,
0
,
540
,
541
,
572
,
573
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"720x576"
,
DRM_MODE_TYPE_DRIVER
,
29816
640
,
721
,
784
,
816
,
576
,
0
,
608
,
577
,
609
,
4196112
,
0
,
{
DRM_MODE
(
"720x576"
,
DRM_MODE_TYPE_DRIVER
,
29816
,
720
,
721
,
784
,
816
,
0
,
576
,
577
,
608
,
609
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"768x576"
,
DRM_MODE_TYPE_DRIVER
,
31570
560
,
769
,
832
,
864
,
576
,
0
,
608
,
577
,
609
,
4196112
,
0
,
{
DRM_MODE
(
"768x576"
,
DRM_MODE_TYPE_DRIVER
,
31570
,
768
,
769
,
832
,
864
,
0
,
576
,
577
,
608
,
609
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"800x600"
,
DRM_MODE_TYPE_DRIVER
,
34030
080
,
801
,
864
,
896
,
600
,
0
,
632
,
601
,
633
,
4196112
,
0
,
{
DRM_MODE
(
"800x600"
,
DRM_MODE_TYPE_DRIVER
,
34030
,
800
,
801
,
864
,
896
,
0
,
600
,
601
,
632
,
633
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"832x624"
,
DRM_MODE_TYPE_DRIVER
,
36581
760
,
833
,
896
,
928
,
624
,
0
,
656
,
625
,
657
,
4196112
,
0
,
{
DRM_MODE
(
"832x624"
,
DRM_MODE_TYPE_DRIVER
,
36581
,
832
,
833
,
896
,
928
,
0
,
624
,
625
,
656
,
657
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"920x766"
,
DRM_MODE_TYPE_DRIVER
,
48707
040
,
921
,
984
,
1016
,
766
,
0
,
798
,
767
,
799
,
4196112
,
0
,
{
DRM_MODE
(
"920x766"
,
DRM_MODE_TYPE_DRIVER
,
48707
,
920
,
921
,
984
,
1016
,
0
,
766
,
767
,
798
,
799
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"1024x768"
,
DRM_MODE_TYPE_DRIVER
,
53827
200
,
1025
,
1088
,
1120
,
768
,
0
,
800
,
769
,
801
,
4196112
,
0
,
{
DRM_MODE
(
"1024x768"
,
DRM_MODE_TYPE_DRIVER
,
53827
,
1024
,
1025
,
1088
,
1120
,
0
,
768
,
769
,
800
,
801
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
{
DRM_MODE
(
"1280x1024"
,
DRM_MODE_TYPE_DRIVER
,
87265
920
,
1281
,
1344
,
1376
,
1
024
,
0
,
1056
,
1025
,
1057
,
4196112
,
0
,
{
DRM_MODE
(
"1280x1024"
,
DRM_MODE_TYPE_DRIVER
,
87265
,
1280
,
1281
,
1344
,
1
376
,
0
,
1024
,
1025
,
1056
,
1057
,
0
,
DRM_MODE_FLAG_PHSYNC
|
DRM_MODE_FLAG_PVSYNC
)
},
};
static
void
intel_sdvo_get_tv_modes
(
struct
drm_connector
*
connector
)
{
struct
intel_output
*
output
=
to_intel_output
(
connector
);
struct
intel_sdvo_priv
*
sdvo_priv
=
output
->
dev_priv
;
struct
intel_sdvo_sdtv_resolution_request
tv_res
;
uint32_t
reply
=
0
;
uint8_t
status
;
int
i
=
0
;
...
...
@@ -1491,15 +1507,22 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
/* Read the list of supported input resolutions for the selected TV
* format.
*/
memset
(
&
tv_res
,
0
,
sizeof
(
tv_res
));
memcpy
(
&
tv_res
,
&
sdvo_priv
->
tv_format
,
sizeof
(
tv_res
));
intel_sdvo_write_cmd
(
output
,
SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT
,
NULL
,
0
);
&
tv_res
,
sizeof
(
tv_res
)
);
status
=
intel_sdvo_read_response
(
output
,
&
reply
,
3
);
if
(
status
!=
SDVO_CMD_STATUS_SUCCESS
)
return
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
sdvo_tv_modes
);
i
++
)
if
(
reply
&
(
1
<<
i
))
drm_mode_probed_add
(
connector
,
&
sdvo_tv_modes
[
i
]);
if
(
reply
&
(
1
<<
i
))
{
struct
drm_display_mode
*
nmode
;
nmode
=
drm_mode_duplicate
(
connector
->
dev
,
&
sdvo_tv_modes
[
i
]);
if
(
nmode
)
drm_mode_probed_add
(
connector
,
nmode
);
}
}
static
int
intel_sdvo_get_modes
(
struct
drm_connector
*
connector
)
...
...
drivers/gpu/drm/i915/intel_sdvo_regs.h
View file @
5f3dbedf
...
...
@@ -100,6 +100,9 @@ struct intel_sdvo_preferred_input_timing_args {
u16
clock
;
u16
width
;
u16
height
;
u8
interlace
:
1
;
u8
scaled
:
1
;
u8
pad
:
6
;
}
__attribute__
((
packed
));
/* I2C registers for SDVO */
...
...
drivers/gpu/drm/i915/intel_tv.c
View file @
5f3dbedf
...
...
@@ -1570,33 +1570,49 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
struct
drm_device
*
dev
=
connector
->
dev
;
struct
intel_output
*
intel_output
=
to_intel_output
(
connector
);
struct
intel_tv_priv
*
tv_priv
=
intel_output
->
dev_priv
;
struct
drm_encoder
*
encoder
=
&
intel_output
->
enc
;
struct
drm_crtc
*
crtc
=
encoder
->
crtc
;
int
ret
=
0
;
bool
changed
=
false
;
ret
=
drm_connector_property_set_value
(
connector
,
property
,
val
);
if
(
ret
<
0
)
goto
out
;
if
(
property
==
dev
->
mode_config
.
tv_left_margin_property
)
if
(
property
==
dev
->
mode_config
.
tv_left_margin_property
&&
tv_priv
->
margin
[
TV_MARGIN_LEFT
]
!=
val
)
{
tv_priv
->
margin
[
TV_MARGIN_LEFT
]
=
val
;
else
if
(
property
==
dev
->
mode_config
.
tv_right_margin_property
)
changed
=
true
;
}
else
if
(
property
==
dev
->
mode_config
.
tv_right_margin_property
&&
tv_priv
->
margin
[
TV_MARGIN_RIGHT
]
!=
val
)
{
tv_priv
->
margin
[
TV_MARGIN_RIGHT
]
=
val
;
else
if
(
property
==
dev
->
mode_config
.
tv_top_margin_property
)
changed
=
true
;
}
else
if
(
property
==
dev
->
mode_config
.
tv_top_margin_property
&&
tv_priv
->
margin
[
TV_MARGIN_TOP
]
!=
val
)
{
tv_priv
->
margin
[
TV_MARGIN_TOP
]
=
val
;
else
if
(
property
==
dev
->
mode_config
.
tv_bottom_margin_property
)
changed
=
true
;
}
else
if
(
property
==
dev
->
mode_config
.
tv_bottom_margin_property
&&
tv_priv
->
margin
[
TV_MARGIN_BOTTOM
]
!=
val
)
{
tv_priv
->
margin
[
TV_MARGIN_BOTTOM
]
=
val
;
else
if
(
property
==
dev
->
mode_config
.
tv_mode_property
)
{
changed
=
true
;
}
else
if
(
property
==
dev
->
mode_config
.
tv_mode_property
)
{
if
(
val
>=
NUM_TV_MODES
)
{
ret
=
-
EINVAL
;
goto
out
;
}
if
(
!
strcmp
(
tv_priv
->
tv_format
,
tv_modes
[
val
].
name
))
goto
out
;
tv_priv
->
tv_format
=
tv_modes
[
val
].
name
;
intel_tv_mode_set
(
&
intel_output
->
enc
,
NULL
,
NULL
)
;
changed
=
true
;
}
else
{
ret
=
-
EINVAL
;
goto
out
;
}
intel_tv_mode_set
(
&
intel_output
->
enc
,
NULL
,
NULL
);
if
(
changed
&&
crtc
)
drm_crtc_helper_set_mode
(
crtc
,
&
crtc
->
mode
,
crtc
->
x
,
crtc
->
y
,
crtc
->
fb
);
out:
return
ret
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment