Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
b7bc613a
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看板
提交
b7bc613a
编写于
10月 19, 2010
作者:
B
Ben Skeggs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm/nv50: move evo handling to nv50_evo.c
Signed-off-by:
N
Ben Skeggs
<
bskeggs@redhat.com
>
上级
106ddad5
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
322 addition
and
245 deletion
+322
-245
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/Makefile
+1
-1
drivers/gpu/drm/nouveau/nouveau_reg.h
drivers/gpu/drm/nouveau/nouveau_reg.h
+11
-11
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_display.c
+5
-233
drivers/gpu/drm/nouveau/nv50_evo.c
drivers/gpu/drm/nouveau/nv50_evo.c
+295
-0
drivers/gpu/drm/nouveau/nv50_evo.h
drivers/gpu/drm/nouveau/nv50_evo.h
+10
-0
未找到文件。
drivers/gpu/drm/nouveau/Makefile
浏览文件 @
b7bc613a
...
@@ -20,7 +20,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
...
@@ -20,7 +20,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nv40_grctx.o nv50_grctx.o
\
nv40_grctx.o nv50_grctx.o
\
nv84_crypt.o
\
nv84_crypt.o
\
nv04_instmem.o nv50_instmem.o nvc0_instmem.o
\
nv04_instmem.o nv50_instmem.o nvc0_instmem.o
\
nv50_crtc.o nv50_dac.o nv50_sor.o
\
nv50_
evo.o nv50_
crtc.o nv50_dac.o nv50_sor.o
\
nv50_cursor.o nv50_display.o nv50_fbcon.o
\
nv50_cursor.o nv50_display.o nv50_fbcon.o
\
nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o
\
nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o
\
nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o
\
nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o
\
...
...
drivers/gpu/drm/nouveau/nouveau_reg.h
浏览文件 @
b7bc613a
...
@@ -729,17 +729,17 @@
...
@@ -729,17 +729,17 @@
#define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000
#define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000
#define NV50_PDISPLAY_TRAPPED_ADDR 0x00610080
#define NV50_PDISPLAY_TRAPPED_ADDR 0x00610080
#define NV50_PDISPLAY_TRAPPED_DATA 0x00610084
#define NV50_PDISPLAY_TRAPPED_DATA 0x00610084
#define NV50_PDISPLAY_
CHANNEL_STAT(i)
((i) * 0x10 + 0x00610200)
#define NV50_PDISPLAY_
EVO_CTRL(i)
((i) * 0x10 + 0x00610200)
#define NV50_PDISPLAY_
CHANNEL_STAT_DMA
0x00000010
#define NV50_PDISPLAY_
EVO_CTRL_DMA
0x00000010
#define NV50_PDISPLAY_
CHANNEL_STAT_DMA_DISABLED
0x00000000
#define NV50_PDISPLAY_
EVO_CTRL_DMA_DISABLED
0x00000000
#define NV50_PDISPLAY_
CHANNEL_STAT_DMA_ENABLED
0x00000010
#define NV50_PDISPLAY_
EVO_CTRL_DMA_ENABLED
0x00000010
#define NV50_PDISPLAY_
CHANNEL_DMA_CB(i)
((i) * 0x10 + 0x00610204)
#define NV50_PDISPLAY_
EVO_DMA_CB(i)
((i) * 0x10 + 0x00610204)
#define NV50_PDISPLAY_
CHANNEL_DMA_CB_LOCATION
0x00000002
#define NV50_PDISPLAY_
EVO_DMA_CB_LOCATION
0x00000002
#define NV50_PDISPLAY_
CHANNEL_DMA_CB_LOCATION_VRAM
0x00000000
#define NV50_PDISPLAY_
EVO_DMA_CB_LOCATION_VRAM
0x00000000
#define NV50_PDISPLAY_
CHANNEL_DMA_CB_LOCATION_SYSTEM
0x00000002
#define NV50_PDISPLAY_
EVO_DMA_CB_LOCATION_SYSTEM
0x00000002
#define NV50_PDISPLAY_
CHANNEL_DMA_CB_VALID
0x00000001
#define NV50_PDISPLAY_
EVO_DMA_CB_VALID
0x00000001
#define NV50_PDISPLAY_
CHANNEL_UNK2(i)
((i) * 0x10 + 0x00610208)
#define NV50_PDISPLAY_
EVO_UNK2(i)
((i) * 0x10 + 0x00610208)
#define NV50_PDISPLAY_
CHANNEL_UNK3
(i) ((i) * 0x10 + 0x0061020c)
#define NV50_PDISPLAY_
EVO_HASH_TAG
(i) ((i) * 0x10 + 0x0061020c)
#define NV50_PDISPLAY_CURSOR 0x00610270
#define NV50_PDISPLAY_CURSOR 0x00610270
#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i) ((i) * 0x10 + 0x00610270)
#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i) ((i) * 0x10 + 0x00610270)
...
...
drivers/gpu/drm/nouveau/nv50_display.c
浏览文件 @
b7bc613a
...
@@ -46,159 +46,6 @@ nv50_sor_nr(struct drm_device *dev)
...
@@ -46,159 +46,6 @@ nv50_sor_nr(struct drm_device *dev)
return
4
;
return
4
;
}
}
static
void
nv50_evo_channel_del
(
struct
nouveau_channel
**
pchan
)
{
struct
nouveau_channel
*
chan
=
*
pchan
;
if
(
!
chan
)
return
;
*
pchan
=
NULL
;
nouveau_gpuobj_channel_takedown
(
chan
);
nouveau_bo_unmap
(
chan
->
pushbuf_bo
);
nouveau_bo_ref
(
NULL
,
&
chan
->
pushbuf_bo
);
if
(
chan
->
user
)
iounmap
(
chan
->
user
);
kfree
(
chan
);
}
static
int
nv50_evo_dmaobj_new
(
struct
nouveau_channel
*
evo
,
uint32_t
class
,
uint32_t
name
,
uint32_t
tile_flags
,
uint32_t
magic_flags
,
uint32_t
offset
,
uint32_t
limit
)
{
struct
drm_nouveau_private
*
dev_priv
=
evo
->
dev
->
dev_private
;
struct
drm_device
*
dev
=
evo
->
dev
;
struct
nouveau_gpuobj
*
obj
=
NULL
;
int
ret
;
ret
=
nouveau_gpuobj_new
(
dev
,
evo
,
6
*
4
,
32
,
0
,
&
obj
);
if
(
ret
)
return
ret
;
obj
->
engine
=
NVOBJ_ENGINE_DISPLAY
;
nv_wo32
(
obj
,
0
,
(
tile_flags
<<
22
)
|
(
magic_flags
<<
16
)
|
class
);
nv_wo32
(
obj
,
4
,
limit
);
nv_wo32
(
obj
,
8
,
offset
);
nv_wo32
(
obj
,
12
,
0x00000000
);
nv_wo32
(
obj
,
16
,
0x00000000
);
if
(
dev_priv
->
card_type
<
NV_C0
)
nv_wo32
(
obj
,
20
,
0x00010000
);
else
nv_wo32
(
obj
,
20
,
0x00020000
);
dev_priv
->
engine
.
instmem
.
flush
(
dev
);
ret
=
nouveau_ramht_insert
(
evo
,
name
,
obj
);
nouveau_gpuobj_ref
(
NULL
,
&
obj
);
if
(
ret
)
{
return
ret
;
}
return
0
;
}
static
int
nv50_evo_channel_new
(
struct
drm_device
*
dev
,
struct
nouveau_channel
**
pchan
)
{
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nouveau_gpuobj
*
ramht
=
NULL
;
struct
nouveau_channel
*
chan
;
int
ret
;
chan
=
kzalloc
(
sizeof
(
struct
nouveau_channel
),
GFP_KERNEL
);
if
(
!
chan
)
return
-
ENOMEM
;
*
pchan
=
chan
;
chan
->
id
=
-
1
;
chan
->
dev
=
dev
;
chan
->
user_get
=
4
;
chan
->
user_put
=
0
;
ret
=
nouveau_gpuobj_new
(
dev
,
NULL
,
32768
,
0x1000
,
NVOBJ_FLAG_ZERO_ALLOC
,
&
chan
->
ramin
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Error allocating EVO channel memory: %d
\n
"
,
ret
);
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
drm_mm_init
(
&
chan
->
ramin_heap
,
0
,
32768
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Error initialising EVO PRAMIN heap: %d
\n
"
,
ret
);
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
nouveau_gpuobj_new
(
dev
,
chan
,
4096
,
16
,
0
,
&
ramht
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Unable to allocate EVO RAMHT: %d
\n
"
,
ret
);
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
nouveau_ramht_new
(
dev
,
ramht
,
&
chan
->
ramht
);
nouveau_gpuobj_ref
(
NULL
,
&
ramht
);
if
(
ret
)
{
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
if
(
dev_priv
->
chipset
!=
0x50
)
{
ret
=
nv50_evo_dmaobj_new
(
chan
,
0x3d
,
NvEvoFB16
,
0x70
,
0x19
,
0
,
0xffffffff
);
if
(
ret
)
{
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
nv50_evo_dmaobj_new
(
chan
,
0x3d
,
NvEvoFB32
,
0x7a
,
0x19
,
0
,
0xffffffff
);
if
(
ret
)
{
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
}
ret
=
nv50_evo_dmaobj_new
(
chan
,
0x3d
,
NvEvoVRAM
,
0
,
0x19
,
0
,
dev_priv
->
vram_size
);
if
(
ret
)
{
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
nouveau_bo_new
(
dev
,
NULL
,
4096
,
0
,
TTM_PL_FLAG_VRAM
,
0
,
0
,
false
,
true
,
&
chan
->
pushbuf_bo
);
if
(
ret
==
0
)
ret
=
nouveau_bo_pin
(
chan
->
pushbuf_bo
,
TTM_PL_FLAG_VRAM
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Error creating EVO DMA push buffer: %d
\n
"
,
ret
);
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
nouveau_bo_map
(
chan
->
pushbuf_bo
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Error mapping EVO DMA push buffer: %d
\n
"
,
ret
);
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
chan
->
user
=
ioremap
(
pci_resource_start
(
dev
->
pdev
,
0
)
+
NV50_PDISPLAY_USER
(
0
),
PAGE_SIZE
);
if
(
!
chan
->
user
)
{
NV_ERROR
(
dev
,
"Error mapping EVO control regs.
\n
"
);
nv50_evo_channel_del
(
pchan
);
return
-
ENOMEM
;
}
return
0
;
}
int
int
nv50_display_early_init
(
struct
drm_device
*
dev
)
nv50_display_early_init
(
struct
drm_device
*
dev
)
{
{
...
@@ -214,12 +61,10 @@ int
...
@@ -214,12 +61,10 @@ int
nv50_display_init
(
struct
drm_device
*
dev
)
nv50_display_init
(
struct
drm_device
*
dev
)
{
{
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nouveau_timer_engine
*
ptimer
=
&
dev_priv
->
engine
.
timer
;
struct
nouveau_gpio_engine
*
pgpio
=
&
dev_priv
->
engine
.
gpio
;
struct
nouveau_gpio_engine
*
pgpio
=
&
dev_priv
->
engine
.
gpio
;
struct
nouveau_channel
*
evo
=
dev_priv
->
evo
;
struct
drm_connector
*
connector
;
struct
drm_connector
*
connector
;
struct
nouveau_channel
*
evo
;
int
ret
,
i
;
int
ret
,
i
;
u64
start
;
u32
val
;
u32
val
;
NV_DEBUG_KMS
(
dev
,
"
\n
"
);
NV_DEBUG_KMS
(
dev
,
"
\n
"
);
...
@@ -303,7 +148,6 @@ nv50_display_init(struct drm_device *dev)
...
@@ -303,7 +148,6 @@ nv50_display_init(struct drm_device *dev)
}
}
}
}
nv_wr32
(
dev
,
NV50_PDISPLAY_OBJECTS
,
(
evo
->
ramin
->
vinst
>>
8
)
|
9
);
nv_wr32
(
dev
,
NV50_PDISPLAY_PIO_CTRL
,
0x00000000
);
nv_wr32
(
dev
,
NV50_PDISPLAY_PIO_CTRL
,
0x00000000
);
nv_wr32
(
dev
,
0x610028
,
0x00000000
);
nv_wr32
(
dev
,
0x610028
,
0x00000000
);
nv_mask
(
dev
,
NV50_PDISPLAY_INTR_0
,
0x00000000
,
0x00000000
);
nv_mask
(
dev
,
NV50_PDISPLAY_INTR_0
,
0x00000000
,
0x00000000
);
...
@@ -323,69 +167,12 @@ nv50_display_init(struct drm_device *dev)
...
@@ -323,69 +167,12 @@ nv50_display_init(struct drm_device *dev)
pgpio
->
irq_enable
(
dev
,
conn
->
dcb
->
gpio_tag
,
true
);
pgpio
->
irq_enable
(
dev
,
conn
->
dcb
->
gpio_tag
,
true
);
}
}
/* taken from nv bug #12637, attempts to un-wedge the hw if it's
ret
=
nv50_evo_init
(
dev
);
* stuck in some unspecified state
*/
start
=
ptimer
->
read
(
dev
);
nv_wr32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
),
0x2b00
);
while
((
val
=
nv_rd32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
)))
&
0x1e0000
)
{
if
((
val
&
0x9f0000
)
==
0x20000
)
nv_wr32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
),
val
|
0x800000
);
if
((
val
&
0x3f0000
)
==
0x30000
)
nv_wr32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
),
val
|
0x200000
);
if
(
ptimer
->
read
(
dev
)
-
start
>
1000000000ULL
)
{
NV_ERROR
(
dev
,
"timeout: (0x610200 & 0x1e0000) != 0
\n
"
);
NV_ERROR
(
dev
,
"0x610200 = 0x%08x
\n
"
,
val
);
return
-
EBUSY
;
}
}
nv_wr32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
),
0x1000b03
);
if
(
!
nv_wait
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
),
0x40000000
,
0x40000000
))
{
NV_ERROR
(
dev
,
"timeout: (0x610200 & 0x40000000) == 0x40000000
\n
"
);
NV_ERROR
(
dev
,
"0x610200 = 0x%08x
\n
"
,
nv_rd32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
)));
return
-
EBUSY
;
}
/* initialise fifo */
nv_wr32
(
dev
,
NV50_PDISPLAY_CHANNEL_DMA_CB
(
0
),
((
evo
->
pushbuf_bo
->
bo
.
mem
.
start
<<
PAGE_SHIFT
)
>>
8
)
|
NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_VRAM
|
NV50_PDISPLAY_CHANNEL_DMA_CB_VALID
);
nv_wr32
(
dev
,
NV50_PDISPLAY_CHANNEL_UNK2
(
0
),
0x00010000
);
nv_wr32
(
dev
,
NV50_PDISPLAY_CHANNEL_UNK3
(
0
),
0x00000002
);
if
(
!
nv_wait
(
dev
,
0x610200
,
0x80000000
,
0x00000000
))
{
NV_ERROR
(
dev
,
"timeout: (0x610200 & 0x80000000) == 0
\n
"
);
NV_ERROR
(
dev
,
"0x610200 = 0x%08x
\n
"
,
nv_rd32
(
dev
,
0x610200
));
return
-
EBUSY
;
}
nv_wr32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
),
(
nv_rd32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
))
&
~
0x00000003
)
|
NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED
);
nv_wr32
(
dev
,
NV50_PDISPLAY_USER_PUT
(
0
),
0
);
nv_wr32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
),
0x01000003
|
NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED
);
/* enable error reporting on the channel */
nv_mask
(
dev
,
0x610028
,
0x00000000
,
0x00010001
<<
0
);
evo
->
dma
.
max
=
(
4096
/
4
)
-
2
;
evo
->
dma
.
put
=
0
;
evo
->
dma
.
cur
=
evo
->
dma
.
put
;
evo
->
dma
.
free
=
evo
->
dma
.
max
-
evo
->
dma
.
cur
;
ret
=
RING_SPACE
(
evo
,
NOUVEAU_DMA_SKIPS
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
evo
=
dev_priv
->
evo
;
for
(
i
=
0
;
i
<
NOUVEAU_DMA_SKIPS
;
i
++
)
nv_wr32
(
dev
,
NV50_PDISPLAY_OBJECTS
,
(
evo
->
ramin
->
vinst
>>
8
)
|
9
);
OUT_RING
(
evo
,
0
);
ret
=
RING_SPACE
(
evo
,
11
);
ret
=
RING_SPACE
(
evo
,
11
);
if
(
ret
)
if
(
ret
)
...
@@ -449,12 +236,7 @@ static int nv50_display_disable(struct drm_device *dev)
...
@@ -449,12 +236,7 @@ static int nv50_display_disable(struct drm_device *dev)
}
}
}
}
nv_wr32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
),
0
);
nv50_evo_fini
(
dev
);
if
(
!
nv_wait
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
),
0x1e0000
,
0
))
{
NV_ERROR
(
dev
,
"timeout: (0x610200 & 0x1e0000) == 0
\n
"
);
NV_ERROR
(
dev
,
"0x610200 = 0x%08x
\n
"
,
nv_rd32
(
dev
,
NV50_PDISPLAY_CHANNEL_STAT
(
0
)));
}
for
(
i
=
0
;
i
<
3
;
i
++
)
{
for
(
i
=
0
;
i
<
3
;
i
++
)
{
if
(
!
nv_wait
(
dev
,
NV50_PDISPLAY_SOR_DPMS_STATE
(
i
),
if
(
!
nv_wait
(
dev
,
NV50_PDISPLAY_SOR_DPMS_STATE
(
i
),
...
@@ -504,13 +286,6 @@ int nv50_display_create(struct drm_device *dev)
...
@@ -504,13 +286,6 @@ int nv50_display_create(struct drm_device *dev)
dev
->
mode_config
.
fb_base
=
dev_priv
->
fb_phys
;
dev
->
mode_config
.
fb_base
=
dev_priv
->
fb_phys
;
/* Create EVO channel */
ret
=
nv50_evo_channel_new
(
dev
,
&
dev_priv
->
evo
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Error creating EVO channel: %d
\n
"
,
ret
);
return
ret
;
}
/* Create CRTC objects */
/* Create CRTC objects */
for
(
i
=
0
;
i
<
2
;
i
++
)
for
(
i
=
0
;
i
<
2
;
i
++
)
nv50_crtc_create
(
dev
,
i
);
nv50_crtc_create
(
dev
,
i
);
...
@@ -565,14 +340,11 @@ int nv50_display_create(struct drm_device *dev)
...
@@ -565,14 +340,11 @@ int nv50_display_create(struct drm_device *dev)
void
void
nv50_display_destroy
(
struct
drm_device
*
dev
)
nv50_display_destroy
(
struct
drm_device
*
dev
)
{
{
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
NV_DEBUG_KMS
(
dev
,
"
\n
"
);
NV_DEBUG_KMS
(
dev
,
"
\n
"
);
drm_mode_config_cleanup
(
dev
);
drm_mode_config_cleanup
(
dev
);
nv50_display_disable
(
dev
);
nv50_display_disable
(
dev
);
nv50_evo_channel_del
(
&
dev_priv
->
evo
);
}
}
static
u16
static
u16
...
...
drivers/gpu/drm/nouveau/nv50_evo.c
0 → 100644
浏览文件 @
b7bc613a
/*
* Copyright 2010 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_dma.h"
#include "nouveau_ramht.h"
static
void
nv50_evo_channel_del
(
struct
nouveau_channel
**
pchan
)
{
struct
nouveau_channel
*
chan
=
*
pchan
;
if
(
!
chan
)
return
;
*
pchan
=
NULL
;
nouveau_gpuobj_channel_takedown
(
chan
);
nouveau_bo_unmap
(
chan
->
pushbuf_bo
);
nouveau_bo_ref
(
NULL
,
&
chan
->
pushbuf_bo
);
if
(
chan
->
user
)
iounmap
(
chan
->
user
);
kfree
(
chan
);
}
int
nv50_evo_dmaobj_new
(
struct
nouveau_channel
*
evo
,
u32
class
,
u32
name
,
u32
tile_flags
,
u32
magic_flags
,
u32
offset
,
u32
limit
)
{
struct
drm_nouveau_private
*
dev_priv
=
evo
->
dev
->
dev_private
;
struct
drm_device
*
dev
=
evo
->
dev
;
struct
nouveau_gpuobj
*
obj
=
NULL
;
int
ret
;
ret
=
nouveau_gpuobj_new
(
dev
,
evo
,
6
*
4
,
32
,
0
,
&
obj
);
if
(
ret
)
return
ret
;
obj
->
engine
=
NVOBJ_ENGINE_DISPLAY
;
nv_wo32
(
obj
,
0
,
(
tile_flags
<<
22
)
|
(
magic_flags
<<
16
)
|
class
);
nv_wo32
(
obj
,
4
,
limit
);
nv_wo32
(
obj
,
8
,
offset
);
nv_wo32
(
obj
,
12
,
0x00000000
);
nv_wo32
(
obj
,
16
,
0x00000000
);
if
(
dev_priv
->
card_type
<
NV_C0
)
nv_wo32
(
obj
,
20
,
0x00010000
);
else
nv_wo32
(
obj
,
20
,
0x00020000
);
dev_priv
->
engine
.
instmem
.
flush
(
dev
);
ret
=
nouveau_ramht_insert
(
evo
,
name
,
obj
);
nouveau_gpuobj_ref
(
NULL
,
&
obj
);
if
(
ret
)
{
return
ret
;
}
return
0
;
}
static
int
nv50_evo_channel_new
(
struct
drm_device
*
dev
,
struct
nouveau_channel
**
pchan
)
{
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
nouveau_gpuobj
*
ramht
=
NULL
;
struct
nouveau_channel
*
chan
;
int
ret
;
chan
=
kzalloc
(
sizeof
(
struct
nouveau_channel
),
GFP_KERNEL
);
if
(
!
chan
)
return
-
ENOMEM
;
*
pchan
=
chan
;
chan
->
id
=
-
1
;
chan
->
dev
=
dev
;
chan
->
user_get
=
4
;
chan
->
user_put
=
0
;
ret
=
nouveau_gpuobj_new
(
dev
,
NULL
,
32768
,
0x1000
,
NVOBJ_FLAG_ZERO_ALLOC
,
&
chan
->
ramin
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Error allocating EVO channel memory: %d
\n
"
,
ret
);
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
drm_mm_init
(
&
chan
->
ramin_heap
,
0
,
32768
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Error initialising EVO PRAMIN heap: %d
\n
"
,
ret
);
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
nouveau_gpuobj_new
(
dev
,
chan
,
4096
,
16
,
0
,
&
ramht
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Unable to allocate EVO RAMHT: %d
\n
"
,
ret
);
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
nouveau_ramht_new
(
dev
,
ramht
,
&
chan
->
ramht
);
nouveau_gpuobj_ref
(
NULL
,
&
ramht
);
if
(
ret
)
{
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
if
(
dev_priv
->
chipset
!=
0x50
)
{
ret
=
nv50_evo_dmaobj_new
(
chan
,
0x3d
,
NvEvoFB16
,
0x70
,
0x19
,
0
,
0xffffffff
);
if
(
ret
)
{
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
nv50_evo_dmaobj_new
(
chan
,
0x3d
,
NvEvoFB32
,
0x7a
,
0x19
,
0
,
0xffffffff
);
if
(
ret
)
{
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
}
ret
=
nv50_evo_dmaobj_new
(
chan
,
0x3d
,
NvEvoVRAM
,
0
,
0x19
,
0
,
dev_priv
->
vram_size
);
if
(
ret
)
{
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
nouveau_bo_new
(
dev
,
NULL
,
4096
,
0
,
TTM_PL_FLAG_VRAM
,
0
,
0
,
false
,
true
,
&
chan
->
pushbuf_bo
);
if
(
ret
==
0
)
ret
=
nouveau_bo_pin
(
chan
->
pushbuf_bo
,
TTM_PL_FLAG_VRAM
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Error creating EVO DMA push buffer: %d
\n
"
,
ret
);
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
ret
=
nouveau_bo_map
(
chan
->
pushbuf_bo
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"Error mapping EVO DMA push buffer: %d
\n
"
,
ret
);
nv50_evo_channel_del
(
pchan
);
return
ret
;
}
chan
->
user
=
ioremap
(
pci_resource_start
(
dev
->
pdev
,
0
)
+
NV50_PDISPLAY_USER
(
0
),
PAGE_SIZE
);
if
(
!
chan
->
user
)
{
NV_ERROR
(
dev
,
"Error mapping EVO control regs.
\n
"
);
nv50_evo_channel_del
(
pchan
);
return
-
ENOMEM
;
}
return
0
;
}
static
int
nv50_evo_channel_init
(
struct
nouveau_channel
*
evo
)
{
struct
drm_nouveau_private
*
dev_priv
=
evo
->
dev
->
dev_private
;
struct
nouveau_timer_engine
*
ptimer
=
&
dev_priv
->
engine
.
timer
;
struct
drm_device
*
dev
=
evo
->
dev
;
int
ret
,
i
;
u64
start
;
u32
tmp
;
/* taken from nv bug #12637, attempts to un-wedge the hw if it's
* stuck in some unspecified state
*/
start
=
ptimer
->
read
(
dev
);
nv_wr32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
),
0x2b00
);
while
((
tmp
=
nv_rd32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
)))
&
0x1e0000
)
{
if
((
tmp
&
0x9f0000
)
==
0x20000
)
nv_wr32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
),
tmp
|
0x800000
);
if
((
tmp
&
0x3f0000
)
==
0x30000
)
nv_wr32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
),
tmp
|
0x200000
);
if
(
ptimer
->
read
(
dev
)
-
start
>
1000000000ULL
)
{
NV_ERROR
(
dev
,
"timeout: (0x610200 & 0x1e0000) != 0
\n
"
);
NV_ERROR
(
dev
,
"0x610200 = 0x%08x
\n
"
,
tmp
);
return
-
EBUSY
;
}
}
nv_wr32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
),
0x1000b03
);
if
(
!
nv_wait
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
),
0x40000000
,
0x40000000
))
{
NV_ERROR
(
dev
,
"timeout: (0x610200 & 0x40000000) == 0x40000000
\n
"
);
NV_ERROR
(
dev
,
"0x610200 = 0x%08x
\n
"
,
nv_rd32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
)));
return
-
EBUSY
;
}
/* initialise fifo */
nv_wr32
(
dev
,
NV50_PDISPLAY_EVO_DMA_CB
(
0
),
((
evo
->
pushbuf_bo
->
bo
.
mem
.
start
<<
PAGE_SHIFT
)
>>
8
)
|
NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM
|
NV50_PDISPLAY_EVO_DMA_CB_VALID
);
nv_wr32
(
dev
,
NV50_PDISPLAY_EVO_UNK2
(
0
),
0x00010000
);
nv_wr32
(
dev
,
NV50_PDISPLAY_EVO_HASH_TAG
(
0
),
0x00000002
);
if
(
!
nv_wait
(
dev
,
0x610200
,
0x80000000
,
0x00000000
))
{
NV_ERROR
(
dev
,
"timeout: (0x610200 & 0x80000000) == 0
\n
"
);
NV_ERROR
(
dev
,
"0x610200 = 0x%08x
\n
"
,
nv_rd32
(
dev
,
0x610200
));
return
-
EBUSY
;
}
nv_wr32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
),
(
nv_rd32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
))
&
~
0x00000003
)
|
NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED
);
nv_wr32
(
dev
,
NV50_PDISPLAY_USER_PUT
(
0
),
0
);
nv_wr32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
),
0x01000003
|
NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED
);
/* enable error reporting on the channel */
nv_mask
(
dev
,
0x610028
,
0x00000000
,
0x00010001
<<
0
);
evo
->
dma
.
max
=
(
4096
/
4
)
-
2
;
evo
->
dma
.
put
=
0
;
evo
->
dma
.
cur
=
evo
->
dma
.
put
;
evo
->
dma
.
free
=
evo
->
dma
.
max
-
evo
->
dma
.
cur
;
ret
=
RING_SPACE
(
evo
,
NOUVEAU_DMA_SKIPS
);
if
(
ret
)
return
ret
;
for
(
i
=
0
;
i
<
NOUVEAU_DMA_SKIPS
;
i
++
)
OUT_RING
(
evo
,
0
);
return
0
;
}
static
void
nv50_evo_channel_fini
(
struct
nouveau_channel
*
evo
)
{
struct
drm_device
*
dev
=
evo
->
dev
;
nv_wr32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
),
0
);
if
(
!
nv_wait
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
),
0x1e0000
,
0
))
{
NV_ERROR
(
dev
,
"timeout: (0x610200 & 0x1e0000) == 0
\n
"
);
NV_ERROR
(
dev
,
"0x610200 = 0x%08x
\n
"
,
nv_rd32
(
dev
,
NV50_PDISPLAY_EVO_CTRL
(
0
)));
}
}
int
nv50_evo_init
(
struct
drm_device
*
dev
)
{
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
int
ret
;
if
(
!
dev_priv
->
evo
)
{
ret
=
nv50_evo_channel_new
(
dev
,
&
dev_priv
->
evo
);
if
(
ret
)
return
ret
;
}
return
nv50_evo_channel_init
(
dev_priv
->
evo
);
}
void
nv50_evo_fini
(
struct
drm_device
*
dev
)
{
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
if
(
dev_priv
->
evo
)
{
nv50_evo_channel_fini
(
dev_priv
->
evo
);
nv50_evo_channel_del
(
&
dev_priv
->
evo
);
}
}
drivers/gpu/drm/nouveau/nv50_evo.h
浏览文件 @
b7bc613a
...
@@ -24,6 +24,15 @@
...
@@ -24,6 +24,15 @@
*
*
*/
*/
#ifndef __NV50_EVO_H__
#define __NV50_EVO_H__
int
nv50_evo_init
(
struct
drm_device
*
dev
);
void
nv50_evo_fini
(
struct
drm_device
*
dev
);
int
nv50_evo_dmaobj_new
(
struct
nouveau_channel
*
,
u32
class
,
u32
name
,
u32
tile_flags
,
u32
magic_flags
,
u32
offset
,
u32
limit
);
#define NV50_EVO_UPDATE 0x00000080
#define NV50_EVO_UPDATE 0x00000080
#define NV50_EVO_UNK84 0x00000084
#define NV50_EVO_UNK84 0x00000084
#define NV50_EVO_UNK84_NOTIFY 0x40000000
#define NV50_EVO_UNK84_NOTIFY 0x40000000
...
@@ -111,3 +120,4 @@
...
@@ -111,3 +120,4 @@
#define NV50_EVO_CRTC_SCALE_RES1 0x000008d8
#define NV50_EVO_CRTC_SCALE_RES1 0x000008d8
#define NV50_EVO_CRTC_SCALE_RES2 0x000008dc
#define NV50_EVO_CRTC_SCALE_RES2 0x000008dc
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录