8 void gx_set_dotpll(struct fb_info
*info
, struct geoderegs
*regs
)
14 rdmsrl(MSR_GLCP_SYS_RSTPLL
, rstpll
);
15 rdmsrl(MSR_GLCP_DOTPLL
, dotpll
);
17 dotpll
&= 0x00000000ffffffffull
;
18 dotpll
|= regs
->msr
.dotpll
& 0xffffffff00000000ull
;
20 dotpll
|= MSR_GLCP_DOTPLL_DOTRESET
;
21 dotpll
&= ~MSR_GLCP_DOTPLL_BYPASS
;
23 wrmsrl(MSR_GLCP_DOTPLL
, dotpll
);
25 rstpll
|= (regs
->msr
.rstpll
&
26 ( MSR_GLCP_SYS_RSTPLL_DOTPREDIV2
|
27 MSR_GLCP_SYS_RSTPLL_DOTPREMULT2
|
28 MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3
));
30 wrmsrl(MSR_GLCP_SYS_RSTPLL
, rstpll
);
31 dotpll
&= ~(MSR_GLCP_DOTPLL_DOTRESET
);
32 wrmsrl(MSR_GLCP_DOTPLL
, dotpll
);
35 rdmsrl(MSR_GLCP_DOTPLL
, dotpll
);
36 } while (timeout
-- && !(dotpll
& MSR_GLCP_DOTPLL_LOCK
));
39 /* FIXME: Make sure nothing is read to clear */
41 void gx_save_regs(struct fb_info
*info
, struct geoderegs
*regs
)
43 struct geodefb_par
*par
= info
->par
;
46 /* Wait for the BLT engine to stop being busy */
47 while(readl(par
->gp_regs
+ 0x44) & 0x05);
49 rdmsrl(GX_VP_MSR_PAD_SELECT
, regs
->msr
.padsel
);
50 rdmsrl(MSR_GLCP_DOTPLL
, regs
->msr
.dotpll
);
51 rdmsrl(MSR_GLCP_SYS_RSTPLL
, regs
->msr
.rstpll
);
53 writel(0x4758, par
->dc_regs
+ 0x00);
55 memcpy(regs
->gp
.b
, par
->gp_regs
, GP_REG_SIZE
);
56 memcpy(regs
->dc
.b
, par
->dc_regs
, DC_REG_SIZE
);
57 memcpy(regs
->vp
.b
, par
->vid_regs
, VP_REG_SIZE
);
58 memcpy(regs
->fp
.b
, par
->vid_regs
+ 0x400, FP_REG_SIZE
);
60 /* Save the palettes */
61 writel(0, par
->dc_regs
+ 0x70);
63 for(i
= 0; i
< DC_PAL_SIZE
; i
++)
64 regs
->pal
[i
] = readl(par
->dc_regs
+ 0x74);
66 writel(0, par
->vid_regs
+ 0x38);
68 for(i
= 0; i
< 0xFF; i
++)
69 regs
->gamma
[i
] = readl(par
->vid_regs
+ 0x40);
72 void gx_restore_regs(struct fb_info
*info
, struct geoderegs
*regs
)
74 struct geodefb_par
*par
= info
->par
;
78 gx_set_dotpll(info
, regs
);
82 writel(regs
->gp
.r
.dst_offset
, par
->gp_regs
+ 0x00);
83 writel(regs
->gp
.r
.src_offset
, par
->gp_regs
+ 0x04);
84 writel(regs
->gp
.r
.stride
, par
->gp_regs
+ 0x08);
85 writel(regs
->gp
.r
.wid_height
, par
->gp_regs
+ 0x0C);
86 writel(regs
->gp
.r
.src_color_fg
, par
->gp_regs
+ 0x10);
87 writel(regs
->gp
.r
.src_color_bg
, par
->gp_regs
+ 0x14);
88 writel(regs
->gp
.r
.pat_color_0
, par
->gp_regs
+ 0x18);
89 writel(regs
->gp
.r
.pat_color_1
, par
->gp_regs
+ 0x1C);
90 writel(regs
->gp
.r
.pat_color_2
, par
->gp_regs
+ 0x20);
91 writel(regs
->gp
.r
.pat_color_3
, par
->gp_regs
+ 0x24);
92 writel(regs
->gp
.r
.pat_color_4
, par
->gp_regs
+ 0x28);
93 writel(regs
->gp
.r
.pat_color_5
, par
->gp_regs
+ 0x2C);
94 writel(regs
->gp
.r
.pat_data_0
, par
->gp_regs
+ 0x30);
95 writel(regs
->gp
.r
.pat_data_1
, par
->gp_regs
+ 0x34);
97 /* Don't write the raster / vector / blt mode regs */
98 /* status register is read only */
100 writel(regs
->gp
.r
.hst_src
, par
->gp_regs
+ 0x48);
101 writel(regs
->gp
.r
.base_offset
, par
->gp_regs
+ 0x4c);
105 /* Write the unlock value */
106 writel(0x4758, par
->dc_regs
+ 0x00);
108 writel(0, par
->dc_regs
+ 0x70);
110 for(i
= 0; i
< DC_PAL_SIZE
; i
++)
111 writel(regs
->pal
[i
], par
->dc_regs
+ 0x74);
113 /* Write the gcfg register without the enables */
114 writel(regs
->dc
.r
.gcfg
& ~0x0F, par
->dc_regs
+ 0x04);
116 /* Write the vcfg register without the enables */
117 writel(regs
->dc
.r
.dcfg
& ~0x19, par
->dc_regs
+ 0x08);
119 /* Write the rest of the active registers */
121 writel(regs
->dc
.r
.fb_st_offset
, par
->dc_regs
+ 0x10);
122 writel(regs
->dc
.r
.cb_st_offset
, par
->dc_regs
+ 0x14);
123 writel(regs
->dc
.r
.curs_st_offset
, par
->dc_regs
+ 0x18);
124 writel(regs
->dc
.r
.icon_st_offset
, par
->dc_regs
+ 0x1C);
125 writel(regs
->dc
.r
.vid_y_st_offset
, par
->dc_regs
+ 0x20);
126 writel(regs
->dc
.r
.vid_u_st_offset
, par
->dc_regs
+ 0x24);
127 writel(regs
->dc
.r
.vid_v_st_offset
, par
->dc_regs
+ 0x28);
128 writel(regs
->dc
.r
.line_size
, par
->dc_regs
+ 0x30);
129 writel(regs
->dc
.r
.gfx_pitch
, par
->dc_regs
+ 0x34);
130 writel(regs
->dc
.r
.vid_yuv_pitch
, par
->dc_regs
+ 0x38);
131 writel(regs
->dc
.r
.h_active_timing
, par
->dc_regs
+ 0x40);
132 writel(regs
->dc
.r
.h_blank_timing
, par
->dc_regs
+ 0x44);
133 writel(regs
->dc
.r
.h_sync_timing
, par
->dc_regs
+ 0x48);
134 writel(regs
->dc
.r
.v_active_timing
, par
->dc_regs
+ 0x50);
135 writel(regs
->dc
.r
.v_blank_timing
, par
->dc_regs
+ 0x54);
136 writel(regs
->dc
.r
.v_sync_timing
, par
->dc_regs
+ 0x58);
137 writel(regs
->dc
.r
.dc_cursor_x
, par
->dc_regs
+ 0x60);
138 writel(regs
->dc
.r
.dc_cursor_y
, par
->dc_regs
+ 0x64);
139 writel(regs
->dc
.r
.dc_icon_x
, par
->dc_regs
+ 0x68);
141 /* Don't write the line_cnt or diag registers */
143 writel(regs
->dc
.r
.dc_vid_ds_delta
, par
->dc_regs
+ 0x80);
144 writel(regs
->dc
.r
.gliu0_mem_offset
, par
->dc_regs
+ 0x84);
145 writel(regs
->dc
.r
.dv_acc
, par
->dc_regs
+ 0x8C);
150 wrmsrl(GX_VP_MSR_PAD_SELECT
, regs
->msr
.padsel
);
152 writel(0, par
->vid_regs
+ 0x38);
154 for(i
= 0; i
< 0xFF; i
++)
155 writel((u32
) regs
->gamma
[i
], par
->vid_regs
+ 0x40);
157 /* Don't enable video yet */
158 writel((u32
) regs
->vp
.r
.vcfg
& ~0x01, par
->vid_regs
+ 0x00);
160 /* Don't enable the CRT yet */
161 writel((u32
) regs
->vp
.r
.dcfg
& ~0x0F, par
->vid_regs
+ 0x08);
163 /* Write the rest of the VP registers */
165 writel((u32
) regs
->vp
.r
.vx
, par
->vid_regs
+ 0x10);
166 writel((u32
) regs
->vp
.r
.vy
, par
->vid_regs
+ 0x18);
167 writel((u32
) regs
->vp
.r
.vs
, par
->vid_regs
+ 0x20);
168 writel((u32
) regs
->vp
.r
.vck
, par
->vid_regs
+ 0x28);
169 writel((u32
) regs
->vp
.r
.vcm
, par
->vid_regs
+ 0x30);
170 writel((u32
) regs
->vp
.r
.misc
, par
->vid_regs
+ 0x50);
171 writel((u32
) regs
->vp
.r
.ccs
, par
->vid_regs
+ 0x58);
172 writel((u32
) regs
->vp
.r
.vdc
, par
->vid_regs
+ 0x78);
173 writel((u32
) regs
->vp
.r
.vco
, par
->vid_regs
+ 0x80);
174 writel((u32
) regs
->vp
.r
.crc
, par
->vid_regs
+ 0x88);
175 writel((u32
) regs
->vp
.r
.vde
, par
->vid_regs
+ 0x98);
176 writel((u32
) regs
->vp
.r
.cck
, par
->vid_regs
+ 0xA0);
177 writel((u32
) regs
->vp
.r
.ccm
, par
->vid_regs
+ 0xA8);
178 writel((u32
) regs
->vp
.r
.cc1
, par
->vid_regs
+ 0xB0);
179 writel((u32
) regs
->vp
.r
.cc2
, par
->vid_regs
+ 0xB8);
180 writel((u32
) regs
->vp
.r
.a1x
, par
->vid_regs
+ 0xC0);
181 writel((u32
) regs
->vp
.r
.a1y
, par
->vid_regs
+ 0xC8);
182 writel((u32
) regs
->vp
.r
.a1c
, par
->vid_regs
+ 0xD0);
183 writel((u32
) regs
->vp
.r
.a1t
, par
->vid_regs
+ 0xD8);
184 writel((u32
) regs
->vp
.r
.a2x
, par
->vid_regs
+ 0xE0);
185 writel((u32
) regs
->vp
.r
.a2y
, par
->vid_regs
+ 0xE8);
186 writel((u32
) regs
->vp
.r
.a2c
, par
->vid_regs
+ 0xF0);
187 writel((u32
) regs
->vp
.r
.a2t
, par
->vid_regs
+ 0xF8);
188 writel((u32
) regs
->vp
.r
.a3x
, par
->vid_regs
+ 0x100);
189 writel((u32
) regs
->vp
.r
.a3y
, par
->vid_regs
+ 0x108);
190 writel((u32
) regs
->vp
.r
.a3c
, par
->vid_regs
+ 0x110);
191 writel((u32
) regs
->vp
.r
.a3t
, par
->vid_regs
+ 0x118);
192 writel((u32
) regs
->vp
.r
.vrr
, par
->vid_regs
+ 0x120);
197 writel((u32
) regs
->fp
.r
.pt1
, par
->vid_regs
+ 0x400);
198 writel((u32
) regs
->fp
.r
.pt2
, par
->vid_regs
+ 0x408);
200 writel((u32
) regs
->fp
.r
.dfc
, par
->vid_regs
+ 0x418);
201 writel(regs
->fp
.r
.blfsr
, par
->vid_regs
+ 0x420);
202 writel(regs
->fp
.r
.rlfsr
, par
->vid_regs
+ 0x428);
203 writel(regs
->fp
.r
.fmi
, par
->vid_regs
+ 0x430);
204 writel(regs
->fp
.r
.fmd
, par
->vid_regs
+ 0x438);
205 writel(regs
->fp
.r
.dca
, par
->vid_regs
+ 0x448);
206 writel(regs
->fp
.r
.dmd
, par
->vid_regs
+ 0x450);
207 writel(regs
->fp
.r
.crc
, par
->vid_regs
+ 0x458);
208 writel(regs
->fp
.r
.fbb
, par
->vid_regs
+ 0x460);
212 val
= readl(par
->vid_regs
+ 0x410);
214 /* Control the panel */
215 if (regs
->fp
.r
.pm
& (1 << 24)) {
218 writel(regs
->fp
.r
.pm
, par
->vid_regs
+ 0x410);
222 writel(regs
->fp
.r
.pm
, par
->vid_regs
+ 0x410);
225 /* Turn everything on */
227 writel(regs
->dc
.r
.gcfg
, par
->dc_regs
+ 0x04);
228 writel((u32
) regs
->vp
.r
.vcfg
, par
->vid_regs
+ 0x00);
229 writel((u32
) regs
->vp
.r
.dcfg
, par
->vid_regs
+ 0x08);
230 writel(regs
->dc
.r
.dcfg
, par
->dc_regs
+ 0x08);
236 void dump_regs(struct fb_info
*info
, int mode
) {
238 struct geodefb_par
*par
= info
->par
;
243 for(i
= 0; i
< GP_REG_SIZE
; i
+= 4) {
244 val
= readl(par
->gp_regs
+ i
);
249 writel(0x4758, par
->dc_regs
+ 0x00);
251 for(i
= 0; i
< DC_REG_SIZE
; i
+= 4) {
252 val
= readl(par
->dc_regs
+ i
);
253 printk("DC%x: %x\n", i
, val
);
258 for(i
= 0; i
< VP_REG_SIZE
; i
+= 8) {
259 val
= readl(par
->vid_regs
+ i
);
260 printk("VP%x: %x\n", i
, val
);
265 for(i
= 0; i
< FP_REG_SIZE
; i
+= 8) {
266 val
= readl(par
->vid_regs
+ 0x400 + i
);
267 printk("FP%x: %x\n", i
, val
);