Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
d17f395c
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看板
提交
d17f395c
编写于
6月 01, 2010
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nouveau: move LVDS detection back to connector detect() time
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
2dfe36b1
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
87 addition
and
115 deletion
+87
-115
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_connector.c
+87
-115
未找到文件。
drivers/gpu/drm/nouveau/nouveau_connector.c
浏览文件 @
d17f395c
...
...
@@ -236,20 +236,6 @@ nouveau_connector_detect(struct drm_connector *connector)
struct
nouveau_i2c_chan
*
i2c
;
int
type
,
flags
;
if
(
nv_connector
->
dcb
->
type
==
DCB_CONNECTOR_LVDS
)
nv_encoder
=
find_encoder_by_type
(
connector
,
OUTPUT_LVDS
);
if
(
nv_encoder
&&
nv_connector
->
native_mode
)
{
unsigned
status
=
connector_status_connected
;
#if defined(CONFIG_ACPI_BUTTON) || \
(defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
if
(
!
nouveau_ignorelid
&&
!
acpi_lid_open
())
status
=
connector_status_unknown
;
#endif
nouveau_connector_set_encoder
(
connector
,
nv_encoder
);
return
status
;
}
/* Cleanup the previous EDID block. */
if
(
nv_connector
->
edid
)
{
drm_mode_connector_update_edid_property
(
connector
,
NULL
);
...
...
@@ -321,6 +307,67 @@ nouveau_connector_detect(struct drm_connector *connector)
return
connector_status_disconnected
;
}
static
enum
drm_connector_status
nouveau_connector_detect_lvds
(
struct
drm_connector
*
connector
)
{
struct
drm_device
*
dev
=
connector
->
dev
;
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nouveau_connector
*
nv_connector
=
nouveau_connector
(
connector
);
struct
nouveau_encoder
*
nv_encoder
=
NULL
;
enum
drm_connector_status
status
=
connector_status_disconnected
;
/* Cleanup the previous EDID block. */
if
(
nv_connector
->
edid
)
{
drm_mode_connector_update_edid_property
(
connector
,
NULL
);
kfree
(
nv_connector
->
edid
);
nv_connector
->
edid
=
NULL
;
}
nv_encoder
=
find_encoder_by_type
(
connector
,
OUTPUT_LVDS
);
if
(
!
nv_encoder
)
return
connector_status_disconnected
;
if
(
!
dev_priv
->
vbios
.
fp_no_ddc
)
{
status
=
nouveau_connector_detect
(
connector
);
if
(
status
==
connector_status_connected
)
goto
out
;
}
/* If no EDID found above, and the VBIOS indicates a hardcoded
* modeline is avalilable for the panel, set it as the panel's
* native mode and exit.
*/
if
(
nouveau_bios_fp_mode
(
dev
,
NULL
)
&&
(
dev_priv
->
vbios
.
fp_no_ddc
||
nv_encoder
->
dcb
->
lvdsconf
.
use_straps_for_mode
))
{
status
=
connector_status_connected
;
goto
out
;
}
/* Still nothing, some VBIOS images have a hardcoded EDID block
* stored for the panel stored in them.
*/
if
(
!
dev_priv
->
vbios
.
fp_no_ddc
)
{
struct
edid
*
edid
=
(
struct
edid
*
)
nouveau_bios_embedded_edid
(
dev
);
if
(
edid
)
{
nv_connector
->
edid
=
kmalloc
(
EDID_LENGTH
,
GFP_KERNEL
);
*
(
nv_connector
->
edid
)
=
*
edid
;
status
=
connector_status_connected
;
}
}
out:
#if defined(CONFIG_ACPI_BUTTON) || \
(defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
if
(
status
==
connector_status_connected
&&
!
nouveau_ignorelid
&&
!
acpi_lid_open
())
status
=
connector_status_unknown
;
#endif
drm_mode_connector_update_edid_property
(
connector
,
nv_connector
->
edid
);
return
status
;
}
static
void
nouveau_connector_force
(
struct
drm_connector
*
connector
)
{
...
...
@@ -534,21 +581,28 @@ static int
nouveau_connector_get_modes
(
struct
drm_connector
*
connector
)
{
struct
drm_device
*
dev
=
connector
->
dev
;
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nouveau_connector
*
nv_connector
=
nouveau_connector
(
connector
);
struct
nouveau_encoder
*
nv_encoder
=
nv_connector
->
detected_encoder
;
struct
drm_display_mode
mode
;
int
ret
=
0
;
/* If we're not LVDS, destroy the previous native mode, the attached
* monitor could have changed.
/* destroy the native mode, the attached monitor could have changed.
*/
if
(
nv_connector
->
dcb
->
type
!=
DCB_CONNECTOR_LVDS
&&
nv_connector
->
native_mode
)
{
if
(
nv_connector
->
native_mode
)
{
drm_mode_destroy
(
dev
,
nv_connector
->
native_mode
);
nv_connector
->
native_mode
=
NULL
;
}
if
(
nv_connector
->
edid
)
ret
=
drm_add_edid_modes
(
connector
,
nv_connector
->
edid
);
else
if
(
nv_encoder
->
dcb
->
type
==
OUTPUT_LVDS
&&
(
nv_encoder
->
dcb
->
lvdsconf
.
use_straps_for_mode
||
dev_priv
->
vbios
.
fp_no_ddc
)
&&
nouveau_bios_fp_mode
(
dev
,
&
mode
))
{
nv_connector
->
native_mode
=
drm_mode_duplicate
(
dev
,
&
mode
);
}
/* Find the native mode if this is a digital panel, if we didn't
* find any modes through DDC previously add the native mode to
...
...
@@ -662,99 +716,28 @@ nouveau_connector_funcs = {
.
force
=
nouveau_connector_force
};
static
int
nouveau_connector_create_lvds
(
struct
drm_device
*
dev
,
struct
drm_connector
*
connector
)
{
struct
nouveau_connector
*
nv_connector
=
nouveau_connector
(
connector
);
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nouveau_i2c_chan
*
i2c
=
NULL
;
struct
nouveau_encoder
*
nv_encoder
;
struct
drm_display_mode
native
,
*
mode
,
*
temp
;
bool
dummy
,
if_is_24bit
=
false
;
int
ret
,
flags
;
nv_encoder
=
find_encoder_by_type
(
connector
,
OUTPUT_LVDS
);
if
(
!
nv_encoder
)
return
-
ENODEV
;
ret
=
nouveau_bios_parse_lvds_table
(
dev
,
0
,
&
dummy
,
&
if_is_24bit
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Error parsing LVDS table, disabling LVDS
\n
"
);
return
ret
;
}
nv_connector
->
use_dithering
=
!
if_is_24bit
;
/* Firstly try getting EDID over DDC, if allowed and I2C channel
* is available.
*/
if
(
!
dev_priv
->
vbios
.
fp_no_ddc
&&
nv_encoder
->
dcb
->
i2c_index
<
0xf
)
i2c
=
nouveau_i2c_find
(
dev
,
nv_encoder
->
dcb
->
i2c_index
);
if
(
i2c
)
{
nouveau_connector_ddc_prepare
(
connector
,
&
flags
);
nv_connector
->
edid
=
drm_get_edid
(
connector
,
&
i2c
->
adapter
);
nouveau_connector_ddc_finish
(
connector
,
flags
);
}
/* If no EDID found above, and the VBIOS indicates a hardcoded
* modeline is avalilable for the panel, set it as the panel's
* native mode and exit.
*/
if
(
!
nv_connector
->
edid
&&
nouveau_bios_fp_mode
(
dev
,
&
native
)
&&
(
nv_encoder
->
dcb
->
lvdsconf
.
use_straps_for_mode
||
dev_priv
->
vbios
.
fp_no_ddc
))
{
nv_connector
->
native_mode
=
drm_mode_duplicate
(
dev
,
&
native
);
goto
out
;
}
/* Still nothing, some VBIOS images have a hardcoded EDID block
* stored for the panel stored in them.
*/
if
(
!
nv_connector
->
edid
&&
!
nv_connector
->
native_mode
&&
!
dev_priv
->
vbios
.
fp_no_ddc
)
{
struct
edid
*
edid
=
(
struct
edid
*
)
nouveau_bios_embedded_edid
(
dev
);
if
(
edid
)
{
nv_connector
->
edid
=
kmalloc
(
EDID_LENGTH
,
GFP_KERNEL
);
*
(
nv_connector
->
edid
)
=
*
edid
;
}
}
if
(
!
nv_connector
->
edid
)
goto
out
;
/* We didn't find/use a panel mode from the VBIOS, so parse the EDID
* block and look for the preferred mode there.
*/
ret
=
drm_add_edid_modes
(
connector
,
nv_connector
->
edid
);
if
(
ret
==
0
)
goto
out
;
nv_connector
->
detected_encoder
=
nv_encoder
;
nv_connector
->
native_mode
=
nouveau_connector_native_mode
(
connector
);
list_for_each_entry_safe
(
mode
,
temp
,
&
connector
->
probed_modes
,
head
)
drm_mode_remove
(
connector
,
mode
);
out:
if
(
!
nv_connector
->
native_mode
)
{
NV_ERROR
(
dev
,
"LVDS present in DCB table, but couldn't "
"determine its native mode. Disabling.
\n
"
);
return
-
ENODEV
;
}
drm_mode_connector_update_edid_property
(
connector
,
nv_connector
->
edid
);
return
0
;
}
static
const
struct
drm_connector_funcs
nouveau_connector_funcs_lvds
=
{
.
dpms
=
drm_helper_connector_dpms
,
.
save
=
NULL
,
.
restore
=
NULL
,
.
detect
=
nouveau_connector_detect_lvds
,
.
destroy
=
nouveau_connector_destroy
,
.
fill_modes
=
drm_helper_probe_single_connector_modes
,
.
set_property
=
nouveau_connector_set_property
,
.
force
=
nouveau_connector_force
};
int
nouveau_connector_create
(
struct
drm_device
*
dev
,
struct
dcb_connector_table_entry
*
dcb
)
{
const
struct
drm_connector_funcs
*
funcs
=
&
nouveau_connector_funcs
;
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nouveau_connector
*
nv_connector
=
NULL
;
struct
drm_connector
*
connector
;
struct
drm_encoder
*
encoder
;
int
ret
,
type
;
int
type
;
NV_DEBUG_KMS
(
dev
,
"
\n
"
);
...
...
@@ -787,6 +770,7 @@ nouveau_connector_create(struct drm_device *dev,
case
DCB_CONNECTOR_LVDS
:
NV_INFO
(
dev
,
"Detected a LVDS connector
\n
"
);
type
=
DRM_MODE_CONNECTOR_LVDS
;
funcs
=
&
nouveau_connector_funcs_lvds
;
break
;
case
DCB_CONNECTOR_DP
:
NV_INFO
(
dev
,
"Detected a DisplayPort connector
\n
"
);
...
...
@@ -811,7 +795,7 @@ nouveau_connector_create(struct drm_device *dev,
connector
->
interlace_allowed
=
false
;
connector
->
doublescan_allowed
=
false
;
drm_connector_init
(
dev
,
connector
,
&
nouveau_connector_
funcs
,
type
);
drm_connector_init
(
dev
,
connector
,
funcs
,
type
);
drm_connector_helper_add
(
connector
,
&
nouveau_connector_helper_funcs
);
/* attach encoders */
...
...
@@ -841,9 +825,6 @@ nouveau_connector_create(struct drm_device *dev,
drm_connector_attach_property
(
connector
,
dev
->
mode_config
.
dvi_i_select_subconnector_property
,
0
);
}
if
(
dcb
->
type
!=
DCB_CONNECTOR_LVDS
)
nv_connector
->
use_dithering
=
false
;
switch
(
dcb
->
type
)
{
case
DCB_CONNECTOR_VGA
:
connector
->
polled
=
DRM_CONNECTOR_POLL_CONNECT
;
...
...
@@ -883,14 +864,5 @@ nouveau_connector_create(struct drm_device *dev,
}
drm_sysfs_connector_add
(
connector
);
if
(
dcb
->
type
==
DCB_CONNECTOR_LVDS
)
{
ret
=
nouveau_connector_create_lvds
(
dev
,
connector
);
if
(
ret
)
{
connector
->
funcs
->
destroy
(
connector
);
return
ret
;
}
}
return
0
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录