Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
4f47643d
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
4f47643d
编写于
2月 03, 2013
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nouveau/gpio: use event interfaces for interrupt signalling
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
0f080066
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
127 addition
and
219 deletion
+127
-219
drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
+13
-18
drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
+9
-128
drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c
drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c
+22
-11
drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
+27
-12
drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
+3
-1
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_connector.c
+35
-42
drivers/gpu/drm/nouveau/nouveau_connector.h
drivers/gpu/drm/nouveau/nouveau_connector.h
+6
-1
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_display.c
+8
-4
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_dp.c
+4
-2
未找到文件。
drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
浏览文件 @
4f47643d
...
...
@@ -3,6 +3,7 @@
#include <core/subdev.h>
#include <core/device.h>
#include <core/event.h>
#include <subdev/bios.h>
#include <subdev/bios/gpio.h>
...
...
@@ -10,28 +11,18 @@
struct
nouveau_gpio
{
struct
nouveau_subdev
base
;
struct
nouveau_event
*
events
;
/* hardware interfaces */
void
(
*
reset
)(
struct
nouveau_gpio
*
,
u8
func
);
int
(
*
drive
)(
struct
nouveau_gpio
*
,
int
line
,
int
dir
,
int
out
);
int
(
*
sense
)(
struct
nouveau_gpio
*
,
int
line
);
void
(
*
irq_enable
)(
struct
nouveau_gpio
*
,
int
line
,
bool
);
/* software interfaces */
int
(
*
find
)(
struct
nouveau_gpio
*
,
int
idx
,
u8
tag
,
u8
line
,
struct
dcb_gpio_func
*
);
int
(
*
set
)(
struct
nouveau_gpio
*
,
int
idx
,
u8
tag
,
u8
line
,
int
state
);
int
(
*
get
)(
struct
nouveau_gpio
*
,
int
idx
,
u8
tag
,
u8
line
);
int
(
*
irq
)(
struct
nouveau_gpio
*
,
int
idx
,
u8
tag
,
u8
line
,
bool
on
);
/* interrupt handling */
struct
list_head
isr
;
spinlock_t
lock
;
void
(
*
isr_run
)(
struct
nouveau_gpio
*
,
int
idx
,
u32
mask
);
int
(
*
isr_add
)(
struct
nouveau_gpio
*
,
int
idx
,
u8
tag
,
u8
line
,
void
(
*
)(
void
*
,
int
state
),
void
*
data
);
void
(
*
isr_del
)(
struct
nouveau_gpio
*
,
int
idx
,
u8
tag
,
u8
line
,
void
(
*
)(
void
*
,
int
state
),
void
*
data
);
};
static
inline
struct
nouveau_gpio
*
...
...
@@ -42,14 +33,17 @@ nouveau_gpio(void *obj)
#define nouveau_gpio_create(p,e,o,l,d) \
nouveau_gpio_create_((p), (e), (o), (l), sizeof(**d), (void **)d)
#define nouveau_gpio_destroy(p) \
nouveau_subdev_destroy(&(p)->base)
#define nouveau_gpio_destroy(p) ({ \
struct nouveau_gpio *gpio = (p); \
_nouveau_gpio_dtor(nv_object(gpio)); \
})
#define nouveau_gpio_fini(p,s) \
nouveau_subdev_fini(&(p)->base, (s))
int
nouveau_gpio_create_
(
struct
nouveau_object
*
,
struct
nouveau_object
*
,
struct
nouveau_oclass
*
,
int
,
int
,
void
**
);
int
nouveau_gpio_init
(
struct
nouveau_gpio
*
);
int
nouveau_gpio_create_
(
struct
nouveau_object
*
,
struct
nouveau_object
*
,
struct
nouveau_oclass
*
,
int
,
int
,
void
**
);
void
_nouveau_gpio_dtor
(
struct
nouveau_object
*
);
int
nouveau_gpio_init
(
struct
nouveau_gpio
*
);
extern
struct
nouveau_oclass
nv10_gpio_oclass
;
extern
struct
nouveau_oclass
nv50_gpio_oclass
;
...
...
@@ -59,6 +53,7 @@ void nv50_gpio_dtor(struct nouveau_object *);
int
nv50_gpio_init
(
struct
nouveau_object
*
);
int
nv50_gpio_fini
(
struct
nouveau_object
*
,
bool
);
void
nv50_gpio_intr
(
struct
nouveau_subdev
*
);
void
nv50_gpio_irq_enable
(
struct
nouveau_gpio
*
,
int
line
,
bool
);
void
nv50_gpio_intr_enable
(
struct
nouveau_event
*
,
int
line
);
void
nv50_gpio_intr_disable
(
struct
nouveau_event
*
,
int
line
);
#endif
drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
浏览文件 @
4f47643d
...
...
@@ -102,129 +102,12 @@ nouveau_gpio_get(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line)
return
ret
;
}
static
int
nouveau_gpio_irq
(
struct
nouveau_gpio
*
gpio
,
int
idx
,
u8
tag
,
u8
line
,
bool
on
)
{
struct
dcb_gpio_func
func
;
int
ret
;
ret
=
nouveau_gpio_find
(
gpio
,
idx
,
tag
,
line
,
&
func
);
if
(
ret
==
0
)
{
if
(
idx
==
0
&&
gpio
->
irq_enable
)
gpio
->
irq_enable
(
gpio
,
func
.
line
,
on
);
else
ret
=
-
ENODEV
;
}
return
ret
;
}
struct
gpio_isr
{
struct
nouveau_gpio
*
gpio
;
struct
list_head
head
;
struct
work_struct
work
;
int
idx
;
struct
dcb_gpio_func
func
;
void
(
*
handler
)(
void
*
,
int
);
void
*
data
;
bool
inhibit
;
};
static
void
nouveau_gpio_isr_bh
(
struct
work_struct
*
work
)
{
struct
gpio_isr
*
isr
=
container_of
(
work
,
struct
gpio_isr
,
work
);
struct
nouveau_gpio
*
gpio
=
isr
->
gpio
;
unsigned
long
flags
;
int
state
;
state
=
nouveau_gpio_get
(
gpio
,
isr
->
idx
,
isr
->
func
.
func
,
isr
->
func
.
line
);
if
(
state
>=
0
)
isr
->
handler
(
isr
->
data
,
state
);
spin_lock_irqsave
(
&
gpio
->
lock
,
flags
);
isr
->
inhibit
=
false
;
spin_unlock_irqrestore
(
&
gpio
->
lock
,
flags
);
}
static
void
nouveau_gpio_isr_run
(
struct
nouveau_gpio
*
gpio
,
int
idx
,
u32
line_mask
)
{
struct
gpio_isr
*
isr
;
if
(
idx
!=
0
)
return
;
spin_lock
(
&
gpio
->
lock
);
list_for_each_entry
(
isr
,
&
gpio
->
isr
,
head
)
{
if
(
line_mask
&
(
1
<<
isr
->
func
.
line
))
{
if
(
isr
->
inhibit
)
continue
;
isr
->
inhibit
=
true
;
schedule_work
(
&
isr
->
work
);
}
}
spin_unlock
(
&
gpio
->
lock
);
}
static
int
nouveau_gpio_isr_add
(
struct
nouveau_gpio
*
gpio
,
int
idx
,
u8
tag
,
u8
line
,
void
(
*
handler
)(
void
*
,
int
),
void
*
data
)
{
struct
gpio_isr
*
isr
;
unsigned
long
flags
;
int
ret
;
isr
=
kzalloc
(
sizeof
(
*
isr
),
GFP_KERNEL
);
if
(
!
isr
)
return
-
ENOMEM
;
ret
=
nouveau_gpio_find
(
gpio
,
idx
,
tag
,
line
,
&
isr
->
func
);
if
(
ret
)
{
kfree
(
isr
);
return
ret
;
}
INIT_WORK
(
&
isr
->
work
,
nouveau_gpio_isr_bh
);
isr
->
gpio
=
gpio
;
isr
->
handler
=
handler
;
isr
->
data
=
data
;
isr
->
idx
=
idx
;
spin_lock_irqsave
(
&
gpio
->
lock
,
flags
);
list_add
(
&
isr
->
head
,
&
gpio
->
isr
);
spin_unlock_irqrestore
(
&
gpio
->
lock
,
flags
);
return
0
;
}
static
void
nouveau_gpio_isr_del
(
struct
nouveau_gpio
*
gpio
,
int
idx
,
u8
tag
,
u8
line
,
void
(
*
handler
)(
void
*
,
int
),
void
*
data
)
void
_nouveau_gpio_dtor
(
struct
nouveau_object
*
object
)
{
struct
gpio_isr
*
isr
,
*
tmp
;
struct
dcb_gpio_func
func
;
unsigned
long
flags
;
LIST_HEAD
(
tofree
);
int
ret
;
ret
=
nouveau_gpio_find
(
gpio
,
idx
,
tag
,
line
,
&
func
);
if
(
ret
==
0
)
{
spin_lock_irqsave
(
&
gpio
->
lock
,
flags
);
list_for_each_entry_safe
(
isr
,
tmp
,
&
gpio
->
isr
,
head
)
{
if
(
memcmp
(
&
isr
->
func
,
&
func
,
sizeof
(
func
))
||
isr
->
idx
!=
idx
||
isr
->
handler
!=
handler
||
isr
->
data
!=
data
)
continue
;
list_move_tail
(
&
isr
->
head
,
&
tofree
);
}
spin_unlock_irqrestore
(
&
gpio
->
lock
,
flags
);
list_for_each_entry_safe
(
isr
,
tmp
,
&
tofree
,
head
)
{
flush_work
(
&
isr
->
work
);
kfree
(
isr
);
}
}
struct
nouveau_gpio
*
gpio
=
(
void
*
)
object
;
nouveau_event_destroy
(
&
gpio
->
events
);
nouveau_subdev_destroy
(
&
gpio
->
base
);
}
int
...
...
@@ -242,15 +125,13 @@ nouveau_gpio_create_(struct nouveau_object *parent,
if
(
ret
)
return
ret
;
ret
=
nouveau_event_create
(
lines
,
&
gpio
->
events
);
if
(
ret
)
return
ret
;
gpio
->
find
=
nouveau_gpio_find
;
gpio
->
set
=
nouveau_gpio_set
;
gpio
->
get
=
nouveau_gpio_get
;
gpio
->
irq
=
nouveau_gpio_irq
;
gpio
->
isr_run
=
nouveau_gpio_isr_run
;
gpio
->
isr_add
=
nouveau_gpio_isr_add
;
gpio
->
isr_del
=
nouveau_gpio_isr_del
;
INIT_LIST_HEAD
(
&
gpio
->
isr
);
spin_lock_init
(
&
gpio
->
lock
);
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c
浏览文件 @
4f47643d
...
...
@@ -82,15 +82,6 @@ nv10_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
return
0
;
}
static
void
nv10_gpio_irq_enable
(
struct
nouveau_gpio
*
gpio
,
int
line
,
bool
on
)
{
u32
mask
=
0x00010001
<<
line
;
nv_wr32
(
gpio
,
0x001104
,
mask
);
nv_mask
(
gpio
,
0x001144
,
mask
,
on
?
mask
:
0
);
}
static
void
nv10_gpio_intr
(
struct
nouveau_subdev
*
subdev
)
{
...
...
@@ -98,12 +89,30 @@ nv10_gpio_intr(struct nouveau_subdev *subdev)
u32
intr
=
nv_rd32
(
priv
,
0x001104
);
u32
hi
=
(
intr
&
0x0000ffff
)
>>
0
;
u32
lo
=
(
intr
&
0xffff0000
)
>>
16
;
int
i
;
priv
->
base
.
isr_run
(
&
priv
->
base
,
0
,
hi
|
lo
);
for
(
i
=
0
;
(
hi
|
lo
)
&&
i
<
32
;
i
++
)
{
if
((
hi
|
lo
)
&
(
1
<<
i
))
nouveau_event_trigger
(
priv
->
base
.
events
,
i
);
}
nv_wr32
(
priv
,
0x001104
,
intr
);
}
static
void
nv10_gpio_intr_enable
(
struct
nouveau_event
*
event
,
int
line
)
{
nv_wr32
(
event
->
priv
,
0x001104
,
0x00010001
<<
line
);
nv_mask
(
event
->
priv
,
0x001144
,
0x00010001
<<
line
,
0x00010001
<<
line
);
}
static
void
nv10_gpio_intr_disable
(
struct
nouveau_event
*
event
,
int
line
)
{
nv_wr32
(
event
->
priv
,
0x001104
,
0x00010001
<<
line
);
nv_mask
(
event
->
priv
,
0x001144
,
0x00010001
<<
line
,
0x00000000
);
}
static
int
nv10_gpio_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -119,7 +128,9 @@ nv10_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
base
.
drive
=
nv10_gpio_drive
;
priv
->
base
.
sense
=
nv10_gpio_sense
;
priv
->
base
.
irq_enable
=
nv10_gpio_irq_enable
;
priv
->
base
.
events
->
priv
=
priv
;
priv
->
base
.
events
->
enable
=
nv10_gpio_intr_enable
;
priv
->
base
.
events
->
disable
=
nv10_gpio_intr_disable
;
nv_subdev
(
priv
)
->
intr
=
nv10_gpio_intr
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
浏览文件 @
4f47643d
...
...
@@ -94,22 +94,13 @@ nv50_gpio_sense(struct nouveau_gpio *gpio, int line)
return
!!
(
nv_rd32
(
gpio
,
reg
)
&
(
4
<<
shift
));
}
void
nv50_gpio_irq_enable
(
struct
nouveau_gpio
*
gpio
,
int
line
,
bool
on
)
{
u32
reg
=
line
<
16
?
0xe050
:
0xe070
;
u32
mask
=
0x00010001
<<
(
line
&
0xf
);
nv_wr32
(
gpio
,
reg
+
4
,
mask
);
nv_mask
(
gpio
,
reg
+
0
,
mask
,
on
?
mask
:
0
);
}
void
nv50_gpio_intr
(
struct
nouveau_subdev
*
subdev
)
{
struct
nv50_gpio_priv
*
priv
=
(
void
*
)
subdev
;
u32
intr0
,
intr1
=
0
;
u32
hi
,
lo
;
int
i
;
intr0
=
nv_rd32
(
priv
,
0xe054
)
&
nv_rd32
(
priv
,
0xe050
);
if
(
nv_device
(
priv
)
->
chipset
>=
0x90
)
...
...
@@ -117,13 +108,35 @@ nv50_gpio_intr(struct nouveau_subdev *subdev)
hi
=
(
intr0
&
0x0000ffff
)
|
(
intr1
<<
16
);
lo
=
(
intr0
>>
16
)
|
(
intr1
&
0xffff0000
);
priv
->
base
.
isr_run
(
&
priv
->
base
,
0
,
hi
|
lo
);
for
(
i
=
0
;
(
hi
|
lo
)
&&
i
<
32
;
i
++
)
{
if
((
hi
|
lo
)
&
(
1
<<
i
))
nouveau_event_trigger
(
priv
->
base
.
events
,
i
);
}
nv_wr32
(
priv
,
0xe054
,
intr0
);
if
(
nv_device
(
priv
)
->
chipset
>=
0x90
)
nv_wr32
(
priv
,
0xe074
,
intr1
);
}
void
nv50_gpio_intr_enable
(
struct
nouveau_event
*
event
,
int
line
)
{
const
u32
addr
=
line
<
16
?
0xe050
:
0xe070
;
const
u32
mask
=
0x00010001
<<
(
line
&
0xf
);
nv_wr32
(
event
->
priv
,
addr
+
0x04
,
mask
);
nv_mask
(
event
->
priv
,
addr
+
0x00
,
mask
,
mask
);
}
void
nv50_gpio_intr_disable
(
struct
nouveau_event
*
event
,
int
line
)
{
const
u32
addr
=
line
<
16
?
0xe050
:
0xe070
;
const
u32
mask
=
0x00010001
<<
(
line
&
0xf
);
nv_wr32
(
event
->
priv
,
addr
+
0x04
,
mask
);
nv_mask
(
event
->
priv
,
addr
+
0x00
,
mask
,
0x00000000
);
}
static
int
nv50_gpio_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -142,7 +155,9 @@ nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
base
.
reset
=
nv50_gpio_reset
;
priv
->
base
.
drive
=
nv50_gpio_drive
;
priv
->
base
.
sense
=
nv50_gpio_sense
;
priv
->
base
.
irq_enable
=
nv50_gpio_irq_enable
;
priv
->
base
.
events
->
priv
=
priv
;
priv
->
base
.
events
->
enable
=
nv50_gpio_intr_enable
;
priv
->
base
.
events
->
disable
=
nv50_gpio_intr_disable
;
nv_subdev
(
priv
)
->
intr
=
nv50_gpio_intr
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
浏览文件 @
4f47643d
...
...
@@ -88,7 +88,9 @@ nvd0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv
->
base
.
reset
=
nvd0_gpio_reset
;
priv
->
base
.
drive
=
nvd0_gpio_drive
;
priv
->
base
.
sense
=
nvd0_gpio_sense
;
priv
->
base
.
irq_enable
=
nv50_gpio_irq_enable
;
priv
->
base
.
events
->
priv
=
priv
;
priv
->
base
.
events
->
enable
=
nv50_gpio_intr_enable
;
priv
->
base
.
events
->
disable
=
nv50_gpio_intr_disable
;
nv_subdev
(
priv
)
->
intr
=
nv50_gpio_intr
;
return
0
;
}
...
...
drivers/gpu/drm/nouveau/nouveau_connector.c
浏览文件 @
4f47643d
...
...
@@ -55,8 +55,6 @@ MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (default: enabled)");
static
int
nouveau_duallink
=
1
;
module_param_named
(
duallink
,
nouveau_duallink
,
int
,
0400
);
static
void
nouveau_connector_hotplug
(
void
*
,
int
);
struct
nouveau_encoder
*
find_encoder
(
struct
drm_connector
*
connector
,
int
type
)
{
...
...
@@ -100,22 +98,6 @@ static void
nouveau_connector_destroy
(
struct
drm_connector
*
connector
)
{
struct
nouveau_connector
*
nv_connector
=
nouveau_connector
(
connector
);
struct
nouveau_gpio
*
gpio
;
struct
nouveau_drm
*
drm
;
struct
drm_device
*
dev
;
if
(
!
nv_connector
)
return
;
dev
=
nv_connector
->
base
.
dev
;
drm
=
nouveau_drm
(
dev
);
gpio
=
nouveau_gpio
(
drm
->
device
);
if
(
gpio
&&
nv_connector
->
hpd
.
func
!=
DCB_GPIO_UNUSED
)
{
gpio
->
isr_del
(
gpio
,
0
,
nv_connector
->
hpd
.
func
,
0xff
,
nouveau_connector_hotplug
,
connector
);
}
kfree
(
nv_connector
->
edid
);
drm_sysfs_connector_remove
(
connector
);
drm_connector_cleanup
(
connector
);
...
...
@@ -912,6 +894,37 @@ nouveau_connector_funcs_lvds = {
.
force
=
nouveau_connector_force
};
static
void
nouveau_connector_hotplug_work
(
struct
work_struct
*
work
)
{
struct
nouveau_connector
*
nv_connector
=
container_of
(
work
,
struct
nouveau_connector
,
hpd_work
);
struct
drm_connector
*
connector
=
&
nv_connector
->
base
;
struct
drm_device
*
dev
=
connector
->
dev
;
struct
nouveau_drm
*
drm
=
nouveau_drm
(
dev
);
struct
nouveau_gpio
*
gpio
=
nouveau_gpio
(
drm
->
device
);
bool
plugged
=
gpio
->
get
(
gpio
,
0
,
nv_connector
->
hpd
.
func
,
0xff
);
NV_DEBUG
(
drm
,
"%splugged %s
\n
"
,
plugged
?
""
:
"un"
,
drm_get_connector_name
(
connector
));
if
(
plugged
)
drm_helper_connector_dpms
(
connector
,
DRM_MODE_DPMS_ON
);
else
drm_helper_connector_dpms
(
connector
,
DRM_MODE_DPMS_OFF
);
drm_helper_hpd_irq_event
(
dev
);
}
static
int
nouveau_connector_hotplug
(
struct
nouveau_eventh
*
event
,
int
index
)
{
struct
nouveau_connector
*
nv_connector
=
container_of
(
event
,
struct
nouveau_connector
,
hpd_func
);
schedule_work
(
&
nv_connector
->
hpd_work
);
return
NVKM_EVENT_KEEP
;
}
static
int
drm_conntype_from_dcb
(
enum
dcb_connector_type
dcb
)
{
...
...
@@ -962,6 +975,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
return
ERR_PTR
(
-
ENOMEM
);
connector
=
&
nv_connector
->
base
;
INIT_WORK
(
&
nv_connector
->
hpd_work
,
nouveau_connector_hotplug_work
);
nv_connector
->
index
=
index
;
/* attempt to parse vbios connector type and hotplug gpio */
...
...
@@ -978,6 +992,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
ret
=
gpio
->
find
(
gpio
,
0
,
hpd
[
ffs
((
entry
&
0x07033000
)
>>
12
)],
DCB_GPIO_UNUSED
,
&
nv_connector
->
hpd
);
nv_connector
->
hpd_func
.
func
=
nouveau_connector_hotplug
;
if
(
ret
)
nv_connector
->
hpd
.
func
=
DCB_GPIO_UNUSED
;
...
...
@@ -1129,31 +1144,9 @@ nouveau_connector_create(struct drm_device *dev, int index)
}
connector
->
polled
=
DRM_CONNECTOR_POLL_CONNECT
;
if
(
gpio
&&
nv_connector
->
hpd
.
func
!=
DCB_GPIO_UNUSED
)
{
ret
=
gpio
->
isr_add
(
gpio
,
0
,
nv_connector
->
hpd
.
func
,
0xff
,
nouveau_connector_hotplug
,
connector
);
if
(
ret
==
0
)
connector
->
polled
=
DRM_CONNECTOR_POLL_HPD
;
}
if
(
nv_connector
->
hpd
.
func
!=
DCB_GPIO_UNUSED
)
connector
->
polled
=
DRM_CONNECTOR_POLL_HPD
;
drm_sysfs_connector_add
(
connector
);
return
connector
;
}
static
void
nouveau_connector_hotplug
(
void
*
data
,
int
plugged
)
{
struct
drm_connector
*
connector
=
data
;
struct
drm_device
*
dev
=
connector
->
dev
;
struct
nouveau_drm
*
drm
=
nouveau_drm
(
dev
);
NV_DEBUG
(
drm
,
"%splugged %s
\n
"
,
plugged
?
""
:
"un"
,
drm_get_connector_name
(
connector
));
if
(
plugged
)
drm_helper_connector_dpms
(
connector
,
DRM_MODE_DPMS_ON
);
else
drm_helper_connector_dpms
(
connector
,
DRM_MODE_DPMS_OFF
);
drm_helper_hpd_irq_event
(
dev
);
}
drivers/gpu/drm/nouveau/nouveau_connector.h
浏览文件 @
4f47643d
...
...
@@ -30,6 +30,8 @@
#include <drm/drm_edid.h>
#include "nouveau_crtc.h"
#include <core/event.h>
#include <subdev/bios.h>
#include <subdev/bios/gpio.h>
...
...
@@ -62,10 +64,13 @@ enum nouveau_dithering_depth {
struct
nouveau_connector
{
struct
drm_connector
base
;
enum
dcb_connector_type
type
;
struct
dcb_gpio_func
hpd
;
u8
index
;
u8
*
dcb
;
struct
dcb_gpio_func
hpd
;
struct
work_struct
hpd_work
;
struct
nouveau_eventh
hpd_func
;
int
dithering_mode
;
int
dithering_depth
;
int
scaling_mode
;
...
...
drivers/gpu/drm/nouveau/nouveau_display.c
浏览文件 @
4f47643d
...
...
@@ -233,8 +233,10 @@ nouveau_display_init(struct drm_device *dev)
/* enable hotplug interrupts */
list_for_each_entry
(
connector
,
&
dev
->
mode_config
.
connector_list
,
head
)
{
struct
nouveau_connector
*
conn
=
nouveau_connector
(
connector
);
if
(
gpio
)
gpio
->
irq
(
gpio
,
0
,
conn
->
hpd
.
func
,
0xff
,
true
);
if
(
gpio
&&
conn
->
hpd
.
func
!=
DCB_GPIO_UNUSED
)
{
nouveau_event_get
(
gpio
->
events
,
conn
->
hpd
.
line
,
&
conn
->
hpd_func
);
}
}
return
ret
;
...
...
@@ -251,8 +253,10 @@ nouveau_display_fini(struct drm_device *dev)
/* disable hotplug interrupts */
list_for_each_entry
(
connector
,
&
dev
->
mode_config
.
connector_list
,
head
)
{
struct
nouveau_connector
*
conn
=
nouveau_connector
(
connector
);
if
(
gpio
)
gpio
->
irq
(
gpio
,
0
,
conn
->
hpd
.
func
,
0xff
,
false
);
if
(
gpio
&&
conn
->
hpd
.
func
!=
DCB_GPIO_UNUSED
)
{
nouveau_event_put
(
gpio
->
events
,
conn
->
hpd
.
line
,
&
conn
->
hpd_func
);
}
}
drm_kms_helper_poll_disable
(
dev
);
...
...
drivers/gpu/drm/nouveau/nouveau_dp.c
浏览文件 @
4f47643d
...
...
@@ -260,7 +260,8 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
* we take during link training (DP_SET_POWER is one), we need
* to ignore them for the moment to avoid races.
*/
gpio
->
irq
(
gpio
,
0
,
nv_connector
->
hpd
.
func
,
0xff
,
false
);
nouveau_event_put
(
gpio
->
events
,
nv_connector
->
hpd
.
line
,
&
nv_connector
->
hpd_func
);
/* enable down-spreading and execute pre-train script from vbios */
dp_link_train_init
(
dev
,
&
dp
,
nv_encoder
->
dp
.
dpcd
[
3
]
&
1
);
...
...
@@ -300,7 +301,8 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
dp_link_train_fini
(
dev
,
&
dp
);
/* re-enable hotplug detect */
gpio
->
irq
(
gpio
,
0
,
nv_connector
->
hpd
.
func
,
0xff
,
true
);
nouveau_event_get
(
gpio
->
events
,
nv_connector
->
hpd
.
line
,
&
nv_connector
->
hpd_func
);
return
true
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录