Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
43720133
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
43720133
编写于
7月 20, 2011
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nouveau/dp: rewrite auxch transaction routines
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
91a8f1ea
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
132 addition
and
105 deletion
+132
-105
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_dp.c
+131
-105
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_drv.h
+1
-0
未找到文件。
drivers/gpu/drm/nouveau/nouveau_dp.c
浏览文件 @
43720133
...
...
@@ -29,6 +29,136 @@
#include "nouveau_connector.h"
#include "nouveau_encoder.h"
/******************************************************************************
* aux channel util functions
*****************************************************************************/
#define AUX_DBG(fmt, args...) do { \
if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_AUXCH) { \
NV_PRINTK(KERN_DEBUG, dev, "AUXCH(%d): " fmt, ch, ##args); \
} \
} while (0)
#define AUX_ERR(fmt, args...) NV_ERROR(dev, "AUXCH(%d): " fmt, ch, ##args)
static
void
auxch_fini
(
struct
drm_device
*
dev
,
int
ch
)
{
nv_mask
(
dev
,
0x00e4e4
+
(
ch
*
0x50
),
0x00310000
,
0x00000000
);
}
static
int
auxch_init
(
struct
drm_device
*
dev
,
int
ch
)
{
const
u32
unksel
=
1
;
/* nfi which to use, or if it matters.. */
const
u32
ureq
=
unksel
?
0x00100000
:
0x00200000
;
const
u32
urep
=
unksel
?
0x01000000
:
0x02000000
;
u32
ctrl
,
timeout
;
/* wait up to 1ms for any previous transaction to be done... */
timeout
=
1000
;
do
{
ctrl
=
nv_rd32
(
dev
,
0x00e4e4
+
(
ch
*
0x50
));
udelay
(
1
);
if
(
!
timeout
--
)
{
AUX_ERR
(
"begin idle timeout 0x%08x"
,
ctrl
);
return
-
EBUSY
;
}
}
while
(
ctrl
&
0x03010000
);
/* set some magic, and wait up to 1ms for it to appear */
nv_mask
(
dev
,
0x00e4e4
+
(
ch
*
0x50
),
0x00300000
,
ureq
);
timeout
=
1000
;
do
{
ctrl
=
nv_rd32
(
dev
,
0x00e4e4
+
(
ch
*
0x50
));
udelay
(
1
);
if
(
!
timeout
--
)
{
AUX_ERR
(
"magic wait 0x%08x
\n
"
,
ctrl
);
auxch_fini
(
dev
,
ch
);
return
-
EBUSY
;
}
}
while
((
ctrl
&
0x03000000
)
!=
urep
);
return
0
;
}
static
int
auxch_tx
(
struct
drm_device
*
dev
,
int
ch
,
u8
type
,
u32
addr
,
u8
*
data
,
u8
size
)
{
u32
ctrl
,
stat
,
timeout
,
retries
;
u32
xbuf
[
4
]
=
{};
int
ret
,
i
;
AUX_DBG
(
"%d: 0x%08x %d
\n
"
,
type
,
addr
,
size
);
ret
=
auxch_init
(
dev
,
ch
);
if
(
ret
)
goto
out
;
stat
=
nv_rd32
(
dev
,
0x00e4e8
+
(
ch
*
0x50
));
if
(
!
(
stat
&
0x10000000
))
{
AUX_DBG
(
"sink not detected
\n
"
);
ret
=
-
ENXIO
;
goto
out
;
}
if
(
!
(
type
&
1
))
{
memcpy
(
xbuf
,
data
,
size
);
for
(
i
=
0
;
i
<
16
;
i
+=
4
)
{
AUX_DBG
(
"wr 0x%08x
\n
"
,
xbuf
[
i
/
4
]);
nv_wr32
(
dev
,
0x00e4c0
+
(
ch
*
0x50
)
+
i
,
xbuf
[
i
/
4
]);
}
}
ctrl
=
nv_rd32
(
dev
,
0x00e4e4
+
(
ch
*
0x50
));
ctrl
&=
~
0x0001f0ff
;
ctrl
|=
type
<<
12
;
ctrl
|=
size
-
1
;
nv_wr32
(
dev
,
0x00e4e0
+
(
ch
*
0x50
),
addr
);
/* retry transaction a number of times on failure... */
ret
=
-
EREMOTEIO
;
for
(
retries
=
0
;
retries
<
32
;
retries
++
)
{
/* reset, and delay a while if this is a retry */
nv_wr32
(
dev
,
0x00e4e4
+
(
ch
*
0x50
),
0x80000000
|
ctrl
);
nv_wr32
(
dev
,
0x00e4e4
+
(
ch
*
0x50
),
0x00000000
|
ctrl
);
if
(
retries
)
udelay
(
400
);
/* transaction request, wait up to 1ms for it to complete */
nv_wr32
(
dev
,
0x00e4e4
+
(
ch
*
0x50
),
0x00010000
|
ctrl
);
timeout
=
1000
;
do
{
ctrl
=
nv_rd32
(
dev
,
0x00e4e4
+
(
ch
*
0x50
));
udelay
(
1
);
if
(
!
timeout
--
)
{
AUX_ERR
(
"tx req timeout 0x%08x
\n
"
,
ctrl
);
goto
out
;
}
}
while
(
ctrl
&
0x00010000
);
/* read status, and check if transaction completed ok */
stat
=
nv_mask
(
dev
,
0x00e4e8
+
(
ch
*
0x50
),
0
,
0
);
if
(
!
(
stat
&
0x000f0f00
))
{
ret
=
0
;
break
;
}
AUX_DBG
(
"%02d 0x%08x 0x%08x
\n
"
,
retries
,
ctrl
,
stat
);
}
if
(
type
&
1
)
{
for
(
i
=
0
;
i
<
16
;
i
+=
4
)
{
xbuf
[
i
/
4
]
=
nv_rd32
(
dev
,
0x00e4d0
+
(
ch
*
0x50
)
+
i
);
AUX_DBG
(
"rd 0x%08x
\n
"
,
xbuf
[
i
/
4
]);
}
memcpy
(
data
,
xbuf
,
size
);
}
out:
auxch_fini
(
dev
,
ch
);
return
ret
;
}
static
int
auxch_rd
(
struct
drm_encoder
*
encoder
,
int
address
,
uint8_t
*
buf
,
int
size
)
{
...
...
@@ -480,98 +610,7 @@ int
nouveau_dp_auxch
(
struct
nouveau_i2c_chan
*
auxch
,
int
cmd
,
int
addr
,
uint8_t
*
data
,
int
data_nr
)
{
struct
drm_device
*
dev
=
auxch
->
dev
;
uint32_t
tmp
,
ctrl
,
stat
=
0
,
data32
[
4
]
=
{};
int
ret
=
0
,
i
,
index
=
auxch
->
rd
;
NV_DEBUG_KMS
(
dev
,
"ch %d cmd %d addr 0x%x len %d
\n
"
,
index
,
cmd
,
addr
,
data_nr
);
tmp
=
nv_rd32
(
dev
,
NV50_AUXCH_CTRL
(
auxch
->
rd
));
nv_wr32
(
dev
,
NV50_AUXCH_CTRL
(
auxch
->
rd
),
tmp
|
0x00100000
);
tmp
=
nv_rd32
(
dev
,
NV50_AUXCH_CTRL
(
auxch
->
rd
));
if
(
!
(
tmp
&
0x01000000
))
{
NV_ERROR
(
dev
,
"expected bit 24 == 1, got 0x%08x
\n
"
,
tmp
);
ret
=
-
EIO
;
goto
out
;
}
for
(
i
=
0
;
i
<
3
;
i
++
)
{
tmp
=
nv_rd32
(
dev
,
NV50_AUXCH_STAT
(
auxch
->
rd
));
if
(
tmp
&
NV50_AUXCH_STAT_STATE_READY
)
break
;
udelay
(
100
);
}
if
(
i
==
3
)
{
ret
=
-
EBUSY
;
goto
out
;
}
if
(
!
(
cmd
&
1
))
{
memcpy
(
data32
,
data
,
data_nr
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
NV_DEBUG_KMS
(
dev
,
"wr %d: 0x%08x
\n
"
,
i
,
data32
[
i
]);
nv_wr32
(
dev
,
NV50_AUXCH_DATA_OUT
(
index
,
i
),
data32
[
i
]);
}
}
nv_wr32
(
dev
,
NV50_AUXCH_ADDR
(
index
),
addr
);
ctrl
=
nv_rd32
(
dev
,
NV50_AUXCH_CTRL
(
index
));
ctrl
&=
~
(
NV50_AUXCH_CTRL_CMD
|
NV50_AUXCH_CTRL_LEN
);
ctrl
|=
(
cmd
<<
NV50_AUXCH_CTRL_CMD_SHIFT
);
ctrl
|=
((
data_nr
-
1
)
<<
NV50_AUXCH_CTRL_LEN_SHIFT
);
for
(
i
=
0
;
i
<
16
;
i
++
)
{
nv_wr32
(
dev
,
NV50_AUXCH_CTRL
(
index
),
ctrl
|
0x80000000
);
nv_wr32
(
dev
,
NV50_AUXCH_CTRL
(
index
),
ctrl
);
nv_wr32
(
dev
,
NV50_AUXCH_CTRL
(
index
),
ctrl
|
0x00010000
);
if
(
!
nv_wait
(
dev
,
NV50_AUXCH_CTRL
(
index
),
0x00010000
,
0x00000000
))
{
NV_ERROR
(
dev
,
"expected bit 16 == 0, got 0x%08x
\n
"
,
nv_rd32
(
dev
,
NV50_AUXCH_CTRL
(
index
)));
ret
=
-
EBUSY
;
goto
out
;
}
udelay
(
400
);
stat
=
nv_rd32
(
dev
,
NV50_AUXCH_STAT
(
index
));
if
((
stat
&
NV50_AUXCH_STAT_REPLY_AUX
)
!=
NV50_AUXCH_STAT_REPLY_AUX_DEFER
)
break
;
}
if
(
i
==
16
)
{
NV_ERROR
(
dev
,
"auxch DEFER too many times, bailing
\n
"
);
ret
=
-
EREMOTEIO
;
goto
out
;
}
if
(
cmd
&
1
)
{
if
((
stat
&
NV50_AUXCH_STAT_COUNT
)
!=
data_nr
)
{
ret
=
-
EREMOTEIO
;
goto
out
;
}
for
(
i
=
0
;
i
<
4
;
i
++
)
{
data32
[
i
]
=
nv_rd32
(
dev
,
NV50_AUXCH_DATA_IN
(
index
,
i
));
NV_DEBUG_KMS
(
dev
,
"rd %d: 0x%08x
\n
"
,
i
,
data32
[
i
]);
}
memcpy
(
data
,
data32
,
data_nr
);
}
out:
tmp
=
nv_rd32
(
dev
,
NV50_AUXCH_CTRL
(
auxch
->
rd
));
nv_wr32
(
dev
,
NV50_AUXCH_CTRL
(
auxch
->
rd
),
tmp
&
~
0x00100000
);
tmp
=
nv_rd32
(
dev
,
NV50_AUXCH_CTRL
(
auxch
->
rd
));
if
(
tmp
&
0x01000000
)
{
NV_ERROR
(
dev
,
"expected bit 24 == 0, got 0x%08x
\n
"
,
tmp
);
ret
=
-
EIO
;
}
udelay
(
400
);
return
ret
?
ret
:
(
stat
&
NV50_AUXCH_STAT_REPLY
);
return
auxch_tx
(
auxch
->
dev
,
auxch
->
rd
,
cmd
,
addr
,
data
,
data_nr
);
}
static
int
...
...
@@ -602,19 +641,6 @@ nouveau_dp_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
if
(
ret
<
0
)
return
ret
;
switch
(
ret
&
NV50_AUXCH_STAT_REPLY_I2C
)
{
case
NV50_AUXCH_STAT_REPLY_I2C_ACK
:
break
;
case
NV50_AUXCH_STAT_REPLY_I2C_NACK
:
return
-
EREMOTEIO
;
case
NV50_AUXCH_STAT_REPLY_I2C_DEFER
:
udelay
(
100
);
continue
;
default:
NV_ERROR
(
dev
,
"bad auxch reply: 0x%08x
\n
"
,
ret
);
return
-
EREMOTEIO
;
}
ptr
+=
cnt
;
remaining
-=
cnt
;
}
...
...
drivers/gpu/drm/nouveau/nouveau_drv.h
浏览文件 @
43720133
...
...
@@ -1570,6 +1570,7 @@ enum {
NOUVEAU_REG_DEBUG_RMVIO
=
0x80
,
NOUVEAU_REG_DEBUG_VGAATTR
=
0x100
,
NOUVEAU_REG_DEBUG_EVO
=
0x200
,
NOUVEAU_REG_DEBUG_AUXCH
=
0x400
};
#define NV_REG_DEBUG(type, dev, fmt, arg...) do { \
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录