2 * Copyright 2012 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
27 #include <subdev/i2c.h>
28 #include <subdev/timer.h>
31 nv50_pior_clock(struct nvkm_ior
*pior
)
33 struct nvkm_device
*device
= pior
->disp
->engine
.subdev
.device
;
34 const u32 poff
= nv50_ior_base(pior
);
35 nvkm_mask(device
, 0x614380 + poff
, 0x00000707, 0x00000001);
39 nv50_pior_dp_links(struct nvkm_ior
*pior
, struct nvkm_i2c_aux
*aux
)
41 int ret
= nvkm_i2c_aux_lnk_ctl(aux
, pior
->dp
.nr
, pior
->dp
.bw
,
49 nv50_pior_power_wait(struct nvkm_device
*device
, u32 poff
)
51 nvkm_msec(device
, 2000,
52 if (!(nvkm_rd32(device
, 0x61e004 + poff
) & 0x80000000))
58 nv50_pior_power(struct nvkm_ior
*pior
, bool normal
, bool pu
,
59 bool data
, bool vsync
, bool hsync
)
61 struct nvkm_device
*device
= pior
->disp
->engine
.subdev
.device
;
62 const u32 poff
= nv50_ior_base(pior
);
63 const u32 shift
= normal
? 0 : 16;
64 const u32 state
= 0x80000000 | (0x00000001 * !!pu
) << shift
;
65 const u32 field
= 0x80000000 | (0x00000101 << shift
);
67 nv50_pior_power_wait(device
, poff
);
68 nvkm_mask(device
, 0x61e004 + poff
, field
, state
);
69 nv50_pior_power_wait(device
, poff
);
73 nv50_pior_depth(struct nvkm_ior
*ior
, struct nvkm_ior_state
*state
, u32 ctrl
)
75 /* GF119 moves this information to per-head methods, which is
76 * a lot more convenient, and where our shared code expect it.
78 if (state
->head
&& state
== &ior
->asy
) {
79 struct nvkm_head
*head
=
80 nvkm_head_find(ior
->disp
, __ffs(state
->head
));
81 if (!WARN_ON(!head
)) {
82 struct nvkm_head_state
*state
= &head
->asy
;
83 switch ((ctrl
& 0x000f0000) >> 16) {
84 case 6: state
->or.depth
= 30; break;
85 case 5: state
->or.depth
= 24; break;
86 case 2: state
->or.depth
= 18; break;
87 case 0: state
->or.depth
= 18; break; /*XXX*/
98 nv50_pior_state(struct nvkm_ior
*pior
, struct nvkm_ior_state
*state
)
100 struct nvkm_device
*device
= pior
->disp
->engine
.subdev
.device
;
101 const u32 coff
= pior
->id
* 8 + (state
== &pior
->arm
) * 4;
102 u32 ctrl
= nvkm_rd32(device
, 0x610b80 + coff
);
104 state
->proto_evo
= (ctrl
& 0x00000f00) >> 8;
106 switch (state
->proto_evo
) {
107 case 0: state
->proto
= TMDS
; break;
109 state
->proto
= UNKNOWN
;
113 state
->head
= ctrl
& 0x00000003;
114 nv50_pior_depth(pior
, state
, ctrl
);
117 static const struct nvkm_ior_func
119 .state
= nv50_pior_state
,
120 .power
= nv50_pior_power
,
121 .clock
= nv50_pior_clock
,
123 .links
= nv50_pior_dp_links
,
128 nv50_pior_new(struct nvkm_disp
*disp
, int id
)
130 struct nvkm_device
*device
= disp
->engine
.subdev
.device
;
131 if (!(nvkm_rd32(device
, 0x610184) & (0x10000000 << id
)))
133 return nvkm_ior_new_(&nv50_pior
, disp
, PIOR
, id
);