3 /* the accelerated functions here are patterned after the
4 * "ACCEL_MMIO" ifdef branches in XFree86
7 static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo,
8 const struct fb_fillrect *region)
12 OUTREG(DP_GUI_MASTER_CNTL,
13 rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */
14 | GMC_BRUSH_SOLID_COLOR
16 OUTREG(DP_BRUSH_FRGD_CLR, region->color);
17 OUTREG(DP_WRITE_MSK, 0xffffffff);
18 OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
21 OUTREG(DST_Y_X, (region->dy << 16) | region->dx);
22 OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height);
25 void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
27 struct radeonfb_info *rinfo = info->par;
28 struct fb_fillrect modded;
31 if (info->state != FBINFO_STATE_RUNNING)
33 if (radeon_accel_disabled()) {
34 cfb_fillrect(info, region);
38 vxres = info->var.xres;
39 vyres = info->var.yres;
41 memcpy(&modded, region, sizeof(struct fb_fillrect));
43 if(!modded.width || !modded.height ||
44 modded.dx >= vxres || modded.dy >= vyres)
47 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
48 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
50 radeonfb_prim_fillrect(rinfo, &modded);
53 static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo,
54 const struct fb_copyarea *area)
57 OUTREG(DP_GUI_MASTER_CNTL,
58 rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */
62 OUTREG(DP_WRITE_MSK, 0xffffffff);
63 OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
66 OUTREG(SRC_Y_X, (area->sy << 16) | area->sx);
67 OUTREG(DST_Y_X, (area->dy << 16) | area->dx);
68 OUTREG(DST_HEIGHT_WIDTH, (area->height << 16) | area->width);
72 void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
74 struct radeonfb_info *rinfo = info->par;
75 struct fb_copyarea modded;
81 modded.width = area->width;
82 modded.height = area->height;
84 if (info->state != FBINFO_STATE_RUNNING)
86 if (radeon_accel_disabled()) {
87 cfb_copyarea(info, area);
91 vxres = info->var.xres;
92 vyres = info->var.yres;
94 if(!modded.width || !modded.height ||
95 modded.sx >= vxres || modded.sy >= vyres ||
96 modded.dx >= vxres || modded.dy >= vyres)
99 if(modded.sx + modded.width > vxres) modded.width = vxres - modded.sx;
100 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
101 if(modded.sy + modded.height > vyres) modded.height = vyres - modded.sy;
102 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
104 radeonfb_prim_copyarea(rinfo, &modded);
107 void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image)
109 struct radeonfb_info *rinfo = info->par;
111 if (info->state != FBINFO_STATE_RUNNING)
113 radeon_engine_idle();
115 cfb_imageblit(info, image);
118 int radeonfb_sync(struct fb_info *info)
120 struct radeonfb_info *rinfo = info->par;
122 if (info->state != FBINFO_STATE_RUNNING)
124 radeon_engine_idle();
129 void radeonfb_engine_reset(struct radeonfb_info *rinfo)
131 u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
134 radeon_engine_flush (rinfo);
136 /* Some ASICs have bugs with dynamic-on feature, which are
137 * ASIC-version dependent, so we force all blocks on for now
139 * We don't do that on macs, things just work here with dynamic
142 #ifdef CONFIG_ALL_PPC
143 if (_machine != _MACH_Pmac && rinfo->hasCRTC2)
145 if (rinfo->has_CRTC2)
150 tmp = INPLL(SCLK_CNTL);
151 OUTPLL(SCLK_CNTL, ((tmp & ~DYN_STOP_LAT_MASK) |
152 CP_MAX_DYN_STOP_LAT |
155 if (rinfo->family == CHIP_FAMILY_RV200)
157 tmp = INPLL(SCLK_MORE_CNTL);
158 OUTPLL(SCLK_MORE_CNTL, tmp | SCLK_MORE_FORCEON);
162 clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
163 mclk_cntl = INPLL(MCLK_CNTL);
165 OUTPLL(MCLK_CNTL, (mclk_cntl |
173 host_path_cntl = INREG(HOST_PATH_CNTL);
174 rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
176 if (rinfo->family == CHIP_FAMILY_R300 ||
177 rinfo->family == CHIP_FAMILY_R350 ||
178 rinfo->family == CHIP_FAMILY_RV350) {
181 OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset |
185 INREG(RBBM_SOFT_RESET);
186 OUTREG(RBBM_SOFT_RESET, 0);
187 tmp = INREG(RB2D_DSTCACHE_MODE);
188 OUTREG(RB2D_DSTCACHE_MODE, tmp | (1 << 17)); /* FIXME */
190 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
198 INREG(RBBM_SOFT_RESET);
199 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
207 INREG(RBBM_SOFT_RESET);
210 OUTREG(HOST_PATH_CNTL, host_path_cntl | HDP_SOFT_RESET);
211 INREG(HOST_PATH_CNTL);
212 OUTREG(HOST_PATH_CNTL, host_path_cntl);
214 if (rinfo->family != CHIP_FAMILY_R300 ||
215 rinfo->family != CHIP_FAMILY_R350 ||
216 rinfo->family != CHIP_FAMILY_RV350)
217 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
219 OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
220 OUTPLL(MCLK_CNTL, mclk_cntl);
221 if (rinfo->R300_cg_workaround)
222 R300_cg_workardound(rinfo);
225 void radeonfb_engine_init (struct radeonfb_info *rinfo)
229 /* disable 3D engine */
230 OUTREG(RB3D_CNTL, 0);
232 radeonfb_engine_reset(rinfo);
234 radeon_fifo_wait (1);
235 if ((rinfo->family != CHIP_FAMILY_R300) &&
236 (rinfo->family != CHIP_FAMILY_R350) &&
237 (rinfo->family != CHIP_FAMILY_RV350))
238 OUTREG(RB2D_DSTCACHE_MODE, 0);
240 radeon_fifo_wait (3);
241 /* We re-read MC_FB_LOCATION from card as it can have been
242 * modified by XFree drivers (ouch !)
244 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
246 OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
247 (rinfo->fb_local_base >> 10));
248 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
249 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
251 radeon_fifo_wait (1);
252 #if defined(__BIG_ENDIAN)
253 OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
255 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
257 radeon_fifo_wait (2);
258 OUTREG(DEFAULT_SC_TOP_LEFT, 0);
259 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
260 DEFAULT_SC_BOTTOM_MAX));
262 temp = radeon_get_dstbpp(rinfo->depth);
263 rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
265 radeon_fifo_wait (1);
266 OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
267 GMC_BRUSH_SOLID_COLOR |
268 GMC_SRC_DATATYPE_COLOR));
270 radeon_fifo_wait (7);
272 /* clear line drawing regs */
273 OUTREG(DST_LINE_START, 0);
274 OUTREG(DST_LINE_END, 0);
276 /* set brush color regs */
277 OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
278 OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
280 /* set source color regs */
281 OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
282 OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
284 /* default write mask */
285 OUTREG(DP_WRITE_MSK, 0xffffffff);
287 radeon_engine_idle ();