Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
c9083577
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
c9083577
编写于
8月 19, 2014
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/gm204/i2c: add aux channel driver
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
f105aa37
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
233 addition
and
3 deletion
+233
-3
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/Makefile
+1
-0
drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
+1
-0
drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c
drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c
+221
-0
drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h
drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h
+4
-0
drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c
drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c
+1
-1
drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c
drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c
+2
-2
drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h
drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h
+3
-0
未找到文件。
drivers/gpu/drm/nouveau/Makefile
浏览文件 @
c9083577
...
...
@@ -166,6 +166,7 @@ nouveau-y += core/subdev/i2c/nv94.o
nouveau-y
+=
core/subdev/i2c/nvd0.o
nouveau-y
+=
core/subdev/i2c/gf117.o
nouveau-y
+=
core/subdev/i2c/nve0.o
nouveau-y
+=
core/subdev/i2c/gm204.o
nouveau-y
+=
core/subdev/ibus/nvc0.o
nouveau-y
+=
core/subdev/ibus/nve0.o
nouveau-y
+=
core/subdev/ibus/gk20a.o
...
...
drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
浏览文件 @
c9083577
...
...
@@ -91,6 +91,7 @@ extern struct nouveau_oclass *nv94_i2c_oclass;
extern
struct
nouveau_oclass
*
nvd0_i2c_oclass
;
extern
struct
nouveau_oclass
*
gf117_i2c_oclass
;
extern
struct
nouveau_oclass
*
nve0_i2c_oclass
;
extern
struct
nouveau_oclass
*
gm204_i2c_oclass
;
static
inline
int
nv_rdi2cr
(
struct
nouveau_i2c_port
*
port
,
u8
addr
,
u8
reg
)
...
...
drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c
0 → 100644
浏览文件 @
c9083577
/*
* Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include "nv50.h"
#define AUX_DBG(fmt, args...) nv_debug(aux, "AUXCH(%d): " fmt, ch, ##args)
#define AUX_ERR(fmt, args...) nv_error(aux, "AUXCH(%d): " fmt, ch, ##args)
static
void
auxch_fini
(
struct
nouveau_i2c
*
aux
,
int
ch
)
{
nv_mask
(
aux
,
0x00d954
+
(
ch
*
0x50
),
0x00310000
,
0x00000000
);
}
static
int
auxch_init
(
struct
nouveau_i2c
*
aux
,
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
(
aux
,
0x00d954
+
(
ch
*
0x50
));
udelay
(
1
);
if
(
!
timeout
--
)
{
AUX_ERR
(
"begin idle timeout 0x%08x
\n
"
,
ctrl
);
return
-
EBUSY
;
}
}
while
(
ctrl
&
0x03010000
);
/* set some magic, and wait up to 1ms for it to appear */
nv_mask
(
aux
,
0x00d954
+
(
ch
*
0x50
),
0x00300000
,
ureq
);
timeout
=
1000
;
do
{
ctrl
=
nv_rd32
(
aux
,
0x00d954
+
(
ch
*
0x50
));
udelay
(
1
);
if
(
!
timeout
--
)
{
AUX_ERR
(
"magic wait 0x%08x
\n
"
,
ctrl
);
auxch_fini
(
aux
,
ch
);
return
-
EBUSY
;
}
}
while
((
ctrl
&
0x03000000
)
!=
urep
);
return
0
;
}
int
gm204_aux
(
struct
nouveau_i2c_port
*
base
,
bool
retry
,
u8
type
,
u32
addr
,
u8
*
data
,
u8
size
)
{
struct
nouveau_i2c
*
aux
=
nouveau_i2c
(
base
);
struct
nv50_i2c_port
*
port
=
(
void
*
)
base
;
u32
ctrl
,
stat
,
timeout
,
retries
;
u32
xbuf
[
4
]
=
{};
int
ch
=
port
->
addr
;
int
ret
,
i
;
AUX_DBG
(
"%d: 0x%08x %d
\n
"
,
type
,
addr
,
size
);
ret
=
auxch_init
(
aux
,
ch
);
if
(
ret
)
goto
out
;
stat
=
nv_rd32
(
aux
,
0x00d958
+
(
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
(
aux
,
0x00d930
+
(
ch
*
0x50
)
+
i
,
xbuf
[
i
/
4
]);
}
}
ctrl
=
nv_rd32
(
aux
,
0x00d954
+
(
ch
*
0x50
));
ctrl
&=
~
0x0001f0ff
;
ctrl
|=
type
<<
12
;
ctrl
|=
size
-
1
;
nv_wr32
(
aux
,
0x00d950
+
(
ch
*
0x50
),
addr
);
/* (maybe) retry transaction a number of times on failure... */
for
(
retries
=
0
;
!
ret
&&
retries
<
32
;
retries
++
)
{
/* reset, and delay a while if this is a retry */
nv_wr32
(
aux
,
0x00d954
+
(
ch
*
0x50
),
0x80000000
|
ctrl
);
nv_wr32
(
aux
,
0x00d954
+
(
ch
*
0x50
),
0x00000000
|
ctrl
);
if
(
retries
)
udelay
(
400
);
/* transaction request, wait up to 1ms for it to complete */
nv_wr32
(
aux
,
0x00d954
+
(
ch
*
0x50
),
0x00010000
|
ctrl
);
timeout
=
1000
;
do
{
ctrl
=
nv_rd32
(
aux
,
0x00d954
+
(
ch
*
0x50
));
udelay
(
1
);
if
(
!
timeout
--
)
{
AUX_ERR
(
"tx req timeout 0x%08x
\n
"
,
ctrl
);
ret
=
-
EIO
;
goto
out
;
}
}
while
(
ctrl
&
0x00010000
);
ret
=
1
;
/* read status, and check if transaction completed ok */
stat
=
nv_mask
(
aux
,
0x00d958
+
(
ch
*
0x50
),
0
,
0
);
if
((
stat
&
0x000f0000
)
==
0x00080000
||
(
stat
&
0x000f0000
)
==
0x00020000
)
ret
=
retry
?
0
:
1
;
if
((
stat
&
0x00000100
))
ret
=
-
ETIMEDOUT
;
if
((
stat
&
0x00000e00
))
ret
=
-
EIO
;
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
(
aux
,
0x00d940
+
(
ch
*
0x50
)
+
i
);
AUX_DBG
(
"rd 0x%08x
\n
"
,
xbuf
[
i
/
4
]);
}
memcpy
(
data
,
xbuf
,
size
);
}
out:
auxch_fini
(
aux
,
ch
);
return
ret
<
0
?
ret
:
(
stat
&
0x000f0000
)
>>
16
;
}
static
const
struct
nouveau_i2c_func
gm204_aux_func
=
{
.
aux
=
gm204_aux
,
};
int
gm204_aux_port_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
index
,
struct
nouveau_object
**
pobject
)
{
struct
dcb_i2c_entry
*
info
=
data
;
struct
nv50_i2c_port
*
port
;
int
ret
;
ret
=
nouveau_i2c_port_create
(
parent
,
engine
,
oclass
,
index
,
&
nouveau_i2c_aux_algo
,
&
gm204_aux_func
,
&
port
);
*
pobject
=
nv_object
(
port
);
if
(
ret
)
return
ret
;
port
->
base
.
aux
=
info
->
auxch
;
port
->
addr
=
info
->
auxch
;
return
0
;
}
struct
nouveau_oclass
gm204_i2c_sclass
[]
=
{
{
.
handle
=
NV_I2C_TYPE_DCBI2C
(
DCB_I2C_NVIO_BIT
),
.
ofuncs
=
&
(
struct
nouveau_ofuncs
)
{
.
ctor
=
nvd0_i2c_port_ctor
,
.
dtor
=
_nouveau_i2c_port_dtor
,
.
init
=
nv50_i2c_port_init
,
.
fini
=
_nouveau_i2c_port_fini
,
},
},
{
.
handle
=
NV_I2C_TYPE_DCBI2C
(
DCB_I2C_NVIO_AUX
),
.
ofuncs
=
&
(
struct
nouveau_ofuncs
)
{
.
ctor
=
gm204_aux_port_ctor
,
.
dtor
=
_nouveau_i2c_port_dtor
,
.
init
=
_nouveau_i2c_port_init
,
.
fini
=
_nouveau_i2c_port_fini
,
},
},
{}
};
struct
nouveau_oclass
*
gm204_i2c_oclass
=
&
(
struct
nouveau_i2c_impl
)
{
.
base
.
handle
=
NV_SUBDEV
(
I2C
,
0x24
),
.
base
.
ofuncs
=
&
(
struct
nouveau_ofuncs
)
{
.
ctor
=
_nouveau_i2c_ctor
,
.
dtor
=
_nouveau_i2c_dtor
,
.
init
=
_nouveau_i2c_init
,
.
fini
=
_nouveau_i2c_fini
,
},
.
sclass
=
gm204_i2c_sclass
,
.
pad_x
=
&
nv04_i2c_pad_oclass
,
.
pad_s
=
&
gm204_i2c_pad_oclass
,
.
aux
=
8
,
.
aux_stat
=
nve0_aux_stat
,
.
aux_mask
=
nve0_aux_mask
,
}.
base
;
drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h
浏览文件 @
c9083577
...
...
@@ -27,4 +27,8 @@ int nv94_aux_port_ctor(struct nouveau_object *, struct nouveau_object *,
void
nv94_i2c_acquire
(
struct
nouveau_i2c_port
*
);
void
nv94_i2c_release
(
struct
nouveau_i2c_port
*
);
int
nvd0_i2c_port_ctor
(
struct
nouveau_object
*
,
struct
nouveau_object
*
,
struct
nouveau_oclass
*
,
void
*
,
u32
,
struct
nouveau_object
**
);
#endif
drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c
浏览文件 @
c9083577
...
...
@@ -48,7 +48,7 @@ nvd0_i2c_func = {
.
sense_sda
=
nvd0_i2c_sense_sda
,
};
static
int
int
nvd0_i2c_port_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
index
,
struct
nouveau_object
**
pobject
)
...
...
drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c
浏览文件 @
c9083577
...
...
@@ -24,7 +24,7 @@
#include "nv50.h"
static
void
void
nve0_aux_stat
(
struct
nouveau_i2c
*
i2c
,
u32
*
hi
,
u32
*
lo
,
u32
*
rq
,
u32
*
tx
)
{
u32
intr
=
nv_rd32
(
i2c
,
0x00dc60
);
...
...
@@ -38,7 +38,7 @@ nve0_aux_stat(struct nouveau_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx)
nv_wr32
(
i2c
,
0x00dc60
,
intr
);
}
static
void
void
nve0_aux_mask
(
struct
nouveau_i2c
*
i2c
,
u32
type
,
u32
mask
,
u32
data
)
{
u32
temp
=
nv_rd32
(
i2c
,
0x00dc68
),
i
;
...
...
drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h
浏览文件 @
c9083577
...
...
@@ -83,4 +83,7 @@ struct nouveau_i2c_impl {
void
nv94_aux_stat
(
struct
nouveau_i2c
*
,
u32
*
,
u32
*
,
u32
*
,
u32
*
);
void
nv94_aux_mask
(
struct
nouveau_i2c
*
,
u32
,
u32
,
u32
);
void
nve0_aux_stat
(
struct
nouveau_i2c
*
,
u32
*
,
u32
*
,
u32
*
,
u32
*
);
void
nve0_aux_mask
(
struct
nouveau_i2c
*
,
u32
,
u32
,
u32
);
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录