Commit | Line | Data |
---|---|---|
026abc33 KS |
1 | /************************************************************************** |
2 | * Copyright (c) 2011, Intel Corporation. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms and conditions of the GNU General Public License, | |
7 | * version 2, as published by the Free Software Foundation. | |
8 | * | |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
12 | * more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along with | |
15 | * this program; if not, write to the Free Software Foundation, Inc., | |
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | |
17 | * | |
18 | **************************************************************************/ | |
19 | ||
20 | #include "psb_drv.h" | |
21 | #include "mid_bios.h" | |
22 | #include "mdfld_output.h" | |
23 | #include "mdfld_dsi_output.h" | |
24 | #include "tc35876x-dsi-lvds.h" | |
25 | ||
26 | #include <asm/intel_scu_ipc.h> | |
27 | ||
28 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE | |
29 | ||
30 | #define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF | |
31 | #define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ | |
32 | #define BLC_PWM_FREQ_CALC_CONSTANT 32 | |
33 | #define MHz 1000000 | |
34 | #define BRIGHTNESS_MIN_LEVEL 1 | |
35 | #define BRIGHTNESS_MAX_LEVEL 100 | |
36 | #define BRIGHTNESS_MASK 0xFF | |
37 | #define BLC_POLARITY_NORMAL 0 | |
38 | #define BLC_POLARITY_INVERSE 1 | |
39 | #define BLC_ADJUSTMENT_MAX 100 | |
40 | ||
41 | #define MDFLD_BLC_PWM_PRECISION_FACTOR 10 | |
42 | #define MDFLD_BLC_MAX_PWM_REG_FREQ 0xFFFE | |
43 | #define MDFLD_BLC_MIN_PWM_REG_FREQ 0x2 | |
44 | ||
45 | #define MDFLD_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) | |
46 | #define MDFLD_BACKLIGHT_PWM_CTL_SHIFT (16) | |
47 | ||
48 | static struct backlight_device *mdfld_backlight_device; | |
49 | ||
50 | int mdfld_set_brightness(struct backlight_device *bd) | |
51 | { | |
52 | struct drm_device *dev = | |
53 | (struct drm_device *)bl_get_data(mdfld_backlight_device); | |
54 | struct drm_psb_private *dev_priv = dev->dev_private; | |
55 | int level = bd->props.brightness; | |
56 | ||
57 | DRM_DEBUG_DRIVER("backlight level set to %d\n", level); | |
58 | ||
59 | /* Perform value bounds checking */ | |
60 | if (level < BRIGHTNESS_MIN_LEVEL) | |
61 | level = BRIGHTNESS_MIN_LEVEL; | |
62 | ||
63 | if (gma_power_begin(dev, false)) { | |
64 | u32 adjusted_level = 0; | |
65 | ||
66 | /* | |
67 | * Adjust the backlight level with the percent in | |
68 | * dev_priv->blc_adj2 | |
69 | */ | |
70 | adjusted_level = level * dev_priv->blc_adj2; | |
71 | adjusted_level = adjusted_level / BLC_ADJUSTMENT_MAX; | |
72 | dev_priv->brightness_adjusted = adjusted_level; | |
73 | ||
74 | if (mdfld_get_panel_type(dev, 0) == TC35876X) { | |
75 | if (dev_priv->dpi_panel_on[0] || | |
76 | dev_priv->dpi_panel_on[2]) | |
77 | tc35876x_brightness_control(dev, | |
78 | dev_priv->brightness_adjusted); | |
79 | } else { | |
80 | if (dev_priv->dpi_panel_on[0]) | |
81 | mdfld_dsi_brightness_control(dev, 0, | |
82 | dev_priv->brightness_adjusted); | |
83 | } | |
84 | ||
85 | if (dev_priv->dpi_panel_on[2]) | |
86 | mdfld_dsi_brightness_control(dev, 2, | |
87 | dev_priv->brightness_adjusted); | |
88 | gma_power_end(dev); | |
89 | } | |
90 | ||
91 | /* cache the brightness for later use */ | |
92 | dev_priv->brightness = level; | |
93 | return 0; | |
94 | } | |
95 | ||
1c6a6268 | 96 | static int mdfld_get_brightness(struct backlight_device *bd) |
026abc33 KS |
97 | { |
98 | struct drm_device *dev = | |
99 | (struct drm_device *)bl_get_data(mdfld_backlight_device); | |
100 | struct drm_psb_private *dev_priv = dev->dev_private; | |
101 | ||
102 | DRM_DEBUG_DRIVER("brightness = 0x%x \n", dev_priv->brightness); | |
103 | ||
104 | /* return locally cached var instead of HW read (due to DPST etc.) */ | |
105 | return dev_priv->brightness; | |
106 | } | |
107 | ||
108 | static const struct backlight_ops mdfld_ops = { | |
109 | .get_brightness = mdfld_get_brightness, | |
110 | .update_status = mdfld_set_brightness, | |
111 | }; | |
112 | ||
113 | static int device_backlight_init(struct drm_device *dev) | |
114 | { | |
115 | struct drm_psb_private *dev_priv = (struct drm_psb_private *) | |
116 | dev->dev_private; | |
117 | ||
118 | dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX; | |
119 | dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX; | |
120 | ||
121 | return 0; | |
122 | } | |
123 | ||
1c6a6268 | 124 | static int mdfld_backlight_init(struct drm_device *dev) |
026abc33 KS |
125 | { |
126 | struct backlight_properties props; | |
127 | int ret = 0; | |
128 | ||
129 | memset(&props, 0, sizeof(struct backlight_properties)); | |
130 | props.max_brightness = BRIGHTNESS_MAX_LEVEL; | |
131 | props.type = BACKLIGHT_PLATFORM; | |
132 | mdfld_backlight_device = backlight_device_register("mdfld-bl", | |
133 | NULL, (void *)dev, &mdfld_ops, &props); | |
134 | ||
135 | if (IS_ERR(mdfld_backlight_device)) | |
136 | return PTR_ERR(mdfld_backlight_device); | |
137 | ||
138 | ret = device_backlight_init(dev); | |
139 | if (ret) | |
140 | return ret; | |
141 | ||
142 | mdfld_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL; | |
143 | mdfld_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL; | |
144 | backlight_update_status(mdfld_backlight_device); | |
145 | return 0; | |
146 | } | |
147 | #endif | |
148 | ||
149 | struct backlight_device *mdfld_get_backlight_device(void) | |
150 | { | |
151 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE | |
152 | return mdfld_backlight_device; | |
153 | #else | |
154 | return NULL; | |
155 | #endif | |
156 | } | |
157 | ||
158 | /* | |
159 | * mdfld_save_display_registers | |
160 | * | |
161 | * Description: We are going to suspend so save current display | |
162 | * register state. | |
163 | * | |
164 | * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio | |
165 | */ | |
6256304b | 166 | static int mdfld_save_display_registers(struct drm_device *dev, int pipenum) |
026abc33 KS |
167 | { |
168 | struct drm_psb_private *dev_priv = dev->dev_private; | |
169 | struct medfield_state *regs = &dev_priv->regs.mdfld; | |
6256304b | 170 | struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum]; |
213a8434 | 171 | const struct psb_offset *map = &dev_priv->regmap[pipenum]; |
026abc33 | 172 | int i; |
f693dfb7 | 173 | u32 *mipi_val; |
026abc33 KS |
174 | |
175 | /* register */ | |
026abc33 | 176 | u32 mipi_reg = MIPI; |
026abc33 | 177 | |
6256304b | 178 | switch (pipenum) { |
026abc33 | 179 | case 0: |
f693dfb7 | 180 | mipi_val = ®s->saveMIPI; |
026abc33 KS |
181 | break; |
182 | case 1: | |
f693dfb7 | 183 | mipi_val = ®s->saveMIPI; |
026abc33 KS |
184 | break; |
185 | case 2: | |
186 | /* register */ | |
026abc33 | 187 | mipi_reg = MIPI_C; |
026abc33 | 188 | /* pointer to values */ |
026abc33 | 189 | mipi_val = ®s->saveMIPI_C; |
026abc33 KS |
190 | break; |
191 | default: | |
192 | DRM_ERROR("%s, invalid pipe number.\n", __func__); | |
193 | return -EINVAL; | |
194 | } | |
195 | ||
196 | /* Pipe & plane A info */ | |
213a8434 AC |
197 | pipe->dpll = PSB_RVDC32(map->dpll); |
198 | pipe->fp0 = PSB_RVDC32(map->fp0); | |
199 | pipe->conf = PSB_RVDC32(map->conf); | |
200 | pipe->htotal = PSB_RVDC32(map->htotal); | |
201 | pipe->hblank = PSB_RVDC32(map->hblank); | |
202 | pipe->hsync = PSB_RVDC32(map->hsync); | |
203 | pipe->vtotal = PSB_RVDC32(map->vtotal); | |
204 | pipe->vblank = PSB_RVDC32(map->vblank); | |
205 | pipe->vsync = PSB_RVDC32(map->vsync); | |
206 | pipe->src = PSB_RVDC32(map->src); | |
207 | pipe->stride = PSB_RVDC32(map->stride); | |
208 | pipe->linoff = PSB_RVDC32(map->linoff); | |
209 | pipe->tileoff = PSB_RVDC32(map->tileoff); | |
210 | pipe->size = PSB_RVDC32(map->size); | |
211 | pipe->pos = PSB_RVDC32(map->pos); | |
212 | pipe->surf = PSB_RVDC32(map->surf); | |
213 | pipe->cntr = PSB_RVDC32(map->cntr); | |
214 | pipe->status = PSB_RVDC32(map->status); | |
026abc33 KS |
215 | |
216 | /*save palette (gamma) */ | |
217 | for (i = 0; i < 256; i++) | |
213a8434 | 218 | pipe->palette[i] = PSB_RVDC32(map->palette + (i << 2)); |
026abc33 | 219 | |
6256304b | 220 | if (pipenum == 1) { |
026abc33 KS |
221 | regs->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); |
222 | regs->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); | |
223 | ||
224 | regs->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL); | |
225 | regs->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL); | |
226 | return 0; | |
227 | } | |
228 | ||
229 | *mipi_val = PSB_RVDC32(mipi_reg); | |
230 | return 0; | |
231 | } | |
232 | ||
233 | /* | |
234 | * mdfld_restore_display_registers | |
235 | * | |
236 | * Description: We are going to resume so restore display register state. | |
237 | * | |
238 | * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio | |
239 | */ | |
6256304b | 240 | static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) |
026abc33 KS |
241 | { |
242 | /* To get panel out of ULPS mode. */ | |
243 | u32 temp = 0; | |
244 | u32 device_ready_reg = DEVICE_READY_REG; | |
245 | struct drm_psb_private *dev_priv = dev->dev_private; | |
246 | struct mdfld_dsi_config *dsi_config = NULL; | |
247 | struct medfield_state *regs = &dev_priv->regs.mdfld; | |
6256304b | 248 | struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum]; |
213a8434 | 249 | const struct psb_offset *map = &dev_priv->regmap[pipenum]; |
f693dfb7 AC |
250 | u32 i; |
251 | u32 dpll; | |
026abc33 KS |
252 | u32 timeout = 0; |
253 | ||
6256304b | 254 | /* register */ |
026abc33 | 255 | u32 mipi_reg = MIPI; |
026abc33 KS |
256 | |
257 | /* values */ | |
6256304b | 258 | u32 dpll_val = pipe->dpll; |
026abc33 | 259 | u32 mipi_val = regs->saveMIPI; |
026abc33 | 260 | |
6256304b | 261 | switch (pipenum) { |
026abc33 | 262 | case 0: |
6256304b | 263 | dpll_val &= ~DPLL_VCO_ENABLE; |
026abc33 KS |
264 | dsi_config = dev_priv->dsi_configs[0]; |
265 | break; | |
266 | case 1: | |
6256304b | 267 | dpll_val &= ~DPLL_VCO_ENABLE; |
026abc33 KS |
268 | break; |
269 | case 2: | |
026abc33 | 270 | mipi_reg = MIPI_C; |
026abc33 | 271 | mipi_val = regs->saveMIPI_C; |
026abc33 KS |
272 | dsi_config = dev_priv->dsi_configs[1]; |
273 | break; | |
274 | default: | |
275 | DRM_ERROR("%s, invalid pipe number.\n", __func__); | |
276 | return -EINVAL; | |
277 | } | |
278 | ||
279 | /*make sure VGA plane is off. it initializes to on after reset!*/ | |
280 | PSB_WVDC32(0x80000000, VGACNTRL); | |
281 | ||
6256304b | 282 | if (pipenum == 1) { |
213a8434 AC |
283 | PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, map->dpll); |
284 | PSB_RVDC32(map->dpll); | |
026abc33 | 285 | |
213a8434 | 286 | PSB_WVDC32(pipe->fp0, map->fp0); |
026abc33 KS |
287 | } else { |
288 | ||
213a8434 | 289 | dpll = PSB_RVDC32(map->dpll); |
026abc33 KS |
290 | |
291 | if (!(dpll & DPLL_VCO_ENABLE)) { | |
292 | ||
293 | /* When ungating power of DPLL, needs to wait 0.5us | |
294 | before enable the VCO */ | |
295 | if (dpll & MDFLD_PWR_GATE_EN) { | |
296 | dpll &= ~MDFLD_PWR_GATE_EN; | |
213a8434 | 297 | PSB_WVDC32(dpll, map->dpll); |
026abc33 KS |
298 | /* FIXME_MDFLD PO - change 500 to 1 after PO */ |
299 | udelay(500); | |
300 | } | |
301 | ||
213a8434 AC |
302 | PSB_WVDC32(pipe->fp0, map->fp0); |
303 | PSB_WVDC32(dpll_val, map->dpll); | |
026abc33 KS |
304 | /* FIXME_MDFLD PO - change 500 to 1 after PO */ |
305 | udelay(500); | |
306 | ||
307 | dpll_val |= DPLL_VCO_ENABLE; | |
213a8434 AC |
308 | PSB_WVDC32(dpll_val, map->dpll); |
309 | PSB_RVDC32(map->dpll); | |
026abc33 KS |
310 | |
311 | /* wait for DSI PLL to lock */ | |
312 | while (timeout < 20000 && | |
213a8434 | 313 | !(PSB_RVDC32(map->conf) & PIPECONF_DSIPLL_LOCK)) { |
026abc33 KS |
314 | udelay(150); |
315 | timeout++; | |
316 | } | |
317 | ||
318 | if (timeout == 20000) { | |
319 | DRM_ERROR("%s, can't lock DSIPLL.\n", | |
320 | __func__); | |
321 | return -EINVAL; | |
322 | } | |
323 | } | |
324 | } | |
325 | /* Restore mode */ | |
213a8434 AC |
326 | PSB_WVDC32(pipe->htotal, map->htotal); |
327 | PSB_WVDC32(pipe->hblank, map->hblank); | |
328 | PSB_WVDC32(pipe->hsync, map->hsync); | |
329 | PSB_WVDC32(pipe->vtotal, map->vtotal); | |
330 | PSB_WVDC32(pipe->vblank, map->vblank); | |
331 | PSB_WVDC32(pipe->vsync, map->vsync); | |
332 | PSB_WVDC32(pipe->src, map->src); | |
333 | PSB_WVDC32(pipe->status, map->status); | |
026abc33 KS |
334 | |
335 | /*set up the plane*/ | |
213a8434 AC |
336 | PSB_WVDC32(pipe->stride, map->stride); |
337 | PSB_WVDC32(pipe->linoff, map->linoff); | |
338 | PSB_WVDC32(pipe->tileoff, map->tileoff); | |
339 | PSB_WVDC32(pipe->size, map->size); | |
340 | PSB_WVDC32(pipe->pos, map->pos); | |
341 | PSB_WVDC32(pipe->surf, map->surf); | |
026abc33 | 342 | |
6256304b | 343 | if (pipenum == 1) { |
026abc33 KS |
344 | /* restore palette (gamma) */ |
345 | /*DRM_UDELAY(50000); */ | |
346 | for (i = 0; i < 256; i++) | |
213a8434 | 347 | PSB_WVDC32(pipe->palette[i], map->palette + (i << 2)); |
026abc33 KS |
348 | |
349 | PSB_WVDC32(regs->savePFIT_CONTROL, PFIT_CONTROL); | |
350 | PSB_WVDC32(regs->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); | |
351 | ||
352 | /*TODO: resume HDMI port */ | |
353 | ||
354 | /*TODO: resume pipe*/ | |
355 | ||
356 | /*enable the plane*/ | |
213a8434 | 357 | PSB_WVDC32(pipe->cntr & ~DISPLAY_PLANE_ENABLE, map->cntr); |
026abc33 KS |
358 | |
359 | return 0; | |
360 | } | |
361 | ||
362 | /*set up pipe related registers*/ | |
363 | PSB_WVDC32(mipi_val, mipi_reg); | |
364 | ||
365 | /*setup MIPI adapter + MIPI IP registers*/ | |
366 | if (dsi_config) | |
6256304b | 367 | mdfld_dsi_controller_init(dsi_config, pipenum); |
026abc33 KS |
368 | |
369 | if (in_atomic() || in_interrupt()) | |
370 | mdelay(20); | |
371 | else | |
372 | msleep(20); | |
373 | ||
374 | /*enable the plane*/ | |
213a8434 | 375 | PSB_WVDC32(pipe->cntr, map->cntr); |
026abc33 KS |
376 | |
377 | if (in_atomic() || in_interrupt()) | |
378 | mdelay(20); | |
379 | else | |
380 | msleep(20); | |
381 | ||
382 | /* LP Hold Release */ | |
383 | temp = REG_READ(mipi_reg); | |
384 | temp |= LP_OUTPUT_HOLD_RELEASE; | |
385 | REG_WRITE(mipi_reg, temp); | |
386 | mdelay(1); | |
387 | ||
388 | ||
389 | /* Set DSI host to exit from Utra Low Power State */ | |
390 | temp = REG_READ(device_ready_reg); | |
391 | temp &= ~ULPS_MASK; | |
392 | temp |= 0x3; | |
393 | temp |= EXIT_ULPS_DEV_READY; | |
394 | REG_WRITE(device_ready_reg, temp); | |
395 | mdelay(1); | |
396 | ||
397 | temp = REG_READ(device_ready_reg); | |
398 | temp &= ~ULPS_MASK; | |
399 | temp |= EXITING_ULPS; | |
400 | REG_WRITE(device_ready_reg, temp); | |
401 | mdelay(1); | |
402 | ||
403 | /*enable the pipe*/ | |
213a8434 | 404 | PSB_WVDC32(pipe->conf, map->conf); |
026abc33 KS |
405 | |
406 | /* restore palette (gamma) */ | |
407 | /*DRM_UDELAY(50000); */ | |
408 | for (i = 0; i < 256; i++) | |
213a8434 | 409 | PSB_WVDC32(pipe->palette[i], map->palette + (i << 2)); |
026abc33 KS |
410 | |
411 | return 0; | |
412 | } | |
413 | ||
414 | static int mdfld_save_registers(struct drm_device *dev) | |
415 | { | |
416 | /* mdfld_save_cursor_overlay_registers(dev); */ | |
417 | mdfld_save_display_registers(dev, 0); | |
418 | mdfld_save_display_registers(dev, 2); | |
419 | mdfld_disable_crtc(dev, 0); | |
420 | mdfld_disable_crtc(dev, 2); | |
421 | ||
422 | return 0; | |
423 | } | |
424 | ||
425 | static int mdfld_restore_registers(struct drm_device *dev) | |
426 | { | |
427 | mdfld_restore_display_registers(dev, 2); | |
428 | mdfld_restore_display_registers(dev, 0); | |
429 | /* mdfld_restore_cursor_overlay_registers(dev); */ | |
430 | ||
431 | return 0; | |
432 | } | |
433 | ||
434 | static int mdfld_power_down(struct drm_device *dev) | |
435 | { | |
436 | /* FIXME */ | |
437 | return 0; | |
438 | } | |
439 | ||
440 | static int mdfld_power_up(struct drm_device *dev) | |
441 | { | |
442 | /* FIXME */ | |
443 | return 0; | |
444 | } | |
445 | ||
8512e074 AC |
446 | /* Medfield */ |
447 | static const struct psb_offset mdfld_regmap[3] = { | |
448 | { | |
449 | .fp0 = MRST_FPA0, | |
450 | .fp1 = MRST_FPA1, | |
451 | .cntr = DSPACNTR, | |
452 | .conf = PIPEACONF, | |
453 | .src = PIPEASRC, | |
454 | .dpll = MRST_DPLL_A, | |
455 | .htotal = HTOTAL_A, | |
456 | .hblank = HBLANK_A, | |
457 | .hsync = HSYNC_A, | |
458 | .vtotal = VTOTAL_A, | |
459 | .vblank = VBLANK_A, | |
460 | .vsync = VSYNC_A, | |
461 | .stride = DSPASTRIDE, | |
462 | .size = DSPASIZE, | |
463 | .pos = DSPAPOS, | |
464 | .surf = DSPASURF, | |
213a8434 | 465 | .addr = MRST_DSPABASE, |
8512e074 AC |
466 | .status = PIPEASTAT, |
467 | .linoff = DSPALINOFF, | |
468 | .tileoff = DSPATILEOFF, | |
469 | .palette = PALETTE_A, | |
470 | }, | |
471 | { | |
472 | .fp0 = MDFLD_DPLL_DIV0, | |
473 | .cntr = DSPBCNTR, | |
474 | .conf = PIPEBCONF, | |
475 | .src = PIPEBSRC, | |
476 | .dpll = MDFLD_DPLL_B, | |
477 | .htotal = HTOTAL_B, | |
478 | .hblank = HBLANK_B, | |
479 | .hsync = HSYNC_B, | |
480 | .vtotal = VTOTAL_B, | |
481 | .vblank = VBLANK_B, | |
482 | .vsync = VSYNC_B, | |
483 | .stride = DSPBSTRIDE, | |
484 | .size = DSPBSIZE, | |
485 | .pos = DSPBPOS, | |
486 | .surf = DSPBSURF, | |
213a8434 | 487 | .addr = MRST_DSPBBASE, |
8512e074 AC |
488 | .status = PIPEBSTAT, |
489 | .linoff = DSPBLINOFF, | |
490 | .tileoff = DSPBTILEOFF, | |
491 | .palette = PALETTE_B, | |
492 | }, | |
493 | { | |
213a8434 | 494 | .fp0 = MRST_FPA0, /* This is what the old code did ?? */ |
8512e074 AC |
495 | .cntr = DSPCCNTR, |
496 | .conf = PIPECCONF, | |
497 | .src = PIPECSRC, | |
498 | /* No DPLL_C */ | |
499 | .dpll = MRST_DPLL_A, | |
500 | .htotal = HTOTAL_C, | |
501 | .hblank = HBLANK_C, | |
502 | .hsync = HSYNC_C, | |
503 | .vtotal = VTOTAL_C, | |
504 | .vblank = VBLANK_C, | |
505 | .vsync = VSYNC_C, | |
506 | .stride = DSPCSTRIDE, | |
507 | .size = DSPBSIZE, | |
508 | .pos = DSPCPOS, | |
509 | .surf = DSPCSURF, | |
213a8434 | 510 | .addr = MDFLD_DSPCBASE, |
8512e074 AC |
511 | .status = PIPECSTAT, |
512 | .linoff = DSPCLINOFF, | |
513 | .tileoff = DSPCTILEOFF, | |
514 | .palette = PALETTE_C, | |
515 | }, | |
516 | }; | |
517 | ||
518 | static int mdfld_chip_setup(struct drm_device *dev) | |
519 | { | |
520 | struct drm_psb_private *dev_priv = dev->dev_private; | |
9c0b6fcd AC |
521 | if (pci_enable_msi(dev->pdev)) |
522 | dev_warn(dev->dev, "Enabling MSI failed!\n"); | |
8512e074 AC |
523 | dev_priv->regmap = mdfld_regmap; |
524 | return mid_chip_setup(dev); | |
525 | } | |
526 | ||
026abc33 KS |
527 | const struct psb_ops mdfld_chip_ops = { |
528 | .name = "mdfld", | |
529 | .accel_2d = 0, | |
530 | .pipes = 3, | |
531 | .crtcs = 3, | |
87438494 PJ |
532 | .lvds_mask = (1 << 1), |
533 | .hdmi_mask = (1 << 1), | |
bc794829 | 534 | .cursor_needs_phys = 0, |
026abc33 KS |
535 | .sgx_offset = MRST_SGX_OFFSET, |
536 | ||
8512e074 | 537 | .chip_setup = mdfld_chip_setup, |
026abc33 KS |
538 | .crtc_helper = &mdfld_helper_funcs, |
539 | .crtc_funcs = &psb_intel_crtc_funcs, | |
540 | ||
541 | .output_init = mdfld_output_init, | |
542 | ||
543 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE | |
544 | .backlight_init = mdfld_backlight_init, | |
545 | #endif | |
546 | ||
547 | .save_regs = mdfld_save_registers, | |
548 | .restore_regs = mdfld_restore_registers, | |
549 | .power_down = mdfld_power_down, | |
550 | .power_up = mdfld_power_up, | |
551 | }; |