Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
a02ccc7f
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看板
提交
a02ccc7f
编写于
4月 04, 2011
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nv40/vpe: add support for PMPEG
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
d5a27370
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
321 addition
and
0 deletion
+321
-0
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/Makefile
+1
-0
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_drv.h
+4
-0
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nouveau_state.c
+3
-0
drivers/gpu/drm/nouveau/nv40_fifo.c
drivers/gpu/drm/nouveau/nv40_fifo.c
+2
-0
drivers/gpu/drm/nouveau/nv40_mpeg.c
drivers/gpu/drm/nouveau/nv40_mpeg.c
+311
-0
未找到文件。
drivers/gpu/drm/nouveau/Makefile
浏览文件 @
a02ccc7f
...
...
@@ -21,6 +21,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nv40_grctx.o nv50_grctx.o nvc0_grctx.o
\
nv84_crypt.o
\
nva3_copy.o nvc0_copy.o
\
nv40_mpeg.o
\
nv04_instmem.o nv50_instmem.o nvc0_instmem.o
\
nv50_evo.o nv50_crtc.o nv50_dac.o nv50_sor.o
\
nv50_cursor.o nv50_display.o
\
...
...
drivers/gpu/drm/nouveau/nouveau_drv.h
浏览文件 @
a02ccc7f
...
...
@@ -153,6 +153,7 @@ enum nouveau_flags {
#define NVOBJ_ENGINE_CRYPT 2
#define NVOBJ_ENGINE_COPY0 3
#define NVOBJ_ENGINE_COPY1 4
#define NVOBJ_ENGINE_MPEG 5
#define NVOBJ_ENGINE_DISPLAY 15
#define NVOBJ_ENGINE_NR 16
...
...
@@ -1154,6 +1155,9 @@ extern int nva3_copy_create(struct drm_device *dev);
/* nvc0_copy.c */
extern
int
nvc0_copy_create
(
struct
drm_device
*
dev
,
int
engine
);
/* nv40_mpeg.c */
extern
int
nv40_mpeg_create
(
struct
drm_device
*
dev
);
/* nv04_instmem.c */
extern
int
nv04_instmem_init
(
struct
drm_device
*
);
extern
void
nv04_instmem_takedown
(
struct
drm_device
*
);
...
...
drivers/gpu/drm/nouveau/nouveau_state.c
浏览文件 @
a02ccc7f
...
...
@@ -617,6 +617,9 @@ nouveau_card_init(struct drm_device *dev)
break
;
}
if
(
dev_priv
->
card_type
==
NV_40
)
nv40_mpeg_create
(
dev
);
if
(
!
nouveau_noaccel
)
{
for
(
e
=
0
;
e
<
NVOBJ_ENGINE_NR
;
e
++
)
{
if
(
dev_priv
->
eng
[
e
])
{
...
...
drivers/gpu/drm/nouveau/nv40_fifo.c
浏览文件 @
a02ccc7f
...
...
@@ -115,6 +115,7 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid)
nv_wr32
(
dev
,
0x32e8
,
nv_ri32
(
dev
,
fc
+
68
));
nv_wr32
(
dev
,
0x2088
,
nv_ri32
(
dev
,
fc
+
76
));
nv_wr32
(
dev
,
0x3300
,
nv_ri32
(
dev
,
fc
+
80
));
nv_wr32
(
dev
,
0x330c
,
nv_ri32
(
dev
,
fc
+
84
));
nv_wr32
(
dev
,
NV03_PFIFO_CACHE1_GET
,
0
);
nv_wr32
(
dev
,
NV03_PFIFO_CACHE1_PUT
,
0
);
...
...
@@ -186,6 +187,7 @@ nv40_fifo_unload_context(struct drm_device *dev)
tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16);
nv_wi32(dev, fc + 72, tmp);
#endif
nv_wi32
(
dev
,
fc
+
84
,
nv_rd32
(
dev
,
0x330c
));
nv40_fifo_do_load_context
(
dev
,
pfifo
->
channels
-
1
);
nv_wr32
(
dev
,
NV03_PFIFO_CACHE1_PUSH1
,
...
...
drivers/gpu/drm/nouveau/nv40_mpeg.c
0 → 100644
浏览文件 @
a02ccc7f
/*
* Copyright 2011 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 "drmP.h"
#include "nouveau_drv.h"
#include "nouveau_ramht.h"
struct
nv40_mpeg_engine
{
struct
nouveau_exec_engine
base
;
};
static
int
nv40_mpeg_context_new
(
struct
nouveau_channel
*
chan
,
int
engine
)
{
struct
drm_device
*
dev
=
chan
->
dev
;
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nouveau_gpuobj
*
ctx
=
NULL
;
unsigned
long
flags
;
int
ret
;
NV_DEBUG
(
dev
,
"ch%d
\n
"
,
chan
->
id
);
ret
=
nouveau_gpuobj_new
(
dev
,
NULL
,
264
*
4
,
16
,
NVOBJ_FLAG_ZERO_ALLOC
|
NVOBJ_FLAG_ZERO_FREE
,
&
ctx
);
if
(
ret
)
return
ret
;
nv_wo32
(
ctx
,
0x78
,
0x02001ec1
);
spin_lock_irqsave
(
&
dev_priv
->
context_switch_lock
,
flags
);
nv_mask
(
dev
,
0x002500
,
0x00000001
,
0x00000000
);
if
((
nv_rd32
(
dev
,
0x003204
)
&
0x1f
)
==
chan
->
id
)
nv_wr32
(
dev
,
0x00330c
,
ctx
->
pinst
>>
4
);
nv_wo32
(
chan
->
ramfc
,
0x54
,
ctx
->
pinst
>>
4
);
nv_mask
(
dev
,
0x002500
,
0x00000001
,
0x00000001
);
spin_unlock_irqrestore
(
&
dev_priv
->
context_switch_lock
,
flags
);
chan
->
engctx
[
engine
]
=
ctx
;
return
0
;
}
static
void
nv40_mpeg_context_del
(
struct
nouveau_channel
*
chan
,
int
engine
)
{
struct
drm_nouveau_private
*
dev_priv
=
chan
->
dev
->
dev_private
;
struct
nouveau_gpuobj
*
ctx
=
chan
->
engctx
[
engine
];
struct
drm_device
*
dev
=
chan
->
dev
;
unsigned
long
flags
;
u32
inst
=
0x80000000
|
(
ctx
->
pinst
>>
4
);
spin_lock_irqsave
(
&
dev_priv
->
context_switch_lock
,
flags
);
nv_mask
(
dev
,
0x00b32c
,
0x00000001
,
0x00000000
);
if
(
nv_rd32
(
dev
,
0x00b318
)
==
inst
)
nv_mask
(
dev
,
0x00b318
,
0x80000000
,
0x00000000
);
nv_mask
(
dev
,
0x00b32c
,
0x00000001
,
0x00000001
);
spin_unlock_irqrestore
(
&
dev_priv
->
context_switch_lock
,
flags
);
nouveau_gpuobj_ref
(
NULL
,
&
ctx
);
chan
->
engctx
[
engine
]
=
NULL
;
}
static
int
nv40_mpeg_object_new
(
struct
nouveau_channel
*
chan
,
int
engine
,
u32
handle
,
u16
class
)
{
struct
drm_device
*
dev
=
chan
->
dev
;
struct
nouveau_gpuobj
*
obj
=
NULL
;
int
ret
;
ret
=
nouveau_gpuobj_new
(
dev
,
chan
,
20
,
16
,
NVOBJ_FLAG_ZERO_ALLOC
|
NVOBJ_FLAG_ZERO_FREE
,
&
obj
);
if
(
ret
)
return
ret
;
obj
->
engine
=
2
;
obj
->
class
=
class
;
nv_wo32
(
obj
,
0x00
,
class
);
ret
=
nouveau_ramht_insert
(
chan
,
handle
,
obj
);
nouveau_gpuobj_ref
(
NULL
,
&
obj
);
return
ret
;
}
static
int
nv40_mpeg_init
(
struct
drm_device
*
dev
,
int
engine
)
{
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nv40_mpeg_engine
*
pmpeg
=
nv_engine
(
dev
,
engine
);
int
i
;
/* VPE init */
nv_mask
(
dev
,
0x000200
,
0x00000002
,
0x00000000
);
nv_mask
(
dev
,
0x000200
,
0x00000002
,
0x00000002
);
nv_wr32
(
dev
,
0x00b0e0
,
0x00000020
);
/* nvidia: rd 0x01, wr 0x20 */
nv_wr32
(
dev
,
0x00b0e8
,
0x00000020
);
/* nvidia: rd 0x01, wr 0x20 */
for
(
i
=
0
;
i
<
dev_priv
->
engine
.
fb
.
num_tiles
;
i
++
)
pmpeg
->
base
.
set_tile_region
(
dev
,
i
);
/* PMPEG init */
nv_wr32
(
dev
,
0x00b32c
,
0x00000000
);
nv_wr32
(
dev
,
0x00b314
,
0x00000100
);
nv_wr32
(
dev
,
0x00b220
,
0x00000044
);
nv_wr32
(
dev
,
0x00b300
,
0x02001ec1
);
nv_mask
(
dev
,
0x00b32c
,
0x00000001
,
0x00000001
);
nv_wr32
(
dev
,
0x00b100
,
0xffffffff
);
nv_wr32
(
dev
,
0x00b140
,
0xffffffff
);
if
(
!
nv_wait
(
dev
,
0x00b200
,
0x00000001
,
0x00000000
))
{
NV_ERROR
(
dev
,
"PMPEG init: 0x%08x
\n
"
,
nv_rd32
(
dev
,
0x00b200
));
return
-
EBUSY
;
}
return
0
;
}
static
int
nv40_mpeg_fini
(
struct
drm_device
*
dev
,
int
engine
)
{
/*XXX: context save? */
nv_mask
(
dev
,
0x00b32c
,
0x00000001
,
0x00000000
);
nv_wr32
(
dev
,
0x00b140
,
0x00000000
);
return
0
;
}
static
int
nv40_mpeg_mthd_dma
(
struct
nouveau_channel
*
chan
,
u32
class
,
u32
mthd
,
u32
data
)
{
struct
drm_device
*
dev
=
chan
->
dev
;
u32
inst
=
data
<<
4
;
u32
dma0
=
nv_ri32
(
dev
,
inst
+
0
);
u32
dma1
=
nv_ri32
(
dev
,
inst
+
4
);
u32
dma2
=
nv_ri32
(
dev
,
inst
+
8
);
u32
base
=
(
dma2
&
0xfffff000
)
|
(
dma0
>>
20
);
u32
size
=
dma1
+
1
;
/* only allow linear DMA objects */
if
(
!
(
dma0
&
0x00002000
))
return
-
EINVAL
;
if
(
mthd
==
0x0190
)
{
/* DMA_CMD */
nv_mask
(
dev
,
0x00b300
,
0x00030000
,
(
dma0
&
0x00030000
));
nv_wr32
(
dev
,
0x00b334
,
base
);
nv_wr32
(
dev
,
0x00b324
,
size
);
}
else
if
(
mthd
==
0x01a0
)
{
/* DMA_DATA */
nv_mask
(
dev
,
0x00b300
,
0x000c0000
,
(
dma0
&
0x00030000
)
<<
2
);
nv_wr32
(
dev
,
0x00b360
,
base
);
nv_wr32
(
dev
,
0x00b364
,
size
);
}
else
{
/* DMA_IMAGE, VRAM only */
if
(
dma0
&
0x000c0000
)
return
-
EINVAL
;
nv_wr32
(
dev
,
0x00b370
,
base
);
nv_wr32
(
dev
,
0x00b374
,
size
);
}
return
0
;
}
static
int
nv40_mpeg_isr_chid
(
struct
drm_device
*
dev
,
u32
inst
)
{
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nouveau_gpuobj
*
ctx
;
unsigned
long
flags
;
int
i
;
spin_lock_irqsave
(
&
dev_priv
->
channels
.
lock
,
flags
);
for
(
i
=
0
;
i
<
dev_priv
->
engine
.
fifo
.
channels
;
i
++
)
{
if
(
!
dev_priv
->
channels
.
ptr
[
i
])
continue
;
ctx
=
dev_priv
->
channels
.
ptr
[
i
]
->
engctx
[
NVOBJ_ENGINE_MPEG
];
if
(
ctx
&&
ctx
->
pinst
==
inst
)
break
;
}
spin_unlock_irqrestore
(
&
dev_priv
->
channels
.
lock
,
flags
);
return
i
;
}
static
void
nv40_vpe_set_tile_region
(
struct
drm_device
*
dev
,
int
i
)
{
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nouveau_tile_reg
*
tile
=
&
dev_priv
->
tile
.
reg
[
i
];
nv_wr32
(
dev
,
0x00b008
+
(
i
*
0x10
),
tile
->
pitch
);
nv_wr32
(
dev
,
0x00b004
+
(
i
*
0x10
),
tile
->
limit
);
nv_wr32
(
dev
,
0x00b000
+
(
i
*
0x10
),
tile
->
addr
);
}
static
void
nv40_mpeg_isr
(
struct
drm_device
*
dev
)
{
u32
inst
=
(
nv_rd32
(
dev
,
0x00b318
)
&
0x000fffff
)
<<
4
;
u32
chid
=
nv40_mpeg_isr_chid
(
dev
,
inst
);
u32
stat
=
nv_rd32
(
dev
,
0x00b100
);
u32
type
=
nv_rd32
(
dev
,
0x00b230
);
u32
mthd
=
nv_rd32
(
dev
,
0x00b234
);
u32
data
=
nv_rd32
(
dev
,
0x00b238
);
u32
show
=
stat
;
if
(
stat
&
0x01000000
)
{
/* happens on initial binding of the object */
if
(
type
==
0x00000020
&&
mthd
==
0x0000
)
{
nv_mask
(
dev
,
0x00b308
,
0x00000000
,
0x00000000
);
show
&=
~
0x01000000
;
}
if
(
type
==
0x00000010
)
{
if
(
!
nouveau_gpuobj_mthd_call2
(
dev
,
chid
,
0x3174
,
mthd
,
data
))
show
&=
~
0x01000000
;
}
}
nv_wr32
(
dev
,
0x00b100
,
stat
);
nv_wr32
(
dev
,
0x00b230
,
0x00000001
);
if
(
show
&&
nouveau_ratelimit
())
{
NV_INFO
(
dev
,
"PMPEG: Ch %d [0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x
\n
"
,
chid
,
inst
,
stat
,
type
,
mthd
,
data
);
}
}
static
void
nv40_vpe_isr
(
struct
drm_device
*
dev
)
{
if
(
nv_rd32
(
dev
,
0x00b100
))
nv40_mpeg_isr
(
dev
);
if
(
nv_rd32
(
dev
,
0x00b800
))
{
u32
stat
=
nv_rd32
(
dev
,
0x00b800
);
NV_INFO
(
dev
,
"PMSRCH: 0x%08x
\n
"
,
stat
);
nv_wr32
(
dev
,
0xb800
,
stat
);
}
}
static
void
nv40_mpeg_destroy
(
struct
drm_device
*
dev
,
int
engine
)
{
struct
nv40_mpeg_engine
*
pmpeg
=
nv_engine
(
dev
,
engine
);
nouveau_irq_unregister
(
dev
,
0
);
NVOBJ_ENGINE_DEL
(
dev
,
MPEG
);
kfree
(
pmpeg
);
}
int
nv40_mpeg_create
(
struct
drm_device
*
dev
)
{
struct
nv40_mpeg_engine
*
pmpeg
;
pmpeg
=
kzalloc
(
sizeof
(
*
pmpeg
),
GFP_KERNEL
);
if
(
!
pmpeg
)
return
-
ENOMEM
;
pmpeg
->
base
.
destroy
=
nv40_mpeg_destroy
;
pmpeg
->
base
.
init
=
nv40_mpeg_init
;
pmpeg
->
base
.
fini
=
nv40_mpeg_fini
;
pmpeg
->
base
.
context_new
=
nv40_mpeg_context_new
;
pmpeg
->
base
.
context_del
=
nv40_mpeg_context_del
;
pmpeg
->
base
.
object_new
=
nv40_mpeg_object_new
;
/* ISR vector, PMC_ENABLE bit, and TILE regs are shared between
* all VPE engines, for this driver's purposes the PMPEG engine
* will be treated as the "master" and handle the global VPE
* bits too
*/
pmpeg
->
base
.
set_tile_region
=
nv40_vpe_set_tile_region
;
nouveau_irq_register
(
dev
,
0
,
nv40_vpe_isr
);
NVOBJ_ENGINE_ADD
(
dev
,
MPEG
,
&
pmpeg
->
base
);
NVOBJ_CLASS
(
dev
,
0x3174
,
MPEG
);
NVOBJ_MTHD
(
dev
,
0x3174
,
0x0190
,
nv40_mpeg_mthd_dma
);
NVOBJ_MTHD
(
dev
,
0x3174
,
0x01a0
,
nv40_mpeg_mthd_dma
);
NVOBJ_MTHD
(
dev
,
0x3174
,
0x01b0
,
nv40_mpeg_mthd_dma
);
#if 0
NVOBJ_ENGINE_ADD(dev, ME, &pme->base);
NVOBJ_CLASS(dev, 0x4075, ME);
#endif
return
0
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录