Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
dcd6dfcf
Commit
dcd6dfcf
authored
Dec 18, 2009
by
Dave Airlie
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'drm-linus' into drm-core-next
parents
cbc8cc04
d785d78b
Changes
26
Show whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1065 additions
and
66 deletions
+1065
-66
drivers/gpu/drm/nouveau/Kconfig
drivers/gpu/drm/nouveau/Kconfig
+3
-2
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_bo.c
+2
-0
drivers/gpu/drm/nouveau/nouveau_fence.c
drivers/gpu/drm/nouveau/nouveau_fence.c
+1
-1
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_gem.c
+0
-7
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_mem.c
+4
-0
drivers/gpu/drm/nouveau/nv40_graph.c
drivers/gpu/drm/nouveau/nv40_graph.c
+12
-8
drivers/gpu/drm/radeon/Makefile
drivers/gpu/drm/radeon/Makefile
+1
-1
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r100.c
+50
-4
drivers/gpu/drm/radeon/r100_track.h
drivers/gpu/drm/radeon/r100_track.h
+5
-0
drivers/gpu/drm/radeon/r200.c
drivers/gpu/drm/radeon/r200.c
+8
-2
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r300.c
+20
-4
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600.c
+13
-6
drivers/gpu/drm/radeon/r600_audio.c
drivers/gpu/drm/radeon/r600_audio.c
+267
-0
drivers/gpu/drm/radeon/r600_hdmi.c
drivers/gpu/drm/radeon/r600_hdmi.c
+506
-0
drivers/gpu/drm/radeon/r600_reg.h
drivers/gpu/drm/radeon/r600_reg.h
+74
-0
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon.h
+25
-0
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_drv.c
+4
-0
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_encoders.c
+11
-5
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_gem.c
+5
-3
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_mode.h
+3
-0
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_object.c
+18
-3
drivers/gpu/drm/radeon/radeon_object.h
drivers/gpu/drm/radeon/radeon_object.h
+5
-11
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/radeon_pm.c
+5
-2
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/radeon_ttm.c
+13
-1
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs400.c
+2
-0
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/rv770.c
+8
-6
No files found.
drivers/gpu/drm/nouveau/Kconfig
View file @
dcd6dfcf
...
...
@@ -30,11 +30,12 @@ config DRM_NOUVEAU_DEBUG
via debugfs.
menu "I2C encoder or helper chips"
depends on DRM
depends on DRM
&& I2C
config DRM_I2C_CH7006
tristate "Chrontel ch7006 TV encoder"
default m if DRM_NOUVEAU
depends on DRM_NOUVEAU
default m
help
Support for Chrontel ch7006 and similar TV encoders, found
on some nVidia video cards.
...
...
drivers/gpu/drm/nouveau/nouveau_bo.c
View file @
dcd6dfcf
...
...
@@ -311,8 +311,10 @@ nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev)
struct
drm_device
*
dev
=
dev_priv
->
dev
;
switch
(
dev_priv
->
gart_info
.
type
)
{
#if __OS_HAS_AGP
case
NOUVEAU_GART_AGP
:
return
ttm_agp_backend_init
(
bdev
,
dev
->
agp
->
bridge
);
#endif
case
NOUVEAU_GART_SGDMA
:
return
nouveau_sgdma_init_ttm
(
dev
);
default:
...
...
drivers/gpu/drm/nouveau/nouveau_fence.c
View file @
dcd6dfcf
...
...
@@ -205,7 +205,7 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
schedule_timeout
(
1
);
if
(
intr
&&
signal_pending
(
current
))
{
ret
=
-
ERESTART
;
ret
=
-
ERESTART
SYS
;
break
;
}
}
...
...
drivers/gpu/drm/nouveau/nouveau_gem.c
View file @
dcd6dfcf
...
...
@@ -342,8 +342,6 @@ retry:
}
ret
=
ttm_bo_wait_cpu
(
&
nvbo
->
bo
,
false
);
if
(
ret
==
-
ERESTART
)
ret
=
-
EAGAIN
;
if
(
ret
)
return
ret
;
goto
retry
;
...
...
@@ -915,8 +913,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
goto
out
;
ret
=
ttm_bo_wait_cpu
(
&
nvbo
->
bo
,
no_wait
);
if
(
ret
==
-
ERESTART
)
ret
=
-
EAGAIN
;
if
(
ret
)
goto
out
;
}
...
...
@@ -925,9 +921,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
ret
=
ttm_bo_wait
(
&
nvbo
->
bo
,
false
,
false
,
no_wait
);
}
else
{
ret
=
ttm_bo_synccpu_write_grab
(
&
nvbo
->
bo
,
no_wait
);
if
(
ret
==
-
ERESTART
)
ret
=
-
EAGAIN
;
else
if
(
ret
==
0
)
nvbo
->
cpu_filp
=
file_priv
;
}
...
...
drivers/gpu/drm/nouveau/nouveau_mem.c
View file @
dcd6dfcf
...
...
@@ -407,6 +407,7 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
return
0
;
}
#if __OS_HAS_AGP
static
void
nouveau_mem_reset_agp
(
struct
drm_device
*
dev
)
{
uint32_t
saved_pci_nv_1
,
saved_pci_nv_19
,
pmc_enable
;
...
...
@@ -432,10 +433,12 @@ static void nouveau_mem_reset_agp(struct drm_device *dev)
nv_wr32
(
dev
,
NV04_PBUS_PCI_NV_19
,
saved_pci_nv_19
);
nv_wr32
(
dev
,
NV04_PBUS_PCI_NV_1
,
saved_pci_nv_1
);
}
#endif
int
nouveau_mem_init_agp
(
struct
drm_device
*
dev
)
{
#if __OS_HAS_AGP
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
struct
drm_agp_info
info
;
struct
drm_agp_mode
mode
;
...
...
@@ -471,6 +474,7 @@ nouveau_mem_init_agp(struct drm_device *dev)
dev_priv
->
gart_info
.
type
=
NOUVEAU_GART_AGP
;
dev_priv
->
gart_info
.
aper_base
=
info
.
aperture_base
;
dev_priv
->
gart_info
.
aper_size
=
info
.
aperture_size
;
#endif
return
0
;
}
...
...
drivers/gpu/drm/nouveau/nv40_graph.c
View file @
dcd6dfcf
...
...
@@ -252,8 +252,9 @@ nv40_grctx_init(struct drm_device *dev)
memcpy
(
pgraph
->
ctxprog
,
fw
->
data
,
fw
->
size
);
cp
=
pgraph
->
ctxprog
;
if
(
cp
->
signature
!=
0x5043564e
||
cp
->
version
!=
0
||
cp
->
length
!=
((
fw
->
size
-
7
)
/
4
))
{
if
(
le32_to_cpu
(
cp
->
signature
)
!=
0x5043564e
||
cp
->
version
!=
0
||
le16_to_cpu
(
cp
->
length
)
!=
((
fw
->
size
-
7
)
/
4
))
{
NV_ERROR
(
dev
,
"ctxprog invalid
\n
"
);
release_firmware
(
fw
);
nv40_grctx_fini
(
dev
);
...
...
@@ -281,8 +282,9 @@ nv40_grctx_init(struct drm_device *dev)
memcpy
(
pgraph
->
ctxvals
,
fw
->
data
,
fw
->
size
);
cv
=
(
void
*
)
pgraph
->
ctxvals
;
if
(
cv
->
signature
!=
0x5643564e
||
cv
->
version
!=
0
||
cv
->
length
!=
((
fw
->
size
-
9
)
/
8
))
{
if
(
le32_to_cpu
(
cv
->
signature
)
!=
0x5643564e
||
cv
->
version
!=
0
||
le32_to_cpu
(
cv
->
length
)
!=
((
fw
->
size
-
9
)
/
8
))
{
NV_ERROR
(
dev
,
"ctxvals invalid
\n
"
);
release_firmware
(
fw
);
nv40_grctx_fini
(
dev
);
...
...
@@ -294,8 +296,9 @@ nv40_grctx_init(struct drm_device *dev)
cp
=
pgraph
->
ctxprog
;
nv_wr32
(
dev
,
NV40_PGRAPH_CTXCTL_UCODE_INDEX
,
0
);
for
(
i
=
0
;
i
<
cp
->
length
;
i
++
)
nv_wr32
(
dev
,
NV40_PGRAPH_CTXCTL_UCODE_DATA
,
cp
->
data
[
i
]);
for
(
i
=
0
;
i
<
le16_to_cpu
(
cp
->
length
);
i
++
)
nv_wr32
(
dev
,
NV40_PGRAPH_CTXCTL_UCODE_DATA
,
le32_to_cpu
(
cp
->
data
[
i
]));
pgraph
->
accel_blocked
=
false
;
return
0
;
...
...
@@ -329,8 +332,9 @@ nv40_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
if
(
!
cv
)
return
;
for
(
i
=
0
;
i
<
cv
->
length
;
i
++
)
nv_wo32
(
dev
,
ctx
,
cv
->
data
[
i
].
offset
,
cv
->
data
[
i
].
value
);
for
(
i
=
0
;
i
<
le32_to_cpu
(
cv
->
length
);
i
++
)
nv_wo32
(
dev
,
ctx
,
le32_to_cpu
(
cv
->
data
[
i
].
offset
),
le32_to_cpu
(
cv
->
data
[
i
].
value
));
}
/*
...
...
drivers/gpu/drm/radeon/Makefile
View file @
dcd6dfcf
...
...
@@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_kms.o \
radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o
\
rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o
\
r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o
\
r600_blit_kms.o radeon_pm.o atombios_dp.o
r600_blit_kms.o radeon_pm.o atombios_dp.o
r600_audio.o r600_hdmi.o
radeon-$(CONFIG_COMPAT)
+=
radeon_ioc32.o
...
...
drivers/gpu/drm/radeon/r100.c
View file @
dcd6dfcf
...
...
@@ -1374,7 +1374,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
case
RADEON_TXFORMAT_ARGB4444
:
case
RADEON_TXFORMAT_VYUY422
:
case
RADEON_TXFORMAT_YVYU422
:
case
RADEON_TXFORMAT_DXT1
:
case
RADEON_TXFORMAT_SHADOW16
:
case
RADEON_TXFORMAT_LDUDV655
:
case
RADEON_TXFORMAT_DUDV88
:
...
...
@@ -1382,12 +1381,19 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
break
;
case
RADEON_TXFORMAT_ARGB8888
:
case
RADEON_TXFORMAT_RGBA8888
:
case
RADEON_TXFORMAT_DXT23
:
case
RADEON_TXFORMAT_DXT45
:
case
RADEON_TXFORMAT_SHADOW32
:
case
RADEON_TXFORMAT_LDUDUV8888
:
track
->
textures
[
i
].
cpp
=
4
;
break
;
case
RADEON_TXFORMAT_DXT1
:
track
->
textures
[
i
].
cpp
=
1
;
track
->
textures
[
i
].
compress_format
=
R100_TRACK_COMP_DXT1
;
break
;
case
RADEON_TXFORMAT_DXT23
:
case
RADEON_TXFORMAT_DXT45
:
track
->
textures
[
i
].
cpp
=
1
;
track
->
textures
[
i
].
compress_format
=
R100_TRACK_COMP_DXT35
;
break
;
}
track
->
textures
[
i
].
cube_info
[
4
].
width
=
1
<<
((
idx_value
>>
16
)
&
0xf
);
track
->
textures
[
i
].
cube_info
[
4
].
height
=
1
<<
((
idx_value
>>
20
)
&
0xf
);
...
...
@@ -2731,6 +2737,7 @@ static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
DRM_ERROR
(
"coordinate type %d
\n
"
,
t
->
tex_coord_type
);
DRM_ERROR
(
"width round to power of 2 %d
\n
"
,
t
->
roundup_w
);
DRM_ERROR
(
"height round to power of 2 %d
\n
"
,
t
->
roundup_h
);
DRM_ERROR
(
"compress format %d
\n
"
,
t
->
compress_format
);
}
static
int
r100_cs_track_cube
(
struct
radeon_device
*
rdev
,
...
...
@@ -2760,6 +2767,36 @@ static int r100_cs_track_cube(struct radeon_device *rdev,
return
0
;
}
static
int
r100_track_compress_size
(
int
compress_format
,
int
w
,
int
h
)
{
int
block_width
,
block_height
,
block_bytes
;
int
wblocks
,
hblocks
;
int
min_wblocks
;
int
sz
;
block_width
=
4
;
block_height
=
4
;
switch
(
compress_format
)
{
case
R100_TRACK_COMP_DXT1
:
block_bytes
=
8
;
min_wblocks
=
4
;
break
;
default:
case
R100_TRACK_COMP_DXT35
:
block_bytes
=
16
;
min_wblocks
=
2
;
break
;
}
hblocks
=
(
h
+
block_height
-
1
)
/
block_height
;
wblocks
=
(
w
+
block_width
-
1
)
/
block_width
;
if
(
wblocks
<
min_wblocks
)
wblocks
=
min_wblocks
;
sz
=
wblocks
*
hblocks
*
block_bytes
;
return
sz
;
}
static
int
r100_cs_track_texture_check
(
struct
radeon_device
*
rdev
,
struct
r100_cs_track
*
track
)
{
...
...
@@ -2797,9 +2834,15 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
h
=
h
/
(
1
<<
i
);
if
(
track
->
textures
[
u
].
roundup_h
)
h
=
roundup_pow_of_two
(
h
);
if
(
track
->
textures
[
u
].
compress_format
)
{
size
+=
r100_track_compress_size
(
track
->
textures
[
u
].
compress_format
,
w
,
h
);
/* compressed textures are block based */
}
else
size
+=
w
*
h
;
}
size
*=
track
->
textures
[
u
].
cpp
;
switch
(
track
->
textures
[
u
].
tex_coord_type
)
{
case
0
:
break
;
...
...
@@ -2967,6 +3010,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
track
->
arrays
[
i
].
esize
=
0x7F
;
}
for
(
i
=
0
;
i
<
track
->
num_texture
;
i
++
)
{
track
->
textures
[
i
].
compress_format
=
R100_TRACK_COMP_NONE
;
track
->
textures
[
i
].
pitch
=
16536
;
track
->
textures
[
i
].
width
=
16536
;
track
->
textures
[
i
].
height
=
16536
;
...
...
@@ -3399,6 +3443,8 @@ int r100_init(struct radeon_device *rdev)
r100_errata
(
rdev
);
/* Initialize clocks */
radeon_get_clock_info
(
rdev
->
ddev
);
/* Initialize power management */
radeon_pm_init
(
rdev
);
/* Get vram informations */
r100_vram_info
(
rdev
);
/* Initialize memory controller (also test AGP) */
...
...
drivers/gpu/drm/radeon/r100_track.h
View file @
dcd6dfcf
...
...
@@ -28,6 +28,10 @@ struct r100_cs_cube_info {
unsigned
height
;
};
#define R100_TRACK_COMP_NONE 0
#define R100_TRACK_COMP_DXT1 1
#define R100_TRACK_COMP_DXT35 2
struct
r100_cs_track_texture
{
struct
radeon_bo
*
robj
;
struct
r100_cs_cube_info
cube_info
[
5
];
/* info for 5 non-primary faces */
...
...
@@ -44,6 +48,7 @@ struct r100_cs_track_texture {
bool
enabled
;
bool
roundup_w
;
bool
roundup_h
;
unsigned
compress_format
;
};
struct
r100_cs_track_limits
{
...
...
drivers/gpu/drm/radeon/r200.c
View file @
dcd6dfcf
...
...
@@ -401,7 +401,6 @@ int r200_packet0_check(struct radeon_cs_parser *p,
case
R200_TXFORMAT_Y8
:
track
->
textures
[
i
].
cpp
=
1
;
break
;
case
R200_TXFORMAT_DXT1
:
case
R200_TXFORMAT_AI88
:
case
R200_TXFORMAT_ARGB1555
:
case
R200_TXFORMAT_RGB565
:
...
...
@@ -418,9 +417,16 @@ int r200_packet0_check(struct radeon_cs_parser *p,
case
R200_TXFORMAT_ABGR8888
:
case
R200_TXFORMAT_BGR111110
:
case
R200_TXFORMAT_LDVDU8888
:
track
->
textures
[
i
].
cpp
=
4
;
break
;
case
R200_TXFORMAT_DXT1
:
track
->
textures
[
i
].
cpp
=
1
;
track
->
textures
[
i
].
compress_format
=
R100_TRACK_COMP_DXT1
;
break
;
case
R200_TXFORMAT_DXT23
:
case
R200_TXFORMAT_DXT45
:
track
->
textures
[
i
].
cpp
=
4
;
track
->
textures
[
i
].
cpp
=
1
;
track
->
textures
[
i
].
compress_format
=
R100_TRACK_COMP_DXT1
;
break
;
}
track
->
textures
[
i
].
cube_info
[
4
].
width
=
1
<<
((
idx_value
>>
16
)
&
0xf
);
...
...
drivers/gpu/drm/radeon/r300.c
View file @
dcd6dfcf
...
...
@@ -686,7 +686,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
r100_cs_dump_packet
(
p
,
pkt
);
return
r
;
}
ib
[
idx
]
=
idx_value
+
((
u32
)
reloc
->
lobj
.
gpu_offset
);
if
(
reloc
->
lobj
.
tiling_flags
&
RADEON_TILING_MACRO
)
tile_flags
|=
R300_TXO_MACRO_TILE
;
if
(
reloc
->
lobj
.
tiling_flags
&
RADEON_TILING_MICRO
)
tile_flags
|=
R300_TXO_MICRO_TILE
;
tmp
=
idx_value
+
((
u32
)
reloc
->
lobj
.
gpu_offset
);
tmp
|=
tile_flags
;
ib
[
idx
]
=
tmp
;
track
->
textures
[
i
].
robj
=
reloc
->
robj
;
break
;
/* Tracked registers */
...
...
@@ -852,7 +860,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
case
R300_TX_FORMAT_Z6Y5X5
:
case
R300_TX_FORMAT_W4Z4Y4X4
:
case
R300_TX_FORMAT_W1Z5Y5X5
:
case
R300_TX_FORMAT_DXT1
:
case
R300_TX_FORMAT_D3DMFT_CxV8U8
:
case
R300_TX_FORMAT_B8G8_B8G8
:
case
R300_TX_FORMAT_G8R8_G8B8
:
...
...
@@ -866,8 +873,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
case
0x17
:
case
R300_TX_FORMAT_FL_I32
:
case
0x1e
:
case
R300_TX_FORMAT_DXT3
:
case
R300_TX_FORMAT_DXT5
:
track
->
textures
[
i
].
cpp
=
4
;
break
;
case
R300_TX_FORMAT_W16Z16Y16X16
:
...
...
@@ -878,6 +883,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
case
R300_TX_FORMAT_FL_R32G32B32A32
:
track
->
textures
[
i
].
cpp
=
16
;
break
;
case
R300_TX_FORMAT_DXT1
:
track
->
textures
[
i
].
cpp
=
1
;
track
->
textures
[
i
].
compress_format
=
R100_TRACK_COMP_DXT1
;
break
;
case
R300_TX_FORMAT_DXT3
:
case
R300_TX_FORMAT_DXT5
:
track
->
textures
[
i
].
cpp
=
1
;
track
->
textures
[
i
].
compress_format
=
R100_TRACK_COMP_DXT35
;
break
;
default:
DRM_ERROR
(
"Invalid texture format %u
\n
"
,
(
idx_value
&
0x1F
));
...
...
@@ -1324,6 +1338,8 @@ int r300_init(struct radeon_device *rdev)
r300_errata
(
rdev
);
/* Initialize clocks */
radeon_get_clock_info
(
rdev
->
ddev
);
/* Initialize power management */
radeon_pm_init
(
rdev
);
/* Get vram informations */
r300_vram_info
(
rdev
);
/* Initialize memory controller (also test AGP) */
...
...
drivers/gpu/drm/radeon/r600.c
View file @
dcd6dfcf
...
...
@@ -1863,6 +1863,14 @@ int r600_startup(struct radeon_device *rdev)
}
r600_gpu_init
(
rdev
);
if
(
!
rdev
->
r600_blit
.
shader_obj
)
{
r
=
r600_blit_init
(
rdev
);
if
(
r
)
{
DRM_ERROR
(
"radeon: failed blitter (%d).
\n
"
,
r
);
return
r
;
}
}
r
=
radeon_bo_reserve
(
rdev
->
r600_blit
.
shader_obj
,
false
);
if
(
unlikely
(
r
!=
0
))
return
r
;
...
...
@@ -2038,12 +2046,6 @@ int r600_init(struct radeon_device *rdev)
if
(
r
)
return
r
;
r
=
r600_blit_init
(
rdev
);
if
(
r
)
{
DRM_ERROR
(
"radeon: failed blitter (%d).
\n
"
,
r
);
return
r
;
}
rdev
->
accel_working
=
true
;
r
=
r600_startup
(
rdev
);
if
(
r
)
{
...
...
@@ -2065,6 +2067,10 @@ int r600_init(struct radeon_device *rdev)
rdev
->
accel_working
=
false
;
}
}
r
=
r600_audio_init
(
rdev
);
if
(
r
)
return
r
;
/* TODO error handling */
return
0
;
}
...
...
@@ -2073,6 +2079,7 @@ void r600_fini(struct radeon_device *rdev)
/* Suspend operations */
r600_suspend
(
rdev
);
r600_audio_fini
(
rdev
);
r600_blit_fini
(
rdev
);
r600_irq_fini
(
rdev
);
radeon_irq_kms_fini
(
rdev
);
...
...
drivers/gpu/drm/radeon/r600_audio.c
0 → 100644
View file @
dcd6dfcf
/*
* Copyright 2008 Advanced Micro Devices, Inc.
* Copyright 2008 Red Hat Inc.
* Copyright 2009 Christian König.
*
* 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: Christian König
*/
#include "drmP.h"
#include "radeon.h"
#include "radeon_reg.h"
#include "atom.h"
#define AUDIO_TIMER_INTERVALL 100
/* 1/10 sekund should be enough */
/*
* check if the chipset is supported
*/
static
int
r600_audio_chipset_supported
(
struct
radeon_device
*
rdev
)
{
return
rdev
->
family
>=
CHIP_R600
||
rdev
->
family
==
CHIP_RS600
||
rdev
->
family
==
CHIP_RS690
||
rdev
->
family
==
CHIP_RS740
;
}
/*
* current number of channels
*/
static
int
r600_audio_channels
(
struct
radeon_device
*
rdev
)
{
return
(
RREG32
(
R600_AUDIO_RATE_BPS_CHANNEL
)
&
0x7
)
+
1
;
}
/*
* current bits per sample
*/
static
int
r600_audio_bits_per_sample
(
struct
radeon_device
*
rdev
)
{
uint32_t
value
=
(
RREG32
(
R600_AUDIO_RATE_BPS_CHANNEL
)
&
0xF0
)
>>
4
;
switch
(
value
)
{
case
0x0
:
return
8
;
case
0x1
:
return
16
;
case
0x2
:
return
20
;
case
0x3
:
return
24
;
case
0x4
:
return
32
;
}
DRM_ERROR
(
"Unknown bits per sample 0x%x using 16 instead.
\n
"
,
(
int
)
value
);
return
16
;
}
/*
* current sampling rate in HZ
*/
static
int
r600_audio_rate
(
struct
radeon_device
*
rdev
)
{
uint32_t
value
=
RREG32
(
R600_AUDIO_RATE_BPS_CHANNEL
);
uint32_t
result
;
if
(
value
&
0x4000
)
result
=
44100
;
else
result
=
48000
;
result
*=
((
value
>>
11
)
&
0x7
)
+
1
;
result
/=
((
value
>>
8
)
&
0x7
)
+
1
;
return
result
;
}
/*
* iec 60958 status bits
*/
static
uint8_t
r600_audio_status_bits
(
struct
radeon_device
*
rdev
)
{
return
RREG32
(
R600_AUDIO_STATUS_BITS
)
&
0xff
;
}
/*
* iec 60958 category code
*/
static
uint8_t
r600_audio_category_code
(
struct
radeon_device
*
rdev
)
{
return
(
RREG32
(
R600_AUDIO_STATUS_BITS
)
>>
8
)
&
0xff
;
}
/*
* update all hdmi interfaces with current audio parameters
*/
static
void
r600_audio_update_hdmi
(
unsigned
long
param
)
{
struct
radeon_device
*
rdev
=
(
struct
radeon_device
*
)
param
;
struct
drm_device
*
dev
=
rdev
->
ddev
;
int
channels
=
r600_audio_channels
(
rdev
);
int
rate
=
r600_audio_rate
(
rdev
);
int
bps
=
r600_audio_bits_per_sample
(
rdev
);
uint8_t
status_bits
=
r600_audio_status_bits
(
rdev
);
uint8_t
category_code
=
r600_audio_category_code
(
rdev
);
struct
drm_encoder
*
encoder
;
int
changes
=
0
;
changes
|=
channels
!=
rdev
->
audio_channels
;
changes
|=
rate
!=
rdev
->
audio_rate
;
changes
|=
bps
!=
rdev
->
audio_bits_per_sample
;
changes
|=
status_bits
!=
rdev
->
audio_status_bits
;
changes
|=
category_code
!=
rdev
->
audio_category_code
;
if
(
changes
)
{
rdev
->
audio_channels
=
channels
;
rdev
->
audio_rate
=
rate
;
rdev
->
audio_bits_per_sample
=
bps
;
rdev
->
audio_status_bits
=
status_bits
;
rdev
->
audio_category_code
=
category_code
;
}
list_for_each_entry
(
encoder
,
&
dev
->
mode_config
.
encoder_list
,
head
)
{
if
(
changes
||
r600_hdmi_buffer_status_changed
(
encoder
))
r600_hdmi_update_audio_settings
(
encoder
,
channels
,
rate
,
bps
,
status_bits
,
category_code
);
}
mod_timer
(
&
rdev
->
audio_timer
,
jiffies
+
msecs_to_jiffies
(
AUDIO_TIMER_INTERVALL
));
}
/*
* initialize the audio vars and register the update timer
*/
int
r600_audio_init
(
struct
radeon_device
*
rdev
)
{
if
(
!
r600_audio_chipset_supported
(
rdev
))
return
0
;
DRM_INFO
(
"%s audio support"
,
radeon_audio
?
"Enabling"
:
"Disabling"
);
WREG32_P
(
R600_AUDIO_ENABLE
,
radeon_audio
?
0x81000000
:
0x0
,
~
0x81000000
);
rdev
->
audio_channels
=
-
1
;
rdev
->
audio_rate
=
-
1
;
rdev
->
audio_bits_per_sample
=
-
1
;
rdev
->
audio_status_bits
=
0
;
rdev
->
audio_category_code
=
0
;
setup_timer
(
&
rdev
->
audio_timer
,
r600_audio_update_hdmi
,
(
unsigned
long
)
rdev
);
mod_timer
(
&
rdev
->
audio_timer
,
jiffies
+
1
);
return
0
;
}
/*
* determin how the encoders and audio interface is wired together
*/
int
r600_audio_tmds_index
(
struct
drm_encoder
*
encoder
)
{
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
radeon_encoder
*
radeon_encoder
=
to_radeon_encoder
(
encoder
);
struct
drm_encoder
*
other
;
switch
(
radeon_encoder
->
encoder_id
)
{
case
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
return
0
;
case
ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
/* special case check if an TMDS1 is present */
list_for_each_entry
(
other
,
&
dev
->
mode_config
.
encoder_list
,
head
)
{
if
(
to_radeon_encoder
(
other
)
->
encoder_id
==
ENCODER_OBJECT_ID_INTERNAL_TMDS1
)
return
1
;
}
return
0
;
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
case
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
return
1
;
default:
DRM_ERROR
(
"Unsupported encoder type 0x%02X
\n
"
,
radeon_encoder
->
encoder_id
);
return
-
1
;
}
}
/*
* atach the audio codec to the clock source of the encoder
*/
void
r600_audio_set_clock
(
struct
drm_encoder
*
encoder
,
int
clock
)
{
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
radeon_device
*
rdev
=
dev
->
dev_private
;
struct
radeon_encoder
*
radeon_encoder
=
to_radeon_encoder
(
encoder
);
int
base_rate
=
48000
;
switch
(
radeon_encoder
->
encoder_id
)
{
case
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
case
ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
WREG32_P
(
R600_AUDIO_TIMING
,
0
,
~
0x301
);
break
;
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
case
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
WREG32_P
(
R600_AUDIO_TIMING
,
0x100
,
~
0x301
);
break
;
default:
DRM_ERROR
(
"Unsupported encoder type 0x%02X
\n
"
,
radeon_encoder
->
encoder_id
);
return
;
}
switch
(
r600_audio_tmds_index
(
encoder
))
{
case
0
:
WREG32
(
R600_AUDIO_PLL1_MUL
,
base_rate
*
50
);
WREG32
(
R600_AUDIO_PLL1_DIV
,
clock
*
100
);
WREG32
(
R600_AUDIO_CLK_SRCSEL
,
0
);
break
;
case
1
:
WREG32
(
R600_AUDIO_PLL2_MUL
,
base_rate
*
50
);
WREG32
(
R600_AUDIO_PLL2_DIV
,
clock
*
100
);
WREG32
(
R600_AUDIO_CLK_SRCSEL
,
1
);
break
;
}
}
/*
* release the audio timer
* TODO: How to do this correctly on SMP systems?
*/
void
r600_audio_fini
(
struct
radeon_device
*
rdev
)
{
if
(
!
r600_audio_chipset_supported
(
rdev
))
return
;
WREG32_P
(
R600_AUDIO_ENABLE
,
0x0
,
~
0x81000000
);
del_timer
(
&
rdev
->
audio_timer
);
}
drivers/gpu/drm/radeon/r600_hdmi.c
0 → 100644
View file @
dcd6dfcf
/*
* Copyright 2008 Advanced Micro Devices, Inc.
* Copyright 2008 Red Hat Inc.
* Copyright 2009 Christian König.
*
* 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: Christian König
*/
#include "drmP.h"
#include "radeon_drm.h"
#include "radeon.h"
#include "atom.h"
/*
* HDMI color format
*/
enum
r600_hdmi_color_format
{
RGB
=
0
,
YCC_422
=
1
,
YCC_444
=
2
};
/*
* IEC60958 status bits
*/
enum
r600_hdmi_iec_status_bits
{
AUDIO_STATUS_DIG_ENABLE
=
0x01
,
AUDIO_STATUS_V
=
0x02
,
AUDIO_STATUS_VCFG
=
0x04
,
AUDIO_STATUS_EMPHASIS
=
0x08
,
AUDIO_STATUS_COPYRIGHT
=
0x10
,
AUDIO_STATUS_NONAUDIO
=
0x20
,
AUDIO_STATUS_PROFESSIONAL
=
0x40
,
AUDIO_STATUS_LEVEL
=
0x80
};
struct
{
uint32_t
Clock
;
int
N_32kHz
;
int
CTS_32kHz
;
int
N_44_1kHz
;
int
CTS_44_1kHz
;
int
N_48kHz
;
int
CTS_48kHz
;
}
r600_hdmi_ACR
[]
=
{
/* 32kHz 44.1kHz 48kHz */
/* Clock N CTS N CTS N CTS */
{
25174
,
4576
,
28125
,
7007
,
31250
,
6864
,
28125
},
/* 25,20/1.001 MHz */
{
25200
,
4096
,
25200
,
6272
,
28000
,
6144
,
25200
},
/* 25.20 MHz */
{
27000
,
4096
,
27000
,
6272
,
30000
,
6144
,
27000
},
/* 27.00 MHz */
{
27027
,
4096
,
27027
,
6272
,
30030
,
6144
,
27027
},
/* 27.00*1.001 MHz */
{
54000
,
4096
,
54000
,
6272
,
60000
,
6144
,
54000
},
/* 54.00 MHz */
{
54054
,
4096
,
54054
,
6272
,
60060
,
6144
,
54054
},
/* 54.00*1.001 MHz */
{
74175
,
11648
,
210937
,
17836
,
234375
,
11648
,
140625
},
/* 74.25/1.001 MHz */
{
74250
,
4096
,
74250
,
6272
,
82500
,
6144
,
74250
},
/* 74.25 MHz */
{
148351
,
11648
,
421875
,
8918
,
234375
,
5824
,
140625
},
/* 148.50/1.001 MHz */
{
148500
,
4096
,
148500
,
6272
,
165000
,
6144
,
148500
},
/* 148.50 MHz */
{
0
,
4096
,
0
,
6272
,
0
,
6144
,
0
}
/* Other */
};
/*
* calculate CTS value if it's not found in the table
*/
static
void
r600_hdmi_calc_CTS
(
uint32_t
clock
,
int
*
CTS
,
int
N
,
int
freq
)
{
if
(
*
CTS
==
0
)
*
CTS
=
clock
*
N
/
(
128
*
freq
)
*
1000
;
DRM_DEBUG
(
"Using ACR timing N=%d CTS=%d for frequency %d
\n
"
,
N
,
*
CTS
,
freq
);
}
/*
* update the N and CTS parameters for a given pixel clock rate
*/
static
void
r600_hdmi_update_ACR
(
struct
drm_encoder
*
encoder
,
uint32_t
clock
)
{
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
radeon_device
*
rdev
=
dev
->
dev_private
;
uint32_t
offset
=
to_radeon_encoder
(
encoder
)
->
hdmi_offset
;
int
CTS
;
int
N
;
int
i
;
for
(
i
=
0
;
r600_hdmi_ACR
[
i
].
Clock
!=
clock
&&
r600_hdmi_ACR
[
i
].
Clock
!=
0
;
i
++
);
CTS
=
r600_hdmi_ACR
[
i
].
CTS_32kHz
;
N
=
r600_hdmi_ACR
[
i
].
N_32kHz
;
r600_hdmi_calc_CTS
(
clock
,
&
CTS
,
N
,
32000
);
WREG32
(
offset
+
R600_HDMI_32kHz_CTS
,
CTS
<<
12
);
WREG32
(
offset
+
R600_HDMI_32kHz_N
,
N
);
CTS
=
r600_hdmi_ACR
[
i
].
CTS_44_1kHz
;
N
=
r600_hdmi_ACR
[
i
].
N_44_1kHz
;
r600_hdmi_calc_CTS
(
clock
,
&
CTS
,
N
,
44100
);
WREG32
(
offset
+
R600_HDMI_44_1kHz_CTS
,
CTS
<<
12
);
WREG32
(
offset
+
R600_HDMI_44_1kHz_N
,
N
);
CTS
=
r600_hdmi_ACR
[
i
].
CTS_48kHz
;
N
=
r600_hdmi_ACR
[
i
].
N_48kHz
;
r600_hdmi_calc_CTS
(
clock
,
&
CTS
,
N
,
48000
);
WREG32
(
offset
+
R600_HDMI_48kHz_CTS
,
CTS
<<
12
);
WREG32
(
offset
+
R600_HDMI_48kHz_N
,
N
);
}
/*
* calculate the crc for a given info frame
*/
static
void
r600_hdmi_infoframe_checksum
(
uint8_t
packetType
,
uint8_t
versionNumber
,
uint8_t
length
,
uint8_t
*
frame
)
{
int
i
;
frame
[
0
]
=
packetType
+
versionNumber
+
length
;
for
(
i
=
1
;
i
<=
length
;
i
++
)
frame
[
0
]
+=
frame
[
i
];
frame
[
0
]
=
0x100
-
frame
[
0
];
}
/*
* build a HDMI Video Info Frame
*/
static
void
r600_hdmi_videoinfoframe
(
struct
drm_encoder
*
encoder
,
enum
r600_hdmi_color_format
color_format
,
int
active_information_present
,
uint8_t
active_format_aspect_ratio
,
uint8_t
scan_information
,
uint8_t
colorimetry
,
uint8_t
ex_colorimetry
,
uint8_t
quantization
,
int
ITC
,
uint8_t
picture_aspect_ratio
,
uint8_t
video_format_identification
,
uint8_t
pixel_repetition
,
uint8_t
non_uniform_picture_scaling
,
uint8_t
bar_info_data_valid
,
uint16_t
top_bar
,
uint16_t
bottom_bar
,
uint16_t
left_bar
,
uint16_t
right_bar
)
{
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
radeon_device
*
rdev
=
dev
->
dev_private
;
uint32_t
offset
=
to_radeon_encoder
(
encoder
)
->
hdmi_offset
;
uint8_t
frame
[
14
];
frame
[
0x0
]
=
0
;
frame
[
0x1
]
=
(
scan_information
&
0x3
)
|
((
bar_info_data_valid
&
0x3
)
<<
2
)
|
((
active_information_present
&
0x1
)
<<
4
)
|
((
color_format
&
0x3
)
<<
5
);
frame
[
0x2
]
=
(
active_format_aspect_ratio
&
0xF
)
|
((
picture_aspect_ratio
&
0x3
)
<<
4
)
|
((
colorimetry
&
0x3
)
<<
6
);
frame
[
0x3
]
=
(
non_uniform_picture_scaling
&
0x3
)
|
((
quantization
&
0x3
)
<<
2
)
|
((
ex_colorimetry
&
0x7
)
<<
4
)
|
((
ITC
&
0x1
)
<<
7
);
frame
[
0x4
]
=
(
video_format_identification
&
0x7F
);
frame
[
0x5
]
=
(
pixel_repetition
&
0xF
);
frame
[
0x6
]
=
(
top_bar
&
0xFF
);
frame
[
0x7
]
=
(
top_bar
>>
8
);
frame
[
0x8
]
=
(
bottom_bar
&
0xFF
);
frame
[
0x9
]
=
(
bottom_bar
>>
8
);
frame
[
0xA
]
=
(
left_bar
&
0xFF
);
frame
[
0xB
]
=
(
left_bar
>>
8
);
frame
[
0xC
]
=
(
right_bar
&
0xFF
);
frame
[
0xD
]
=
(
right_bar
>>
8
);
r600_hdmi_infoframe_checksum
(
0x82
,
0x02
,
0x0D
,
frame
);
WREG32
(
offset
+
R600_HDMI_VIDEOINFOFRAME_0
,
frame
[
0x0
]
|
(
frame
[
0x1
]
<<
8
)
|
(
frame
[
0x2
]
<<
16
)
|
(
frame
[
0x3
]
<<
24
));
WREG32
(
offset
+
R600_HDMI_VIDEOINFOFRAME_1
,
frame
[
0x4
]
|
(
frame
[
0x5
]
<<
8
)
|
(
frame
[
0x6
]
<<
16
)
|
(
frame
[
0x7
]
<<
24
));
WREG32
(
offset
+
R600_HDMI_VIDEOINFOFRAME_2
,
frame
[
0x8
]
|
(
frame
[
0x9
]
<<
8
)
|
(
frame
[
0xA
]
<<
16
)
|
(
frame
[
0xB
]
<<
24
));
WREG32
(
offset
+
R600_HDMI_VIDEOINFOFRAME_3
,
frame
[
0xC
]
|
(
frame
[
0xD
]
<<
8
));
}
/*
* build a Audio Info Frame
*/
static
void
r600_hdmi_audioinfoframe
(
struct
drm_encoder
*
encoder
,
uint8_t
channel_count
,
uint8_t
coding_type
,
uint8_t
sample_size
,
uint8_t
sample_frequency
,
uint8_t
format
,
uint8_t
channel_allocation
,
uint8_t
level_shift
,
int
downmix_inhibit
)
{
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
radeon_device
*
rdev
=
dev
->
dev_private
;
uint32_t
offset
=
to_radeon_encoder
(
encoder
)
->
hdmi_offset
;
uint8_t
frame
[
11
];
frame
[
0x0
]
=
0
;
frame
[
0x1
]
=
(
channel_count
&
0x7
)
|
((
coding_type
&
0xF
)
<<
4
);
frame
[
0x2
]
=
(
sample_size
&
0x3
)
|
((
sample_frequency
&
0x7
)
<<
2
);
frame
[
0x3
]
=
format
;
frame
[
0x4
]
=
channel_allocation
;
frame
[
0x5
]
=
((
level_shift
&
0xF
)
<<
3
)
|
((
downmix_inhibit
&
0x1
)
<<
7
);
frame
[
0x6
]
=
0
;
frame
[
0x7
]
=
0
;
frame
[
0x8
]
=
0
;
frame
[
0x9
]
=
0
;
frame
[
0xA
]
=
0
;
r600_hdmi_infoframe_checksum
(
0x84
,
0x01
,
0x0A
,
frame
);
WREG32
(
offset
+
R600_HDMI_AUDIOINFOFRAME_0
,
frame
[
0x0
]
|
(
frame
[
0x1
]
<<
8
)
|
(
frame
[
0x2
]
<<
16
)
|
(
frame
[
0x3
]
<<
24
));
WREG32
(
offset
+
R600_HDMI_AUDIOINFOFRAME_1
,
frame
[
0x4
]
|
(
frame
[
0x5
]
<<
8
)
|
(
frame
[
0x6
]
<<
16
)
|
(
frame
[
0x8
]
<<
24
));
}
/*
* test if audio buffer is filled enough to start playing
*/
static
int
r600_hdmi_is_audio_buffer_filled
(
struct
drm_encoder
*
encoder
)
{
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
radeon_device
*
rdev
=
dev
->
dev_private
;
uint32_t
offset
=
to_radeon_encoder
(
encoder
)
->
hdmi_offset
;
return
(
RREG32
(
offset
+
R600_HDMI_STATUS
)
&
0x10
)
!=
0
;
}
/*
* have buffer status changed since last call?
*/
int
r600_hdmi_buffer_status_changed
(
struct
drm_encoder
*
encoder
)
{
struct
radeon_encoder
*
radeon_encoder
=
to_radeon_encoder
(
encoder
);
int
status
,
result
;
if
(
!
radeon_encoder
->
hdmi_offset
)
return
0
;
status
=
r600_hdmi_is_audio_buffer_filled
(
encoder
);
result
=
radeon_encoder
->
hdmi_buffer_status
!=
status
;
radeon_encoder
->
hdmi_buffer_status
=
status
;
return
result
;
}
/*
* write the audio workaround status to the hardware
*/
void
r600_hdmi_audio_workaround
(
struct
drm_encoder
*
encoder
)
{
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
radeon_device
*
rdev
=
dev
->
dev_private
;
struct
radeon_encoder
*
radeon_encoder
=
to_radeon_encoder
(
encoder
);
uint32_t
offset
=
radeon_encoder
->
hdmi_offset
;
if
(
!
offset
)
return
;
if
(
r600_hdmi_is_audio_buffer_filled
(
encoder
))
{
/* disable audio workaround and start delivering of audio frames */
WREG32_P
(
offset
+
R600_HDMI_CNTL
,
0x00000001
,
~
0x00001001
);
}
else
if
(
radeon_encoder
->
hdmi_audio_workaround
)
{
/* enable audio workaround and start delivering of audio frames */
WREG32_P
(
offset
+
R600_HDMI_CNTL
,
0x00001001
,
~
0x00001001
);
}
else
{
/* disable audio workaround and stop delivering of audio frames */
WREG32_P
(
offset
+
R600_HDMI_CNTL
,
0x00000000
,
~
0x00001001
);
}
}
/*
* update the info frames with the data from the current display mode
*/
void
r600_hdmi_setmode
(
struct
drm_encoder
*
encoder
,
struct
drm_display_mode
*
mode
)
{
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
radeon_device
*
rdev
=
dev
->
dev_private
;
uint32_t
offset
=
to_radeon_encoder
(
encoder
)
->
hdmi_offset
;
if
(
!
offset
)
return
;
r600_audio_set_clock
(
encoder
,
mode
->
clock
);
WREG32
(
offset
+
R600_HDMI_UNKNOWN_0
,
0x1000
);
WREG32
(
offset
+
R600_HDMI_UNKNOWN_1
,
0x0
);
WREG32
(
offset
+
R600_HDMI_UNKNOWN_2
,
0x1000
);
r600_hdmi_update_ACR
(
encoder
,
mode
->
clock
);
WREG32
(
offset
+
R600_HDMI_VIDEOCNTL
,
0x13
);
WREG32
(
offset
+
R600_HDMI_VERSION
,
0x202
);
r600_hdmi_videoinfoframe
(
encoder
,
RGB
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
/* it's unknown what these bits do excatly, but it's indeed quite usefull for debugging */
WREG32
(
offset
+
R600_HDMI_AUDIO_DEBUG_0
,
0x00FFFFFF
);
WREG32
(
offset
+
R600_HDMI_AUDIO_DEBUG_1
,
0x007FFFFF
);
WREG32
(
offset
+
R600_HDMI_AUDIO_DEBUG_2
,
0x00000001
);
WREG32
(
offset
+
R600_HDMI_AUDIO_DEBUG_3
,
0x00000001
);
r600_hdmi_audio_workaround
(
encoder
);
/* audio packets per line, does anyone know how to calc this ? */
WREG32_P
(
offset
+
R600_HDMI_CNTL
,
0x00040000
,
~
0x001F0000
);
/* update? reset? don't realy know */
WREG32_P
(
offset
+
R600_HDMI_CNTL
,
0x14000000
,
~
0x14000000
);
}
/*
* update settings with current parameters from audio engine
*/
void
r600_hdmi_update_audio_settings
(
struct
drm_encoder
*
encoder
,
int
channels
,
int
rate
,
int
bps
,
uint8_t
status_bits
,
uint8_t
category_code
)
{
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
radeon_device
*
rdev
=
dev
->
dev_private
;
uint32_t
offset
=
to_radeon_encoder
(
encoder
)
->
hdmi_offset
;
uint32_t
iec
;
if
(
!
offset
)
return
;
DRM_DEBUG
(
"%s with %d channels, %d Hz sampling rate, %d bits per sample,
\n
"
,
r600_hdmi_is_audio_buffer_filled
(
encoder
)
?
"playing"
:
"stopped"
,
channels
,
rate
,
bps
);
DRM_DEBUG
(
"0x%02X IEC60958 status bits and 0x%02X category code
\n
"
,
(
int
)
status_bits
,
(
int
)
category_code
);
iec
=
0
;
if
(
status_bits
&
AUDIO_STATUS_PROFESSIONAL
)
iec
|=
1
<<
0
;
if
(
status_bits
&
AUDIO_STATUS_NONAUDIO
)
iec
|=
1
<<
1
;
if
(
status_bits
&
AUDIO_STATUS_COPYRIGHT
)
iec
|=
1
<<
2
;
if
(
status_bits
&
AUDIO_STATUS_EMPHASIS
)
iec
|=
1
<<
3
;
iec
|=
category_code
<<
8
;
switch
(
rate
)
{
case
32000
:
iec
|=
0x3
<<
24
;
break
;
case
44100
:
iec
|=
0x0
<<
24
;
break
;
case
88200
:
iec
|=
0x8
<<
24
;
break
;
case
176400
:
iec
|=
0xc
<<
24
;
break
;
case
48000
:
iec
|=
0x2
<<
24
;
break
;
case
96000
:
iec
|=
0xa
<<
24
;
break
;
case
192000
:
iec
|=
0xe
<<
24
;
break
;
}
WREG32
(
offset
+
R600_HDMI_IEC60958_1
,
iec
);
iec
=
0
;
switch
(
bps
)
{
case
16
:
iec
|=
0x2
;
break
;
case
20
:
iec
|=
0x3
;
break
;
case
24
:
iec
|=
0xb
;
break
;
}
if
(
status_bits
&
AUDIO_STATUS_V
)
iec
|=
0x5
<<
16
;
WREG32_P
(
offset
+
R600_HDMI_IEC60958_2
,
iec
,
~
0x5000f
);
/* 0x021 or 0x031 sets the audio frame length */
WREG32
(
offset
+
R600_HDMI_AUDIOCNTL
,
0x31
);
r600_hdmi_audioinfoframe
(
encoder
,
channels
-
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
r600_hdmi_audio_workaround
(
encoder
);
/* update? reset? don't realy know */
WREG32_P
(
offset
+
R600_HDMI_CNTL
,
0x04000000
,
~
0x04000000
);
}
/*
* enable/disable the HDMI engine
*/
void
r600_hdmi_enable
(
struct
drm_encoder
*
encoder
,
int
enable
)
{
struct
drm_device
*
dev
=
encoder
->
dev
;
struct
radeon_device
*
rdev
=
dev
->
dev_private
;
struct
radeon_encoder
*
radeon_encoder
=
to_radeon_encoder
(
encoder
);
uint32_t
offset
=
to_radeon_encoder
(
encoder
)
->
hdmi_offset
;
if
(
!
offset
)
return
;
DRM_DEBUG
(
"%s HDMI interface @ 0x%04X
\n
"
,
enable
?
"Enabling"
:
"Disabling"
,
offset
);
/* some version of atombios ignore the enable HDMI flag
* so enabling/disabling HDMI was moved here for TMDS1+2 */
switch
(
radeon_encoder
->
encoder_id
)
{
case
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
WREG32_P
(
AVIVO_TMDSA_CNTL
,
enable
?
0x4
:
0x0
,
~
0x4
);
WREG32
(
offset
+
R600_HDMI_ENABLE
,
enable
?
0x101
:
0x0
);
break
;
case
ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
WREG32_P
(
AVIVO_LVTMA_CNTL
,
enable
?
0x4
:
0x0
,
~
0x4
);
WREG32
(
offset
+
R600_HDMI_ENABLE
,
enable
?
0x105
:
0x0
);
break
;
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
case
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
/* This part is doubtfull in my opinion */
WREG32
(
offset
+
R600_HDMI_ENABLE
,
enable
?
0x110
:
0x0
);
break
;
default:
DRM_ERROR
(
"unknown HDMI output type
\n
"
);
break
;
}
}
/*
* determin at which register offset the HDMI encoder is
*/
void
r600_hdmi_init
(
struct
drm_encoder
*
encoder
)
{
struct
radeon_encoder
*
radeon_encoder
=
to_radeon_encoder
(
encoder
);
switch
(
radeon_encoder
->
encoder_id
)
{
case
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
radeon_encoder
->
hdmi_offset
=
R600_HDMI_TMDS1
;
break
;
case
ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
switch
(
r600_audio_tmds_index
(
encoder
))
{
case
0
:
radeon_encoder
->
hdmi_offset
=
R600_HDMI_TMDS1
;
break
;
case
1
:
radeon_encoder
->
hdmi_offset
=
R600_HDMI_TMDS2
;
break
;
default:
radeon_encoder
->
hdmi_offset
=
0
;
break
;
}
case
ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
radeon_encoder
->
hdmi_offset
=
R600_HDMI_TMDS2
;
break
;
case
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
radeon_encoder
->
hdmi_offset
=
R600_HDMI_DIG
;
break
;
default:
radeon_encoder
->
hdmi_offset
=
0
;
break
;
}
DRM_DEBUG
(
"using HDMI engine at offset 0x%04X for encoder 0x%x
\n
"
,
radeon_encoder
->
hdmi_offset
,
radeon_encoder
->
encoder_id
);
/* TODO: make this configureable */
radeon_encoder
->
hdmi_audio_workaround
=
0
;
}
drivers/gpu/drm/radeon/r600_reg.h
View file @
dcd6dfcf
...
...
@@ -110,5 +110,79 @@
#define R600_BIOS_6_SCRATCH 0x173c
#define R600_BIOS_7_SCRATCH 0x1740
/* Audio, these regs were reverse enginered,
* so the chance is high that the naming is wrong
* R6xx+ ??? */
/* Audio clocks */
#define R600_AUDIO_PLL1_MUL 0x0514
#define R600_AUDIO_PLL1_DIV 0x0518
#define R600_AUDIO_PLL2_MUL 0x0524
#define R600_AUDIO_PLL2_DIV 0x0528
#define R600_AUDIO_CLK_SRCSEL 0x0534
/* Audio general */
#define R600_AUDIO_ENABLE 0x7300
#define R600_AUDIO_TIMING 0x7344
/* Audio params */
#define R600_AUDIO_VENDOR_ID 0x7380
#define R600_AUDIO_REVISION_ID 0x7384
#define R600_AUDIO_ROOT_NODE_COUNT 0x7388
#define R600_AUDIO_NID1_NODE_COUNT 0x738c
#define R600_AUDIO_NID1_TYPE 0x7390
#define R600_AUDIO_SUPPORTED_SIZE_RATE 0x7394
#define R600_AUDIO_SUPPORTED_CODEC 0x7398
#define R600_AUDIO_SUPPORTED_POWER_STATES 0x739c
#define R600_AUDIO_NID2_CAPS 0x73a0
#define R600_AUDIO_NID3_CAPS 0x73a4
#define R600_AUDIO_NID3_PIN_CAPS 0x73a8
/* Audio conn list */
#define R600_AUDIO_CONN_LIST_LEN 0x73ac
#define R600_AUDIO_CONN_LIST 0x73b0
/* Audio verbs */
#define R600_AUDIO_RATE_BPS_CHANNEL 0x73c0
#define R600_AUDIO_PLAYING 0x73c4
#define R600_AUDIO_IMPLEMENTATION_ID 0x73c8
#define R600_AUDIO_CONFIG_DEFAULT 0x73cc
#define R600_AUDIO_PIN_SENSE 0x73d0
#define R600_AUDIO_PIN_WIDGET_CNTL 0x73d4
#define R600_AUDIO_STATUS_BITS 0x73d8
/* HDMI base register addresses */
#define R600_HDMI_TMDS1 0x7400
#define R600_HDMI_TMDS2 0x7700
#define R600_HDMI_DIG 0x7800
/* HDMI registers */
#define R600_HDMI_ENABLE 0x00
#define R600_HDMI_STATUS 0x04
#define R600_HDMI_CNTL 0x08
#define R600_HDMI_UNKNOWN_0 0x0C
#define R600_HDMI_AUDIOCNTL 0x10
#define R600_HDMI_VIDEOCNTL 0x14
#define R600_HDMI_VERSION 0x18
#define R600_HDMI_UNKNOWN_1 0x28
#define R600_HDMI_VIDEOINFOFRAME_0 0x54
#define R600_HDMI_VIDEOINFOFRAME_1 0x58
#define R600_HDMI_VIDEOINFOFRAME_2 0x5c
#define R600_HDMI_VIDEOINFOFRAME_3 0x60
#define R600_HDMI_32kHz_CTS 0xac
#define R600_HDMI_32kHz_N 0xb0
#define R600_HDMI_44_1kHz_CTS 0xb4
#define R600_HDMI_44_1kHz_N 0xb8
#define R600_HDMI_48kHz_CTS 0xbc
#define R600_HDMI_48kHz_N 0xc0
#define R600_HDMI_AUDIOINFOFRAME_0 0xcc
#define R600_HDMI_AUDIOINFOFRAME_1 0xd0
#define R600_HDMI_IEC60958_1 0xd4
#define R600_HDMI_IEC60958_2 0xd8
#define R600_HDMI_UNKNOWN_2 0xdc
#define R600_HDMI_AUDIO_DEBUG_0 0xe0
#define R600_HDMI_AUDIO_DEBUG_1 0xe4
#define R600_HDMI_AUDIO_DEBUG_2 0xe8
#define R600_HDMI_AUDIO_DEBUG_3 0xec
#endif
drivers/gpu/drm/radeon/radeon.h
View file @
dcd6dfcf
...
...
@@ -89,6 +89,7 @@ extern int radeon_testing;
extern
int
radeon_connector_table
;
extern
int
radeon_tv
;
extern
int
radeon_new_pll
;
extern
int
radeon_audio
;
/*
* Copy from radeon_drv.h so we don't have to include both and have conflicting
...
...
@@ -814,6 +815,14 @@ struct radeon_device {
struct
r600_ih
ih
;
/* r6/700 interrupt ring */
struct
workqueue_struct
*
wq
;
struct
work_struct
hotplug_work
;
/* audio stuff */
struct
timer_list
audio_timer
;
int
audio_channels
;
int
audio_rate
;
int
audio_bits_per_sample
;
uint8_t
audio_status_bits
;
uint8_t
audio_category_code
;
};
int
radeon_device_init
(
struct
radeon_device
*
rdev
,
...
...
@@ -1016,6 +1025,7 @@ extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
extern
void
radeon_legacy_set_clock_gating
(
struct
radeon_device
*
rdev
,
int
enable
);
extern
void
radeon_atom_set_clock_gating
(
struct
radeon_device
*
rdev
,
int
enable
);
extern
void
radeon_ttm_placement_from_domain
(
struct
radeon_bo
*
rbo
,
u32
domain
);
extern
bool
radeon_ttm_bo_is_radeon_bo
(
struct
ttm_buffer_object
*
bo
);
/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
struct
r100_mc_save
{
...
...
@@ -1146,6 +1156,21 @@ extern void r600_irq_fini(struct radeon_device *rdev);
extern
void
r600_ih_ring_init
(
struct
radeon_device
*
rdev
,
unsigned
ring_size
);
extern
int
r600_irq_set
(
struct
radeon_device
*
rdev
);
extern
int
r600_audio_init
(
struct
radeon_device
*
rdev
);
extern
int
r600_audio_tmds_index
(
struct
drm_encoder
*
encoder
);
extern
void
r600_audio_set_clock
(
struct
drm_encoder
*
encoder
,
int
clock
);
extern
void
r600_audio_fini
(
struct
radeon_device
*
rdev
);
extern
void
r600_hdmi_init
(
struct
drm_encoder
*
encoder
);
extern
void
r600_hdmi_enable
(
struct
drm_encoder
*
encoder
,
int
enable
);
extern
void
r600_hdmi_setmode
(
struct
drm_encoder
*
encoder
,
struct
drm_display_mode
*
mode
);
extern
int
r600_hdmi_buffer_status_changed
(
struct
drm_encoder
*
encoder
);
extern
void
r600_hdmi_update_audio_settings
(
struct
drm_encoder
*
encoder
,
int
channels
,
int
rate
,
int
bps
,
uint8_t
status_bits
,
uint8_t
category_code
);
#include "radeon_object.h"
#endif
drivers/gpu/drm/radeon/radeon_drv.c
View file @
dcd6dfcf
...
...
@@ -87,6 +87,7 @@ int radeon_testing = 0;
int
radeon_connector_table
=
0
;
int
radeon_tv
=
1
;
int
radeon_new_pll
=
1
;
int
radeon_audio
=
1
;
MODULE_PARM_DESC
(
no_wb
,
"Disable AGP writeback for scratch registers"
);
module_param_named
(
no_wb
,
radeon_no_wb
,
int
,
0444
);
...
...
@@ -124,6 +125,9 @@ module_param_named(tv, radeon_tv, int, 0444);
MODULE_PARM_DESC
(
new_pll
,
"Select new PLL code for AVIVO chips"
);
module_param_named
(
new_pll
,
radeon_new_pll
,
int
,
0444
);
MODULE_PARM_DESC
(
audio
,
"Audio enable (0 = disable)"
);
module_param_named
(
audio
,
radeon_audio
,
int
,
0444
);
static
int
radeon_suspend
(
struct
drm_device
*
dev
,
pm_message_t
state
)
{
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
...
...
drivers/gpu/drm/radeon/radeon_encoders.c
View file @
dcd6dfcf
...
...
@@ -438,6 +438,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
struct
radeon_encoder
*
radeon_encoder
=
to_radeon_encoder
(
encoder
);
union
lvds_encoder_control
args
;
int
index
=
0
;
int
hdmi_detected
=
0
;
uint8_t
frev
,
crev
;
struct
radeon_encoder_atom_dig
*
dig
;
struct
drm_connector
*
connector
;
...
...
@@ -458,6 +459,9 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
if
(
!
radeon_connector
->
con_priv
)
return
;
if
(
drm_detect_hdmi_monitor
(
radeon_connector
->
edid
))
hdmi_detected
=
1
;
dig_connector
=
radeon_connector
->
con_priv
;
memset
(
&
args
,
0
,
sizeof
(
args
));
...
...
@@ -487,7 +491,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
case
1
:
args
.
v1
.
ucMisc
=
0
;
args
.
v1
.
ucAction
=
action
;
if
(
drm_detect_hdmi_monitor
(
radeon_connector
->
edid
)
)
if
(
hdmi_detected
)
args
.
v1
.
ucMisc
|=
PANEL_ENCODER_MISC_HDMI_TYPE
;
args
.
v1
.
usPixelClock
=
cpu_to_le16
(
radeon_encoder
->
pixel_clock
/
10
);
if
(
radeon_encoder
->
devices
&
(
ATOM_DEVICE_LCD_SUPPORT
))
{
...
...
@@ -512,7 +516,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
if
(
dig
->
coherent_mode
)
args
.
v2
.
ucMisc
|=
PANEL_ENCODER_MISC_COHERENT
;
}
if
(
drm_detect_hdmi_monitor
(
radeon_connector
->
edid
)
)
if
(
hdmi_detected
)
args
.
v2
.
ucMisc
|=
PANEL_ENCODER_MISC_HDMI_TYPE
;
args
.
v2
.
usPixelClock
=
cpu_to_le16
(
radeon_encoder
->
pixel_clock
/
10
);
args
.
v2
.
ucTruncate
=
0
;
...
...
@@ -552,7 +556,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
}
atom_execute_table
(
rdev
->
mode_info
.
atom_context
,
index
,
(
uint32_t
*
)
&
args
);
r600_hdmi_enable
(
encoder
,
hdmi_detected
);
}
int
...
...
@@ -893,7 +897,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
}
atom_execute_table
(
rdev
->
mode_info
.
atom_context
,
index
,
(
uint32_t
*
)
&
args
);
}
static
void
...
...
@@ -1162,7 +1165,6 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
}
atom_execute_table
(
rdev
->
mode_info
.
atom_context
,
index
,
(
uint32_t
*
)
&
args
);
}
static
void
...
...
@@ -1265,6 +1267,8 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
break
;
}
atombios_apply_encoder_quirks
(
encoder
,
adjusted_mode
);
r600_hdmi_setmode
(
encoder
,
adjusted_mode
);
}
static
bool
...
...
@@ -1510,4 +1514,6 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
drm_encoder_helper_add
(
encoder
,
&
radeon_atom_dig_helper_funcs
);
break
;
}
r600_hdmi_init
(
encoder
);
}
drivers/gpu/drm/radeon/radeon_gem.c
View file @
dcd6dfcf
...
...
@@ -66,8 +66,9 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size,
}
r
=
radeon_bo_create
(
rdev
,
gobj
,
size
,
kernel
,
initial_domain
,
&
robj
);
if
(
r
)
{
DRM_ERROR
(
"Failed to allocate GEM object (%d, %d, %u)
\n
"
,
size
,
initial_domain
,
alignment
);
if
(
r
!=
-
ERESTARTSYS
)
DRM_ERROR
(
"Failed to allocate GEM object (%d, %d, %u, %d)
\n
"
,
size
,
initial_domain
,
alignment
,
r
);
mutex_lock
(
&
rdev
->
ddev
->
struct_mutex
);
drm_gem_object_unreference
(
gobj
);
mutex_unlock
(
&
rdev
->
ddev
->
struct_mutex
);
...
...
@@ -350,9 +351,10 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
rbo
=
gobj
->
driver_private
;
r
=
radeon_bo_reserve
(
rbo
,
false
);
if
(
unlikely
(
r
!=
0
))
return
r
;
goto
out
;
radeon_bo_get_tiling_flags
(
rbo
,
&
args
->
tiling_flags
,
&
args
->
pitch
);
radeon_bo_unreserve
(
rbo
);
out:
mutex_lock
(
&
dev
->
struct_mutex
);
drm_gem_object_unreference
(
gobj
);
mutex_unlock
(
&
dev
->
struct_mutex
);
...
...
drivers/gpu/drm/radeon/radeon_mode.h
View file @
dcd6dfcf
...
...
@@ -334,6 +334,9 @@ struct radeon_encoder {
enum
radeon_rmx_type
rmx_type
;
struct
drm_display_mode
native_mode
;
void
*
enc_priv
;
int
hdmi_offset
;
int
hdmi_audio_workaround
;
int
hdmi_buffer_status
;
};
struct
radeon_connector_atom_dig
{
...
...
drivers/gpu/drm/radeon/radeon_object.c
View file @
dcd6dfcf
...
...
@@ -56,6 +56,13 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo)
kfree
(
bo
);
}
bool
radeon_ttm_bo_is_radeon_bo
(
struct
ttm_buffer_object
*
bo
)
{
if
(
bo
->
destroy
==
&
radeon_ttm_bo_destroy
)
return
true
;
return
false
;
}
void
radeon_ttm_placement_from_domain
(
struct
radeon_bo
*
rbo
,
u32
domain
)
{
u32
c
=
0
;
...
...
@@ -71,6 +78,8 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
rbo
->
placements
[
c
++
]
=
TTM_PL_MASK_CACHING
|
TTM_PL_FLAG_TT
;
if
(
domain
&
RADEON_GEM_DOMAIN_CPU
)
rbo
->
placements
[
c
++
]
=
TTM_PL_MASK_CACHING
|
TTM_PL_FLAG_SYSTEM
;
if
(
!
c
)
rbo
->
placements
[
c
++
]
=
TTM_PL_MASK_CACHING
|
TTM_PL_FLAG_SYSTEM
;
rbo
->
placement
.
num_placement
=
c
;
rbo
->
placement
.
num_busy_placement
=
c
;
}
...
...
@@ -483,12 +492,18 @@ int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
void
radeon_bo_move_notify
(
struct
ttm_buffer_object
*
bo
,
struct
ttm_mem_reg
*
mem
)
{
struct
radeon_bo
*
rbo
=
container_of
(
bo
,
struct
radeon_bo
,
tbo
);
struct
radeon_bo
*
rbo
;
if
(
!
radeon_ttm_bo_is_radeon_bo
(
bo
))
return
;
rbo
=
container_of
(
bo
,
struct
radeon_bo
,
tbo
);
radeon_bo_check_tiling
(
rbo
,
0
,
1
);
}
void
radeon_bo_fault_reserve_notify
(
struct
ttm_buffer_object
*
bo
)
{
struct
radeon_bo
*
rbo
=
container_of
(
bo
,
struct
radeon_bo
,
tbo
);
struct
radeon_bo
*
rbo
;
if
(
!
radeon_ttm_bo_is_radeon_bo
(
bo
))
return
;
rbo
=
container_of
(
bo
,
struct
radeon_bo
,
tbo
);
radeon_bo_check_tiling
(
rbo
,
0
,
0
);
}
drivers/gpu/drm/radeon/radeon_object.h
View file @
dcd6dfcf
...
...
@@ -59,18 +59,16 @@ static inline unsigned radeon_mem_type_to_domain(u32 mem_type)
*
* Returns:
* -EBUSY: buffer is busy and @no_wait is true
* -ERESTART: A wait for the buffer to become unreserved was interrupted by
* -ERESTART
SYS
: A wait for the buffer to become unreserved was interrupted by
* a signal. Release all buffer reservations and return to user-space.
*/
static
inline
int
radeon_bo_reserve
(
struct
radeon_bo
*
bo
,
bool
no_wait
)
{
int
r
;
retry:
r
=
ttm_bo_reserve
(
&
bo
->
tbo
,
true
,
no_wait
,
false
,
0
);
if
(
unlikely
(
r
!=
0
))
{
if
(
r
==
-
ERESTART
)
goto
retry
;
if
(
r
!=
-
ERESTARTSYS
)
dev_err
(
bo
->
rdev
->
dev
,
"%p reserve failed
\n
"
,
bo
);
return
r
;
}
...
...
@@ -125,11 +123,9 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
{
int
r
;
retry:
r
=
ttm_bo_reserve
(
&
bo
->
tbo
,
true
,
no_wait
,
false
,
0
);
if
(
unlikely
(
r
!=
0
))
{
if
(
r
==
-
ERESTART
)
goto
retry
;
if
(
r
!=
-
ERESTARTSYS
)
dev_err
(
bo
->
rdev
->
dev
,
"%p reserve failed for wait
\n
"
,
bo
);
return
r
;
}
...
...
@@ -140,8 +136,6 @@ retry:
r
=
ttm_bo_wait
(
&
bo
->
tbo
,
true
,
true
,
no_wait
);
spin_unlock
(
&
bo
->
tbo
.
lock
);
ttm_bo_unreserve
(
&
bo
->
tbo
);
if
(
unlikely
(
r
==
-
ERESTART
))
goto
retry
;
return
r
;
}
...
...
drivers/gpu/drm/radeon/radeon_pm.c
View file @
dcd6dfcf
...
...
@@ -44,8 +44,11 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
struct
drm_device
*
dev
=
node
->
minor
->
dev
;
struct
radeon_device
*
rdev
=
dev
->
dev_private
;
seq_printf
(
m
,
"engine clock: %u0 kHz
\n
"
,
radeon_get_engine_clock
(
rdev
));
seq_printf
(
m
,
"memory clock: %u0 kHz
\n
"
,
radeon_get_memory_clock
(
rdev
));
seq_printf
(
m
,
"default engine clock: %u0 kHz
\n
"
,
rdev
->
clock
.
default_sclk
);
seq_printf
(
m
,
"current engine clock: %u0 kHz
\n
"
,
radeon_get_engine_clock
(
rdev
));
seq_printf
(
m
,
"default memory clock: %u0 kHz
\n
"
,
rdev
->
clock
.
default_mclk
);
if
(
rdev
->
asic
->
get_memory_clock
)
seq_printf
(
m
,
"current memory clock: %u0 kHz
\n
"
,
radeon_get_memory_clock
(
rdev
));
return
0
;
}
...
...
drivers/gpu/drm/radeon/radeon_ttm.c
View file @
dcd6dfcf
...
...
@@ -200,7 +200,19 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
static
void
radeon_evict_flags
(
struct
ttm_buffer_object
*
bo
,
struct
ttm_placement
*
placement
)
{
struct
radeon_bo
*
rbo
=
container_of
(
bo
,
struct
radeon_bo
,
tbo
);
struct
radeon_bo
*
rbo
;
static
u32
placements
=
TTM_PL_MASK_CACHING
|
TTM_PL_FLAG_SYSTEM
;
if
(
!
radeon_ttm_bo_is_radeon_bo
(
bo
))
{
placement
->
fpfn
=
0
;
placement
->
lpfn
=
0
;
placement
->
placement
=
&
placements
;
placement
->
busy_placement
=
&
placements
;
placement
->
num_placement
=
1
;
placement
->
num_busy_placement
=
1
;
return
;
}
rbo
=
container_of
(
bo
,
struct
radeon_bo
,
tbo
);
switch
(
bo
->
mem
.
mem_type
)
{
case
TTM_PL_VRAM
:
radeon_ttm_placement_from_domain
(
rbo
,
RADEON_GEM_DOMAIN_GTT
);
...
...
drivers/gpu/drm/radeon/rs400.c
View file @
dcd6dfcf
...
...
@@ -497,6 +497,8 @@ int rs400_init(struct radeon_device *rdev)
/* Initialize clocks */
radeon_get_clock_info
(
rdev
->
ddev
);
/* Initialize power management */
radeon_pm_init
(
rdev
);
/* Get vram informations */
rs400_vram_info
(
rdev
);
/* Initialize memory controller (also test AGP) */
...
...
drivers/gpu/drm/radeon/rv770.c
View file @
dcd6dfcf
...
...
@@ -892,6 +892,14 @@ static int rv770_startup(struct radeon_device *rdev)
}
rv770_gpu_init
(
rdev
);
if
(
!
rdev
->
r600_blit
.
shader_obj
)
{
r
=
r600_blit_init
(
rdev
);
if
(
r
)
{
DRM_ERROR
(
"radeon: failed blitter (%d).
\n
"
,
r
);
return
r
;
}
}
r
=
radeon_bo_reserve
(
rdev
->
r600_blit
.
shader_obj
,
false
);
if
(
unlikely
(
r
!=
0
))
return
r
;
...
...
@@ -1051,12 +1059,6 @@ int rv770_init(struct radeon_device *rdev)
if
(
r
)
return
r
;
r
=
r600_blit_init
(
rdev
);
if
(
r
)
{
DRM_ERROR
(
"radeon: failed blitter (%d).
\n
"
,
r
);
return
r
;
}
rdev
->
accel_working
=
true
;
r
=
rv770_startup
(
rdev
);
if
(
r
)
{
...
...
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