Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
b2c81703
Commit
b2c81703
authored
Aug 10, 2014
by
Ben Skeggs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drm/nouveau/dmaobj: switch to a slightly saner design
Signed-off-by:
Ben Skeggs
<
bskeggs@redhat.com
>
parent
bc98540b
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
357 additions
and
181 deletions
+357
-181
drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
+32
-41
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c
+79
-36
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c
+82
-38
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c
+76
-34
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
+73
-27
drivers/gpu/drm/nouveau/core/engine/dmaobj/priv.h
drivers/gpu/drm/nouveau/core/engine/dmaobj/priv.h
+13
-2
drivers/gpu/drm/nouveau/core/engine/fifo/base.c
drivers/gpu/drm/nouveau/core/engine/fifo/base.c
+1
-1
drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h
drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h
+1
-2
No files found.
drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
View file @
b2c81703
...
...
@@ -30,22 +30,43 @@
#include "priv.h"
static
int
nouveau_dmaobj_ctor
(
struct
nouveau_object
*
parent
,
nvkm_dmaobj_bind
(
struct
nouveau_dmaobj
*
dmaobj
,
struct
nouveau_object
*
parent
,
struct
nouveau_gpuobj
**
pgpuobj
)
{
const
struct
nvkm_dmaeng_impl
*
impl
=
(
void
*
)
nv_oclass
(
nv_object
(
dmaobj
)
->
engine
);
int
ret
=
0
;
if
(
nv_object
(
dmaobj
)
==
parent
)
{
/* ctor bind */
if
(
nv_mclass
(
parent
->
parent
)
==
NV_DEVICE
)
{
/* delayed, or no, binding */
return
0
;
}
ret
=
impl
->
bind
(
dmaobj
,
parent
,
pgpuobj
);
if
(
ret
==
0
)
nouveau_object_ref
(
NULL
,
&
parent
);
return
ret
;
}
return
impl
->
bind
(
dmaobj
,
parent
,
pgpuobj
);
}
int
nvkm_dmaobj_create_
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
struct
nouveau_oclass
*
oclass
,
void
*
*
pdata
,
u32
*
p
size
,
int
length
,
void
**
pobject
)
{
struct
n
ouveau_dmaeng
*
dmaeng
=
(
void
*
)
engine
;
struct
n
v_dma_class
*
args
=
*
pdata
;
struct
nouveau_dmaobj
*
dmaobj
;
struct
nouveau_gpuobj
*
gpuobj
;
struct
nv_dma_class
*
args
=
data
;
int
ret
;
if
(
size
<
sizeof
(
*
args
))
if
(
*
p
size
<
sizeof
(
*
args
))
return
-
EINVAL
;
*
pdata
=
&
args
->
conf0
;
ret
=
nouveau_object_create
(
parent
,
engine
,
oclass
,
0
,
&
dmaobj
);
*
pobject
=
nv_object
(
dmaobj
)
;
ret
=
nouveau_object_create
_
(
parent
,
engine
,
oclass
,
0
,
length
,
pobject
);
dmaobj
=
*
pobject
;
if
(
ret
)
return
ret
;
...
...
@@ -87,39 +108,9 @@ nouveau_dmaobj_ctor(struct nouveau_object *parent,
dmaobj
->
start
=
args
->
start
;
dmaobj
->
limit
=
args
->
limit
;
dmaobj
->
conf0
=
args
->
conf0
;
switch
(
nv_mclass
(
parent
))
{
case
NV_DEVICE
:
/* delayed, or no, binding */
break
;
default:
ret
=
dmaeng
->
bind
(
dmaeng
,
*
pobject
,
dmaobj
,
&
gpuobj
);
if
(
ret
==
0
)
{
nouveau_object_ref
(
NULL
,
pobject
);
*
pobject
=
nv_object
(
gpuobj
);
}
break
;
}
return
ret
;
}
static
struct
nouveau_ofuncs
nouveau_dmaobj_ofuncs
=
{
.
ctor
=
nouveau_dmaobj_ctor
,
.
dtor
=
nouveau_object_destroy
,
.
init
=
nouveau_object_init
,
.
fini
=
nouveau_object_fini
,
};
static
struct
nouveau_oclass
nouveau_dmaobj_sclass
[]
=
{
{
NV_DMA_FROM_MEMORY_CLASS
,
&
nouveau_dmaobj_ofuncs
},
{
NV_DMA_TO_MEMORY_CLASS
,
&
nouveau_dmaobj_ofuncs
},
{
NV_DMA_IN_MEMORY_CLASS
,
&
nouveau_dmaobj_ofuncs
},
{}
};
int
_nvkm_dmaeng_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
...
...
@@ -135,7 +126,7 @@ _nvkm_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if
(
ret
)
return
ret
;
nv_engine
(
dmaeng
)
->
sclass
=
nouveau_dmaobj_
sclass
;
dmaeng
->
bind
=
impl
->
bind
;
nv_engine
(
dmaeng
)
->
sclass
=
impl
->
sclass
;
dmaeng
->
bind
=
nvkm_dmaobj_
bind
;
return
0
;
}
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c
View file @
b2c81703
...
...
@@ -30,19 +30,23 @@
#include "priv.h"
struct
nv04_dmaobj_priv
{
struct
nouveau_dmaobj
base
;
bool
clone
;
u32
flags0
;
u32
flags2
;
};
static
int
nv04_dmaobj_bind
(
struct
nouveau_dma
eng
*
dmaeng
,
nv04_dmaobj_bind
(
struct
nouveau_dma
obj
*
dmaobj
,
struct
nouveau_object
*
parent
,
struct
nouveau_dmaobj
*
dmaobj
,
struct
nouveau_gpuobj
**
pgpuobj
)
{
struct
nv04_
vmmgr_priv
*
vmm
=
nv04_vmmgr
(
dmaeng
)
;
struct
nv04_
dmaobj_priv
*
priv
=
(
void
*
)
dmaobj
;
struct
nouveau_gpuobj
*
gpuobj
;
u32
flags0
=
nv_mclass
(
dmaobj
);
u32
flags2
=
0x00000000
;
u64
offset
=
dmaobj
->
start
&
0xfffff000
;
u64
adjust
=
dmaobj
->
start
&
0x00000fff
;
u32
length
=
dmaobj
->
limit
-
dmaobj
->
start
;
u64
offset
=
priv
->
base
.
start
&
0xfffff000
;
u64
adjust
=
priv
->
base
.
start
&
0x00000fff
;
u32
length
=
priv
->
base
.
limit
-
priv
->
base
.
start
;
int
ret
;
if
(
!
nv_iclass
(
parent
,
NV_ENGCTX_CLASS
))
{
...
...
@@ -57,58 +61,96 @@ nv04_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
}
}
if
(
dmaobj
->
target
==
NV_MEM_TARGET_VM
)
{
if
(
nv_object
(
vmm
)
->
oclass
==
&
nv04_vmmgr_oclass
)
{
struct
nouveau_gpuobj
*
pgt
=
vmm
->
vm
->
pgt
[
0
].
obj
[
0
];
if
(
!
dmaobj
->
start
)
return
nouveau_gpuobj_dup
(
parent
,
pgt
,
pgpuobj
);
offset
=
nv_ro32
(
pgt
,
8
+
(
offset
>>
10
));
offset
&=
0xfffff000
;
}
if
(
priv
->
clone
)
{
struct
nv04_vmmgr_priv
*
vmm
=
nv04_vmmgr
(
dmaobj
);
struct
nouveau_gpuobj
*
pgt
=
vmm
->
vm
->
pgt
[
0
].
obj
[
0
];
if
(
!
dmaobj
->
start
)
return
nouveau_gpuobj_dup
(
parent
,
pgt
,
pgpuobj
);
offset
=
nv_ro32
(
pgt
,
8
+
(
offset
>>
10
));
offset
&=
0xfffff000
;
}
ret
=
nouveau_gpuobj_new
(
parent
,
parent
,
16
,
16
,
0
,
&
gpuobj
);
*
pgpuobj
=
gpuobj
;
if
(
ret
==
0
)
{
nv_wo32
(
*
pgpuobj
,
0x00
,
priv
->
flags0
|
(
adjust
<<
20
));
nv_wo32
(
*
pgpuobj
,
0x04
,
length
);
nv_wo32
(
*
pgpuobj
,
0x08
,
priv
->
flags2
|
offset
);
nv_wo32
(
*
pgpuobj
,
0x0c
,
priv
->
flags2
|
offset
);
}
return
ret
;
}
static
int
nv04_dmaobj_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nouveau_dmaeng
*
dmaeng
=
(
void
*
)
engine
;
struct
nv04_vmmgr_priv
*
vmm
=
nv04_vmmgr
(
engine
);
struct
nv04_dmaobj_priv
*
priv
;
int
ret
;
ret
=
nvkm_dmaobj_create
(
parent
,
engine
,
oclass
,
&
data
,
&
size
,
&
priv
);
*
pobject
=
nv_object
(
priv
);
if
(
ret
)
return
ret
;
dmaobj
->
target
=
NV_MEM_TARGET_PCI
;
dmaobj
->
access
=
NV_MEM_ACCESS_RW
;
if
(
priv
->
base
.
target
==
NV_MEM_TARGET_VM
)
{
if
(
nv_object
(
vmm
)
->
oclass
==
&
nv04_vmmgr_oclass
)
priv
->
clone
=
true
;
priv
->
base
.
target
=
NV_MEM_TARGET_PCI
;
priv
->
base
.
access
=
NV_MEM_ACCESS_RW
;
}
switch
(
dmaobj
->
target
)
{
priv
->
flags0
=
nv_mclass
(
priv
);
switch
(
priv
->
base
.
target
)
{
case
NV_MEM_TARGET_VRAM
:
flags0
|=
0x00003000
;
priv
->
flags0
|=
0x00003000
;
break
;
case
NV_MEM_TARGET_PCI
:
flags0
|=
0x00023000
;
priv
->
flags0
|=
0x00023000
;
break
;
case
NV_MEM_TARGET_PCI_NOSNOOP
:
flags0
|=
0x00033000
;
priv
->
flags0
|=
0x00033000
;
break
;
default:
return
-
EINVAL
;
}
switch
(
dmaobj
->
access
)
{
switch
(
priv
->
base
.
access
)
{
case
NV_MEM_ACCESS_RO
:
flags0
|=
0x00004000
;
priv
->
flags0
|=
0x00004000
;
break
;
case
NV_MEM_ACCESS_WO
:
flags0
|=
0x00008000
;
priv
->
flags0
|=
0x00008000
;
case
NV_MEM_ACCESS_RW
:
flags2
|=
0x00000002
;
priv
->
flags2
|=
0x00000002
;
break
;
default:
return
-
EINVAL
;
}
ret
=
nouveau_gpuobj_new
(
parent
,
parent
,
16
,
16
,
0
,
&
gpuobj
);
*
pgpuobj
=
gpuobj
;
if
(
ret
==
0
)
{
nv_wo32
(
*
pgpuobj
,
0x00
,
flags0
|
(
adjust
<<
20
));
nv_wo32
(
*
pgpuobj
,
0x04
,
length
);
nv_wo32
(
*
pgpuobj
,
0x08
,
flags2
|
offset
);
nv_wo32
(
*
pgpuobj
,
0x0c
,
flags2
|
offset
);
}
return
ret
;
return
dmaeng
->
bind
(
&
priv
->
base
,
nv_object
(
priv
),
(
void
*
)
pobject
);
}
static
struct
nouveau_ofuncs
nv04_dmaobj_ofuncs
=
{
.
ctor
=
nv04_dmaobj_ctor
,
.
dtor
=
_nvkm_dmaobj_dtor
,
.
init
=
_nvkm_dmaobj_init
,
.
fini
=
_nvkm_dmaobj_fini
,
};
static
struct
nouveau_oclass
nv04_dmaeng_sclass
[]
=
{
{
NV_DMA_FROM_MEMORY_CLASS
,
&
nv04_dmaobj_ofuncs
},
{
NV_DMA_TO_MEMORY_CLASS
,
&
nv04_dmaobj_ofuncs
},
{
NV_DMA_IN_MEMORY_CLASS
,
&
nv04_dmaobj_ofuncs
},
{}
};
struct
nouveau_oclass
*
nv04_dmaeng_oclass
=
&
(
struct
nvkm_dmaeng_impl
)
{
.
base
.
handle
=
NV_ENGINE
(
DMAOBJ
,
0x04
),
...
...
@@ -118,5 +160,6 @@ nv04_dmaeng_oclass = &(struct nvkm_dmaeng_impl) {
.
init
=
_nvkm_dmaeng_init
,
.
fini
=
_nvkm_dmaeng_fini
,
},
.
sclass
=
nv04_dmaeng_sclass
,
.
bind
=
nv04_dmaobj_bind
,
}.
base
;
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c
View file @
b2c81703
...
...
@@ -29,14 +29,18 @@
#include "priv.h"
struct
nv50_dmaobj_priv
{
struct
nouveau_dmaobj
base
;
u32
flags0
;
u32
flags5
;
};
static
int
nv50_dmaobj_bind
(
struct
nouveau_dma
eng
*
dmaeng
,
nv50_dmaobj_bind
(
struct
nouveau_dma
obj
*
dmaobj
,
struct
nouveau_object
*
parent
,
struct
nouveau_dmaobj
*
dmaobj
,
struct
nouveau_gpuobj
**
pgpuobj
)
{
u32
flags0
=
nv_mclass
(
dmaobj
);
u32
flags5
=
0x00000000
;
struct
nv50_dmaobj_priv
*
priv
=
(
void
*
)
dmaobj
;
int
ret
;
if
(
!
nv_iclass
(
parent
,
NV_ENGCTX_CLASS
))
{
...
...
@@ -66,68 +70,107 @@ nv50_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
}
}
if
(
!
(
dmaobj
->
conf0
&
NV50_DMA_CONF0_ENABLE
))
{
if
(
dmaobj
->
target
==
NV_MEM_TARGET_VM
)
{
dmaobj
->
conf0
=
NV50_DMA_CONF0_PRIV_VM
;
dmaobj
->
conf0
|=
NV50_DMA_CONF0_PART_VM
;
dmaobj
->
conf0
|=
NV50_DMA_CONF0_COMP_VM
;
dmaobj
->
conf0
|=
NV50_DMA_CONF0_TYPE_VM
;
ret
=
nouveau_gpuobj_new
(
parent
,
parent
,
24
,
32
,
0
,
pgpuobj
);
if
(
ret
==
0
)
{
nv_wo32
(
*
pgpuobj
,
0x00
,
priv
->
flags0
|
nv_mclass
(
dmaobj
));
nv_wo32
(
*
pgpuobj
,
0x04
,
lower_32_bits
(
priv
->
base
.
limit
));
nv_wo32
(
*
pgpuobj
,
0x08
,
lower_32_bits
(
priv
->
base
.
start
));
nv_wo32
(
*
pgpuobj
,
0x0c
,
upper_32_bits
(
priv
->
base
.
limit
)
<<
24
|
upper_32_bits
(
priv
->
base
.
start
));
nv_wo32
(
*
pgpuobj
,
0x10
,
0x00000000
);
nv_wo32
(
*
pgpuobj
,
0x14
,
priv
->
flags5
);
}
return
ret
;
}
static
int
nv50_dmaobj_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nouveau_dmaeng
*
dmaeng
=
(
void
*
)
engine
;
struct
nv50_dmaobj_priv
*
priv
;
union
{
u32
conf0
;
}
*
args
;
int
ret
;
ret
=
nvkm_dmaobj_create
(
parent
,
engine
,
oclass
,
&
data
,
&
size
,
&
priv
);
*
pobject
=
nv_object
(
priv
);
if
(
ret
)
return
ret
;
args
=
data
;
if
(
!
(
args
->
conf0
&
NV50_DMA_CONF0_ENABLE
))
{
if
(
priv
->
base
.
target
==
NV_MEM_TARGET_VM
)
{
args
->
conf0
=
NV50_DMA_CONF0_PRIV_VM
;
args
->
conf0
|=
NV50_DMA_CONF0_PART_VM
;
args
->
conf0
|=
NV50_DMA_CONF0_COMP_VM
;
args
->
conf0
|=
NV50_DMA_CONF0_TYPE_VM
;
}
else
{
dmaobj
->
conf0
=
NV50_DMA_CONF0_PRIV_US
;
dmaobj
->
conf0
|=
NV50_DMA_CONF0_PART_256
;
dmaobj
->
conf0
|=
NV50_DMA_CONF0_COMP_NONE
;
dmaobj
->
conf0
|=
NV50_DMA_CONF0_TYPE_LINEAR
;
args
->
conf0
=
NV50_DMA_CONF0_PRIV_US
;
args
->
conf0
|=
NV50_DMA_CONF0_PART_256
;
args
->
conf0
|=
NV50_DMA_CONF0_COMP_NONE
;
args
->
conf0
|=
NV50_DMA_CONF0_TYPE_LINEAR
;
}
}
flags0
|=
(
dmaobj
->
conf0
&
NV50_DMA_CONF0_COMP
)
<<
22
;
flags0
|=
(
dmaobj
->
conf0
&
NV50_DMA_CONF0_TYPE
)
<<
22
;
flags0
|=
(
dmaobj
->
conf0
&
NV50_DMA_CONF0_PRIV
);
flags5
|=
(
dmaobj
->
conf0
&
NV50_DMA_CONF0_PART
);
priv
->
flags0
|=
(
args
->
conf0
&
NV50_DMA_CONF0_COMP
)
<<
22
;
priv
->
flags0
|=
(
args
->
conf0
&
NV50_DMA_CONF0_TYPE
)
<<
22
;
priv
->
flags0
|=
(
args
->
conf0
&
NV50_DMA_CONF0_PRIV
);
priv
->
flags5
|=
(
args
->
conf0
&
NV50_DMA_CONF0_PART
);
switch
(
dmaobj
->
target
)
{
switch
(
priv
->
base
.
target
)
{
case
NV_MEM_TARGET_VM
:
flags0
|=
0x00000000
;
priv
->
flags0
|=
0x00000000
;
break
;
case
NV_MEM_TARGET_VRAM
:
flags0
|=
0x00010000
;
priv
->
flags0
|=
0x00010000
;
break
;
case
NV_MEM_TARGET_PCI
:
flags0
|=
0x00020000
;
priv
->
flags0
|=
0x00020000
;
break
;
case
NV_MEM_TARGET_PCI_NOSNOOP
:
flags0
|=
0x00030000
;
priv
->
flags0
|=
0x00030000
;
break
;
default:
return
-
EINVAL
;
}
switch
(
dmaobj
->
access
)
{
switch
(
priv
->
base
.
access
)
{
case
NV_MEM_ACCESS_VM
:
break
;
case
NV_MEM_ACCESS_RO
:
flags0
|=
0x00040000
;
priv
->
flags0
|=
0x00040000
;
break
;
case
NV_MEM_ACCESS_WO
:
case
NV_MEM_ACCESS_RW
:
flags0
|=
0x00080000
;
priv
->
flags0
|=
0x00080000
;
break
;
default:
return
-
EINVAL
;
}
ret
=
nouveau_gpuobj_new
(
parent
,
parent
,
24
,
32
,
0
,
pgpuobj
);
if
(
ret
==
0
)
{
nv_wo32
(
*
pgpuobj
,
0x00
,
flags0
);
nv_wo32
(
*
pgpuobj
,
0x04
,
lower_32_bits
(
dmaobj
->
limit
));
nv_wo32
(
*
pgpuobj
,
0x08
,
lower_32_bits
(
dmaobj
->
start
));
nv_wo32
(
*
pgpuobj
,
0x0c
,
upper_32_bits
(
dmaobj
->
limit
)
<<
24
|
upper_32_bits
(
dmaobj
->
start
));
nv_wo32
(
*
pgpuobj
,
0x10
,
0x00000000
);
nv_wo32
(
*
pgpuobj
,
0x14
,
flags5
);
}
return
ret
;
return
dmaeng
->
bind
(
&
priv
->
base
,
nv_object
(
priv
),
(
void
*
)
pobject
);
}
static
struct
nouveau_ofuncs
nv50_dmaobj_ofuncs
=
{
.
ctor
=
nv50_dmaobj_ctor
,
.
dtor
=
_nvkm_dmaobj_dtor
,
.
init
=
_nvkm_dmaobj_init
,
.
fini
=
_nvkm_dmaobj_fini
,
};
static
struct
nouveau_oclass
nv50_dmaeng_sclass
[]
=
{
{
NV_DMA_FROM_MEMORY_CLASS
,
&
nv50_dmaobj_ofuncs
},
{
NV_DMA_TO_MEMORY_CLASS
,
&
nv50_dmaobj_ofuncs
},
{
NV_DMA_IN_MEMORY_CLASS
,
&
nv50_dmaobj_ofuncs
},
{}
};
struct
nouveau_oclass
*
nv50_dmaeng_oclass
=
&
(
struct
nvkm_dmaeng_impl
)
{
.
base
.
handle
=
NV_ENGINE
(
DMAOBJ
,
0x50
),
...
...
@@ -137,5 +180,6 @@ nv50_dmaeng_oclass = &(struct nvkm_dmaeng_impl) {
.
init
=
_nvkm_dmaeng_init
,
.
fini
=
_nvkm_dmaeng_fini
,
},
.
sclass
=
nv50_dmaeng_sclass
,
.
bind
=
nv50_dmaobj_bind
,
}.
base
;
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c
View file @
b2c81703
...
...
@@ -30,14 +30,18 @@
#include "priv.h"
struct
nvc0_dmaobj_priv
{
struct
nouveau_dmaobj
base
;
u32
flags0
;
u32
flags5
;
};
static
int
nvc0_dmaobj_bind
(
struct
nouveau_dma
eng
*
dmaeng
,
nvc0_dmaobj_bind
(
struct
nouveau_dma
obj
*
dmaobj
,
struct
nouveau_object
*
parent
,
struct
nouveau_dmaobj
*
dmaobj
,
struct
nouveau_gpuobj
**
pgpuobj
)
{
u32
flags0
=
nv_mclass
(
dmaobj
);
u32
flags5
=
0x00000000
;
struct
nvc0_dmaobj_priv
*
priv
=
(
void
*
)
dmaobj
;
int
ret
;
if
(
!
nv_iclass
(
parent
,
NV_ENGCTX_CLASS
))
{
...
...
@@ -52,64 +56,101 @@ nvc0_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
}
else
return
0
;
if
(
!
(
dmaobj
->
conf0
&
NVC0_DMA_CONF0_ENABLE
))
{
if
(
dmaobj
->
target
==
NV_MEM_TARGET_VM
)
{
dmaobj
->
conf0
=
NVC0_DMA_CONF0_PRIV_VM
;
dmaobj
->
conf0
|=
NVC0_DMA_CONF0_TYPE_VM
;
ret
=
nouveau_gpuobj_new
(
parent
,
parent
,
24
,
32
,
0
,
pgpuobj
);
if
(
ret
==
0
)
{
nv_wo32
(
*
pgpuobj
,
0x00
,
priv
->
flags0
|
nv_mclass
(
dmaobj
));
nv_wo32
(
*
pgpuobj
,
0x04
,
lower_32_bits
(
priv
->
base
.
limit
));
nv_wo32
(
*
pgpuobj
,
0x08
,
lower_32_bits
(
priv
->
base
.
start
));
nv_wo32
(
*
pgpuobj
,
0x0c
,
upper_32_bits
(
priv
->
base
.
limit
)
<<
24
|
upper_32_bits
(
priv
->
base
.
start
));
nv_wo32
(
*
pgpuobj
,
0x10
,
0x00000000
);
nv_wo32
(
*
pgpuobj
,
0x14
,
priv
->
flags5
);
}
return
ret
;
}
static
int
nvc0_dmaobj_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nouveau_dmaeng
*
dmaeng
=
(
void
*
)
engine
;
struct
nvc0_dmaobj_priv
*
priv
;
union
{
u32
conf0
;
}
*
args
;
int
ret
;
ret
=
nvkm_dmaobj_create
(
parent
,
engine
,
oclass
,
&
data
,
&
size
,
&
priv
);
*
pobject
=
nv_object
(
priv
);
if
(
ret
)
return
ret
;
args
=
data
;
if
(
!
(
args
->
conf0
&
NVC0_DMA_CONF0_ENABLE
))
{
if
(
priv
->
base
.
target
==
NV_MEM_TARGET_VM
)
{
args
->
conf0
=
NVC0_DMA_CONF0_PRIV_VM
;
args
->
conf0
|=
NVC0_DMA_CONF0_TYPE_VM
;
}
else
{
dmaobj
->
conf0
=
NVC0_DMA_CONF0_PRIV_US
;
dmaobj
->
conf0
|=
NVC0_DMA_CONF0_TYPE_LINEAR
;
dmaobj
->
conf0
|=
0x00020000
;
args
->
conf0
=
NVC0_DMA_CONF0_PRIV_US
;
args
->
conf0
|=
NVC0_DMA_CONF0_TYPE_LINEAR
;
args
->
conf0
|=
0x00020000
;
}
}
flags0
|=
(
dmaobj
->
conf0
&
NVC0_DMA_CONF0_TYPE
)
<<
22
;
flags0
|=
(
dmaobj
->
conf0
&
NVC0_DMA_CONF0_PRIV
);
flags5
|=
(
dmaobj
->
conf0
&
NVC0_DMA_CONF0_UNKN
);
priv
->
flags0
|=
(
args
->
conf0
&
NVC0_DMA_CONF0_TYPE
)
<<
22
;
priv
->
flags0
|=
(
args
->
conf0
&
NVC0_DMA_CONF0_PRIV
);
priv
->
flags5
|=
(
args
->
conf0
&
NVC0_DMA_CONF0_UNKN
);
switch
(
dmaobj
->
target
)
{
switch
(
priv
->
base
.
target
)
{
case
NV_MEM_TARGET_VM
:
flags0
|=
0x00000000
;
priv
->
flags0
|=
0x00000000
;
break
;
case
NV_MEM_TARGET_VRAM
:
flags0
|=
0x00010000
;
priv
->
flags0
|=
0x00010000
;
break
;
case
NV_MEM_TARGET_PCI
:
flags0
|=
0x00020000
;
priv
->
flags0
|=
0x00020000
;
break
;
case
NV_MEM_TARGET_PCI_NOSNOOP
:
flags0
|=
0x00030000
;
priv
->
flags0
|=
0x00030000
;
break
;
default:
return
-
EINVAL
;
}
switch
(
dmaobj
->
access
)
{
switch
(
priv
->
base
.
access
)
{
case
NV_MEM_ACCESS_VM
:
break
;
case
NV_MEM_ACCESS_RO
:
flags0
|=
0x00040000
;
priv
->
flags0
|=
0x00040000
;
break
;
case
NV_MEM_ACCESS_WO
:
case
NV_MEM_ACCESS_RW
:
flags0
|=
0x00080000
;
priv
->
flags0
|=
0x00080000
;
break
;
}
ret
=
nouveau_gpuobj_new
(
parent
,
parent
,
24
,
32
,
0
,
pgpuobj
);
if
(
ret
==
0
)
{
nv_wo32
(
*
pgpuobj
,
0x00
,
flags0
);
nv_wo32
(
*
pgpuobj
,
0x04
,
lower_32_bits
(
dmaobj
->
limit
));
nv_wo32
(
*
pgpuobj
,
0x08
,
lower_32_bits
(
dmaobj
->
start
));
nv_wo32
(
*
pgpuobj
,
0x0c
,
upper_32_bits
(
dmaobj
->
limit
)
<<
24
|
upper_32_bits
(
dmaobj
->
start
));
nv_wo32
(
*
pgpuobj
,
0x10
,
0x00000000
);
nv_wo32
(
*
pgpuobj
,
0x14
,
flags5
);
}
return
ret
;
return
dmaeng
->
bind
(
&
priv
->
base
,
nv_object
(
priv
),
(
void
*
)
pobject
);
}
static
struct
nouveau_ofuncs
nvc0_dmaobj_ofuncs
=
{
.
ctor
=
nvc0_dmaobj_ctor
,
.
dtor
=
_nvkm_dmaobj_dtor
,
.
init
=
_nvkm_dmaobj_init
,
.
fini
=
_nvkm_dmaobj_fini
,
};
static
struct
nouveau_oclass
nvc0_dmaeng_sclass
[]
=
{
{
NV_DMA_FROM_MEMORY_CLASS
,
&
nvc0_dmaobj_ofuncs
},
{
NV_DMA_TO_MEMORY_CLASS
,
&
nvc0_dmaobj_ofuncs
},
{
NV_DMA_IN_MEMORY_CLASS
,
&
nvc0_dmaobj_ofuncs
},
{}
};
struct
nouveau_oclass
*
nvc0_dmaeng_oclass
=
&
(
struct
nvkm_dmaeng_impl
)
{
.
base
.
handle
=
NV_ENGINE
(
DMAOBJ
,
0xc0
),
...
...
@@ -119,5 +160,6 @@ nvc0_dmaeng_oclass = &(struct nvkm_dmaeng_impl) {
.
init
=
_nvkm_dmaeng_init
,
.
fini
=
_nvkm_dmaeng_fini
,
},
.
sclass
=
nvc0_dmaeng_sclass
,
.
bind
=
nvc0_dmaobj_bind
,
}.
base
;
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
View file @
b2c81703
...
...
@@ -30,17 +30,17 @@
#include "priv.h"
struct
nvd0_dmaeng_priv
{
struct
nouveau_dmaeng
base
;
struct
nvd0_dmaobj_priv
{
struct
nouveau_dmaobj
base
;
u32
flags0
;
};
static
int
nvd0_dmaobj_bind
(
struct
nouveau_dma
eng
*
dmaeng
,
nvd0_dmaobj_bind
(
struct
nouveau_dma
obj
*
dmaobj
,
struct
nouveau_object
*
parent
,
struct
nouveau_dmaobj
*
dmaobj
,
struct
nouveau_gpuobj
**
pgpuobj
)
{
u32
flags0
=
0x00000000
;
struct
nvd0_dmaobj_priv
*
priv
=
(
void
*
)
dmaobj
;
int
ret
;
if
(
!
nv_iclass
(
parent
,
NV_ENGCTX_CLASS
))
{
...
...
@@ -64,41 +64,86 @@ nvd0_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
}
else
return
0
;
if
(
!
(
dmaobj
->
conf0
&
NVD0_DMA_CONF0_ENABLE
))
{
if
(
dmaobj
->
target
==
NV_MEM_TARGET_VM
)
{
dmaobj
->
conf0
|=
NVD0_DMA_CONF0_TYPE_VM
;
dmaobj
->
conf0
|=
NVD0_DMA_CONF0_PAGE_LP
;
ret
=
nouveau_gpuobj_new
(
parent
,
parent
,
24
,
32
,
0
,
pgpuobj
);
if
(
ret
==
0
)
{
nv_wo32
(
*
pgpuobj
,
0x00
,
priv
->
flags0
);
nv_wo32
(
*
pgpuobj
,
0x04
,
priv
->
base
.
start
>>
8
);
nv_wo32
(
*
pgpuobj
,
0x08
,
priv
->
base
.
limit
>>
8
);
nv_wo32
(
*
pgpuobj
,
0x0c
,
0x00000000
);
nv_wo32
(
*
pgpuobj
,
0x10
,
0x00000000
);
nv_wo32
(
*
pgpuobj
,
0x14
,
0x00000000
);
}
return
ret
;
}
static
int
nvd0_dmaobj_ctor
(
struct
nouveau_object
*
parent
,
struct
nouveau_object
*
engine
,
struct
nouveau_oclass
*
oclass
,
void
*
data
,
u32
size
,
struct
nouveau_object
**
pobject
)
{
struct
nouveau_dmaeng
*
dmaeng
=
(
void
*
)
engine
;
struct
nvd0_dmaobj_priv
*
priv
;
union
{
u32
conf0
;
}
*
args
;
int
ret
;
ret
=
nvkm_dmaobj_create
(
parent
,
engine
,
oclass
,
&
data
,
&
size
,
&
priv
);
*
pobject
=
nv_object
(
priv
);
if
(
ret
)
return
ret
;
args
=
data
;
if
(
!
(
args
->
conf0
&
NVD0_DMA_CONF0_ENABLE
))
{
if
(
priv
->
base
.
target
==
NV_MEM_TARGET_VM
)
{
args
->
conf0
|=
NVD0_DMA_CONF0_TYPE_VM
;
args
->
conf0
|=
NVD0_DMA_CONF0_PAGE_LP
;
}
else
{
dmaobj
->
conf0
|=
NVD0_DMA_CONF0_TYPE_LINEAR
;
dmaobj
->
conf0
|=
NVD0_DMA_CONF0_PAGE_SP
;
args
->
conf0
|=
NVD0_DMA_CONF0_TYPE_LINEAR
;
args
->
conf0
|=
NVD0_DMA_CONF0_PAGE_SP
;
}
}
flags0
|=
(
dmaobj
->
conf0
&
NVD0_DMA_CONF0_TYPE
)
<<
20
;
flags0
|=
(
dmaobj
->
conf0
&
NVD0_DMA_CONF0_PAGE
)
>>
4
;
priv
->
flags0
|=
(
args
->
conf0
&
NVD0_DMA_CONF0_TYPE
)
<<
20
;
priv
->
flags0
|=
(
args
->
conf0
&
NVD0_DMA_CONF0_PAGE
)
>>
4
;
switch
(
dmaobj
->
target
)
{
switch
(
priv
->
base
.
target
)
{
case
NV_MEM_TARGET_VRAM
:
flags0
|=
0x00000009
;
priv
->
flags0
|=
0x00000009
;
break
;
case
NV_MEM_TARGET_VM
:
case
NV_MEM_TARGET_PCI
:
case
NV_MEM_TARGET_PCI_NOSNOOP
:
/* XXX: don't currently know how to construct a real one
* of these. we only use them to represent pushbufs
* on these chipsets, and the classes that use them
* deal with the target themselves.
*/
break
;
default:
return
-
EINVAL
;
break
;
}
ret
=
nouveau_gpuobj_new
(
parent
,
parent
,
24
,
32
,
0
,
pgpuobj
);
if
(
ret
==
0
)
{
nv_wo32
(
*
pgpuobj
,
0x00
,
flags0
);
nv_wo32
(
*
pgpuobj
,
0x04
,
dmaobj
->
start
>>
8
);
nv_wo32
(
*
pgpuobj
,
0x08
,
dmaobj
->
limit
>>
8
);
nv_wo32
(
*
pgpuobj
,
0x0c
,
0x00000000
);
nv_wo32
(
*
pgpuobj
,
0x10
,
0x00000000
);
nv_wo32
(
*
pgpuobj
,
0x14
,
0x00000000
);
}
return
ret
;
return
dmaeng
->
bind
(
&
priv
->
base
,
nv_object
(
priv
),
(
void
*
)
pobject
)
;
}
static
struct
nouveau_ofuncs
nvd0_dmaobj_ofuncs
=
{
.
ctor
=
nvd0_dmaobj_ctor
,
.
dtor
=
_nvkm_dmaobj_dtor
,
.
init
=
_nvkm_dmaobj_init
,
.
fini
=
_nvkm_dmaobj_fini
,
};
static
struct
nouveau_oclass
nvd0_dmaeng_sclass
[]
=
{
{
NV_DMA_FROM_MEMORY_CLASS
,
&
nvd0_dmaobj_ofuncs
},
{
NV_DMA_TO_MEMORY_CLASS
,
&
nvd0_dmaobj_ofuncs
},
{
NV_DMA_IN_MEMORY_CLASS
,
&
nvd0_dmaobj_ofuncs
},
{}
};
struct
nouveau_oclass
*
nvd0_dmaeng_oclass
=
&
(
struct
nvkm_dmaeng_impl
)
{
.
base
.
handle
=
NV_ENGINE
(
DMAOBJ
,
0xd0
),
...
...
@@ -108,5 +153,6 @@ nvd0_dmaeng_oclass = &(struct nvkm_dmaeng_impl) {
.
init
=
_nvkm_dmaeng_init
,
.
fini
=
_nvkm_dmaeng_fini
,
},
.
sclass
=
nvd0_dmaeng_sclass
,
.
bind
=
nvd0_dmaobj_bind
,
}.
base
;
drivers/gpu/drm/nouveau/core/engine/dmaobj/priv.h
View file @
b2c81703
...
...
@@ -3,6 +3,16 @@
#include <engine/dmaobj.h>
#define nvkm_dmaobj_create(p,e,c,pa,sa,d) \
nvkm_dmaobj_create_((p), (e), (c), (pa), (sa), sizeof(**d), (void **)d)
int
nvkm_dmaobj_create_
(
struct
nouveau_object
*
,
struct
nouveau_object
*
,
struct
nouveau_oclass
*
,
void
**
,
u32
*
,
int
,
void
**
);
#define _nvkm_dmaobj_dtor nouveau_object_destroy
#define _nvkm_dmaobj_init nouveau_object_init
#define _nvkm_dmaobj_fini nouveau_object_fini
int
_nvkm_dmaeng_ctor
(
struct
nouveau_object
*
,
struct
nouveau_object
*
,
struct
nouveau_oclass
*
,
void
*
,
u32
,
struct
nouveau_object
**
);
...
...
@@ -12,8 +22,9 @@ int _nvkm_dmaeng_ctor(struct nouveau_object *, struct nouveau_object *,
struct
nvkm_dmaeng_impl
{
struct
nouveau_oclass
base
;
int
(
*
bind
)(
struct
nouveau_dmaeng
*
,
struct
nouveau_object
*
,
struct
nouveau_dmaobj
*
,
struct
nouveau_gpuobj
**
);
struct
nouveau_oclass
*
sclass
;
int
(
*
bind
)(
struct
nouveau_dmaobj
*
,
struct
nouveau_object
*
,
struct
nouveau_gpuobj
**
);
};
#endif
drivers/gpu/drm/nouveau/core/engine/fifo/base.c
View file @
b2c81703
...
...
@@ -83,7 +83,7 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent,
return
-
EINVAL
;
}
ret
=
dmaeng
->
bind
(
dmaeng
,
parent
,
chan
->
pushdma
,
&
chan
->
pushgpu
);
ret
=
dmaeng
->
bind
(
chan
->
pushdma
,
parent
,
&
chan
->
pushgpu
);
if
(
ret
)
return
ret
;
...
...
drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h
View file @
b2c81703
...
...
@@ -19,9 +19,8 @@ struct nouveau_dmaeng {
struct
nouveau_engine
base
;
/* creates a "physical" dma object from a struct nouveau_dmaobj */
int
(
*
bind
)(
struct
nouveau_dma
eng
*
dmaeng
,
int
(
*
bind
)(
struct
nouveau_dma
obj
*
dmaobj
,
struct
nouveau_object
*
parent
,
struct
nouveau_dmaobj
*
dmaobj
,
struct
nouveau_gpuobj
**
);
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment