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
16d4c031
Commit
16d4c031
authored
Feb 20, 2013
by
Ben Skeggs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drm/nv50/disp: handle multiple actions from one set of supervisor intrs
Signed-off-by:
Ben Skeggs
<
bskeggs@redhat.com
>
parent
a91ed42d
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
118 additions
and
108 deletions
+118
-108
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+118
-108
No files found.
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
View file @
16d4c031
...
...
@@ -972,20 +972,28 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk,
}
static
void
nv50_disp_intr_unk10
(
struct
nv50_disp_priv
*
priv
,
u32
super
)
nv50_disp_intr_unk10
_0
(
struct
nv50_disp_priv
*
priv
,
int
head
)
{
int
head
=
ffs
((
super
&
0x00000060
)
>>
5
)
-
1
;
if
(
head
>=
0
)
{
head
=
ffs
((
super
&
0x00000180
)
>>
7
)
-
1
;
if
(
head
>=
0
)
exec_script
(
priv
,
head
,
1
);
}
}
nv_wr32
(
priv
,
0x610030
,
0x80000000
);
static
void
nv50_disp_intr_unk20_0
(
struct
nv50_disp_priv
*
priv
,
int
head
)
{
exec_script
(
priv
,
head
,
2
);
}
static
void
nv50_disp_intr_unk20_dp
(
struct
nv50_disp_priv
*
priv
,
nv50_disp_intr_unk20_1
(
struct
nv50_disp_priv
*
priv
,
int
head
)
{
struct
nouveau_clock
*
clk
=
nouveau_clock
(
priv
);
u32
pclk
=
nv_rd32
(
priv
,
0x610ad0
+
(
head
*
0x540
))
&
0x3fffff
;
if
(
pclk
)
clk
->
pll_set
(
clk
,
PLL_VPLL0
+
head
,
pclk
);
}
static
void
nv50_disp_intr_unk20_2_dp
(
struct
nv50_disp_priv
*
priv
,
struct
dcb_output
*
outp
,
u32
pclk
)
{
const
int
link
=
!
(
outp
->
sorconf
.
link
&
1
);
...
...
@@ -1092,29 +1100,9 @@ nv50_disp_intr_unk20_dp(struct nv50_disp_priv *priv,
}
static
void
nv50_disp_intr_unk20
(
struct
nv50_disp_priv
*
priv
,
u32
super
)
nv50_disp_intr_unk20
_2
(
struct
nv50_disp_priv
*
priv
,
int
head
)
{
struct
dcb_output
outp
;
int
head
;
/* finish detaching encoder? */
head
=
ffs
((
super
&
0x00000180
)
>>
7
)
-
1
;
if
(
head
>=
0
)
exec_script
(
priv
,
head
,
2
);
/* check whether a vpll change is required */
head
=
ffs
((
super
&
0x00000600
)
>>
9
)
-
1
;
if
(
head
>=
0
)
{
u32
pclk
=
nv_rd32
(
priv
,
0x610ad0
+
(
head
*
0x540
))
&
0x3fffff
;
if
(
pclk
)
{
struct
nouveau_clock
*
clk
=
nouveau_clock
(
priv
);
clk
->
pll_set
(
clk
,
PLL_VPLL0
+
head
,
pclk
);
}
}
/* (re)attach the relevant OR to the head */
head
=
ffs
((
super
&
0x00000180
)
>>
7
)
-
1
;
if
(
head
>=
0
)
{
u32
pclk
=
nv_rd32
(
priv
,
0x610ad0
+
(
head
*
0x540
))
&
0x3fffff
;
u32
hval
,
hreg
=
0x614200
+
(
head
*
0x800
);
u32
oval
,
oreg
;
...
...
@@ -1147,9 +1135,9 @@ nv50_disp_intr_unk20(struct nv50_disp_priv *priv, u32 super)
}
else
if
(
!
outp
.
location
)
{
if
(
outp
.
type
==
DCB_OUTPUT_DP
)
nv50_disp_intr_unk20
_dp
(
priv
,
&
outp
,
pclk
);
nv50_disp_intr_unk20_2
_dp
(
priv
,
&
outp
,
pclk
);
oreg
=
0x614300
+
(
ffs
(
outp
.
or
)
-
1
)
*
0x800
;
oval
=
(
conf
&
0x0100
)
?
0x0101
:
0x
0000
;
oval
=
(
conf
&
0x0100
)
?
0x00000101
:
0x0000
0000
;
hval
=
0x00000000
;
}
else
{
oreg
=
0x614380
+
(
ffs
(
outp
.
or
)
-
1
)
*
0x800
;
...
...
@@ -1160,9 +1148,6 @@ nv50_disp_intr_unk20(struct nv50_disp_priv *priv, u32 super)
nv_mask
(
priv
,
hreg
,
0x0000000f
,
hval
);
nv_mask
(
priv
,
oreg
,
0x00000707
,
oval
);
}
}
nv_wr32
(
priv
,
0x610030
,
0x80000000
);
}
/* If programming a TMDS output on a SOR that can also be configured for
...
...
@@ -1174,7 +1159,7 @@ nv50_disp_intr_unk20(struct nv50_disp_priv *priv, u32 super)
* programmed for DisplayPort.
*/
static
void
nv50_disp_intr_unk40_tmds
(
struct
nv50_disp_priv
*
priv
,
struct
dcb_output
*
outp
)
nv50_disp_intr_unk40_
0_
tmds
(
struct
nv50_disp_priv
*
priv
,
struct
dcb_output
*
outp
)
{
struct
nouveau_bios
*
bios
=
nouveau_bios
(
priv
);
const
int
link
=
!
(
outp
->
sorconf
.
link
&
1
);
...
...
@@ -1188,15 +1173,13 @@ nv50_disp_intr_unk40_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp)
}
static
void
nv50_disp_intr_unk40
(
struct
nv50_disp_priv
*
priv
,
u32
super
)
nv50_disp_intr_unk40
_0
(
struct
nv50_disp_priv
*
priv
,
int
head
)
{
int
head
=
ffs
((
super
&
0x00000180
)
>>
7
)
-
1
;
if
(
head
>=
0
)
{
struct
dcb_output
outp
;
u32
pclk
=
nv_rd32
(
priv
,
0x610ad0
+
(
head
*
0x540
))
&
0x3fffff
;
if
(
exec_clkcmp
(
priv
,
head
,
1
,
pclk
,
&
outp
)
!=
~
0
)
{
if
(
outp
.
location
==
0
&&
outp
.
type
==
DCB_OUTPUT_TMDS
)
nv50_disp_intr_unk4
0_tmds
(
priv
,
&
outp
);
nv50_disp_intr_unk40_
0_tmds
(
priv
,
&
outp
);
else
if
(
outp
.
location
==
1
&&
outp
.
type
==
DCB_OUTPUT_DP
)
{
u32
soff
=
(
ffs
(
outp
.
or
)
-
1
)
*
0x08
;
...
...
@@ -1216,9 +1199,6 @@ nv50_disp_intr_unk40(struct nv50_disp_priv *priv, u32 super)
&
outp
,
head
,
datarate
);
}
}
}
nv_wr32
(
priv
,
0x610030
,
0x80000000
);
}
void
...
...
@@ -1227,15 +1207,45 @@ nv50_disp_intr_supervisor(struct work_struct *work)
struct
nv50_disp_priv
*
priv
=
container_of
(
work
,
struct
nv50_disp_priv
,
supervisor
);
u32
super
=
nv_rd32
(
priv
,
0x610030
);
int
head
;
nv_debug
(
priv
,
"supervisor 0x%08x 0x%08x
\n
"
,
priv
->
super
,
super
);
if
(
priv
->
super
&
0x00000010
)
nv50_disp_intr_unk10
(
priv
,
super
);
if
(
priv
->
super
&
0x00000020
)
nv50_disp_intr_unk20
(
priv
,
super
);
if
(
priv
->
super
&
0x00000040
)
nv50_disp_intr_unk40
(
priv
,
super
);
if
(
priv
->
super
&
0x00000010
)
{
for
(
head
=
0
;
head
<
priv
->
head
.
nr
;
head
++
)
{
if
(
!
(
super
&
(
0x00000020
<<
head
)))
continue
;
if
(
!
(
super
&
(
0x00000080
<<
head
)))
continue
;
nv50_disp_intr_unk10_0
(
priv
,
head
);
}
}
else
if
(
priv
->
super
&
0x00000020
)
{
for
(
head
=
0
;
head
<
priv
->
head
.
nr
;
head
++
)
{
if
(
!
(
super
&
(
0x00000080
<<
head
)))
continue
;
nv50_disp_intr_unk20_0
(
priv
,
head
);
}
for
(
head
=
0
;
head
<
priv
->
head
.
nr
;
head
++
)
{
if
(
!
(
super
&
(
0x00000200
<<
head
)))
continue
;
nv50_disp_intr_unk20_1
(
priv
,
head
);
}
for
(
head
=
0
;
head
<
priv
->
head
.
nr
;
head
++
)
{
if
(
!
(
super
&
(
0x00000080
<<
head
)))
continue
;
nv50_disp_intr_unk20_2
(
priv
,
head
);
}
}
else
if
(
priv
->
super
&
0x00000040
)
{
for
(
head
=
0
;
head
<
priv
->
head
.
nr
;
head
++
)
{
if
(
!
(
super
&
(
0x00000080
<<
head
)))
continue
;
nv50_disp_intr_unk40_0
(
priv
,
head
);
}
}
nv_wr32
(
priv
,
0x610030
,
0x80000000
);
}
void
...
...
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