1 /**************************************************************************
2 * Copyright (c) 2011, Intel Corporation.
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.
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
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.
18 **************************************************************************/
20 #include <linux/backlight.h>
21 #include <linux/module.h>
22 #include <linux/dmi.h>
28 #include "psb_intel_reg.h"
30 #include <asm/intel_scu_ipc.h>
35 module_param_named(type
, devtype
, int, 0600);
36 MODULE_PARM_DESC(type
, "Moorestown/Oaktrail device type");
38 #define DEVICE_MOORESTOWN 1
39 #define DEVICE_OAKTRAIL 2
40 #define DEVICE_MOORESTOWN_MM 3
42 static int mrst_device_ident(struct drm_device
*dev
)
47 if (dmi_match(DMI_PRODUCT_NAME
, "OakTrail") ||
48 dmi_match(DMI_PRODUCT_NAME
, "OakTrail platform"))
49 return DEVICE_OAKTRAIL
;
50 #if defined(CONFIG_X86_MRST)
51 if (dmi_match(DMI_PRODUCT_NAME
, "MM") ||
52 dmi_match(DMI_PRODUCT_NAME
, "MM 10"))
53 return DEVICE_MOORESTOWN_MM
;
54 if (mrst_identify_cpu())
55 return DEVICE_MOORESTOWN
;
57 return DEVICE_OAKTRAIL
;
61 /* IPC message and command defines used to enable/disable mipi panel voltages */
62 #define IPC_MSG_PANEL_ON_OFF 0xE9
63 #define IPC_CMD_PANEL_ON 1
64 #define IPC_CMD_PANEL_OFF 0
66 static int mrst_output_init(struct drm_device
*dev
)
68 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
69 if (dev_priv
->iLVDS_enable
)
70 mrst_lvds_init(dev
, &dev_priv
->mode_dev
);
72 dev_err(dev
->dev
, "DSI is not supported\n");
73 if (dev_priv
->hdmi_priv
)
74 mrst_hdmi_init(dev
, &dev_priv
->mode_dev
);
79 * Provide the low level interfaces for the Moorestown backlight
82 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
84 #define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF
85 #define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
86 #define BLC_PWM_FREQ_CALC_CONSTANT 32
88 #define BLC_ADJUSTMENT_MAX 100
90 static struct backlight_device
*mrst_backlight_device
;
91 static int mrst_brightness
;
93 static int mrst_set_brightness(struct backlight_device
*bd
)
95 struct drm_device
*dev
= bl_get_data(mrst_backlight_device
);
96 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
97 int level
= bd
->props
.brightness
;
101 /* Percentage 1-100% being valid */
105 if (gma_power_begin(dev
, 0)) {
106 /* Calculate and set the brightness value */
107 max_pwm_blc
= REG_READ(BLC_PWM_CTL
) >> 16;
108 blc_pwm_ctl
= level
* max_pwm_blc
/ 100;
110 /* Adjust the backlight level with the percent in
111 * dev_priv->blc_adj1;
113 blc_pwm_ctl
= blc_pwm_ctl
* dev_priv
->blc_adj1
;
114 blc_pwm_ctl
= blc_pwm_ctl
/ 100;
116 /* Adjust the backlight level with the percent in
117 * dev_priv->blc_adj2;
119 blc_pwm_ctl
= blc_pwm_ctl
* dev_priv
->blc_adj2
;
120 blc_pwm_ctl
= blc_pwm_ctl
/ 100;
122 /* force PWM bit on */
123 REG_WRITE(BLC_PWM_CTL2
, (0x80000000 | REG_READ(BLC_PWM_CTL2
)));
124 REG_WRITE(BLC_PWM_CTL
, (max_pwm_blc
<< 16) | blc_pwm_ctl
);
127 mrst_brightness
= level
;
131 static int mrst_get_brightness(struct backlight_device
*bd
)
133 /* return locally cached var instead of HW read (due to DPST etc.) */
134 /* FIXME: ideally return actual value in case firmware fiddled with
136 return mrst_brightness
;
139 static int device_backlight_init(struct drm_device
*dev
)
141 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
142 unsigned long core_clock
;
145 uint32_t blc_pwm_precision_factor
;
147 dev_priv
->blc_adj1
= BLC_ADJUSTMENT_MAX
;
148 dev_priv
->blc_adj2
= BLC_ADJUSTMENT_MAX
;
150 /* this needs to be set elsewhere */
151 blc_pwm_precision_factor
= BLC_PWM_PRECISION_FACTOR
;
153 core_clock
= dev_priv
->core_freq
;
155 value
= (core_clock
* MHz
) / BLC_PWM_FREQ_CALC_CONSTANT
;
156 value
*= blc_pwm_precision_factor
;
157 value
/= bl_max_freq
;
158 value
/= blc_pwm_precision_factor
;
160 if (value
> (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ
)
163 if (gma_power_begin(dev
, false)) {
164 REG_WRITE(BLC_PWM_CTL2
, (0x80000000 | REG_READ(BLC_PWM_CTL2
)));
165 REG_WRITE(BLC_PWM_CTL
, value
| (value
<< 16));
171 static const struct backlight_ops mrst_ops
= {
172 .get_brightness
= mrst_get_brightness
,
173 .update_status
= mrst_set_brightness
,
176 int mrst_backlight_init(struct drm_device
*dev
)
178 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
180 struct backlight_properties props
;
182 memset(&props
, 0, sizeof(struct backlight_properties
));
183 props
.max_brightness
= 100;
184 props
.type
= BACKLIGHT_PLATFORM
;
186 mrst_backlight_device
= backlight_device_register("mrst-bl",
187 NULL
, (void *)dev
, &mrst_ops
, &props
);
189 if (IS_ERR(mrst_backlight_device
))
190 return PTR_ERR(mrst_backlight_device
);
192 ret
= device_backlight_init(dev
);
194 backlight_device_unregister(mrst_backlight_device
);
197 mrst_backlight_device
->props
.brightness
= 100;
198 mrst_backlight_device
->props
.max_brightness
= 100;
199 backlight_update_status(mrst_backlight_device
);
200 dev_priv
->backlight_device
= mrst_backlight_device
;
207 * Provide the Moorestown specific chip logic and low level methods
208 * for power management
211 static void mrst_init_pm(struct drm_device
*dev
)
216 * mrst_save_display_registers - save registers lost on suspend
217 * @dev: our DRM device
219 * Save the state we need in order to be able to restore the interface
220 * upon resume from suspend
222 static int mrst_save_display_registers(struct drm_device
*dev
)
224 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
228 /* Display arbitration control + watermarks */
229 dev_priv
->saveDSPARB
= PSB_RVDC32(DSPARB
);
230 dev_priv
->saveDSPFW1
= PSB_RVDC32(DSPFW1
);
231 dev_priv
->saveDSPFW2
= PSB_RVDC32(DSPFW2
);
232 dev_priv
->saveDSPFW3
= PSB_RVDC32(DSPFW3
);
233 dev_priv
->saveDSPFW4
= PSB_RVDC32(DSPFW4
);
234 dev_priv
->saveDSPFW5
= PSB_RVDC32(DSPFW5
);
235 dev_priv
->saveDSPFW6
= PSB_RVDC32(DSPFW6
);
236 dev_priv
->saveCHICKENBIT
= PSB_RVDC32(DSPCHICKENBIT
);
238 /* Pipe & plane A info */
239 dev_priv
->savePIPEACONF
= PSB_RVDC32(PIPEACONF
);
240 dev_priv
->savePIPEASRC
= PSB_RVDC32(PIPEASRC
);
241 dev_priv
->saveFPA0
= PSB_RVDC32(MRST_FPA0
);
242 dev_priv
->saveFPA1
= PSB_RVDC32(MRST_FPA1
);
243 dev_priv
->saveDPLL_A
= PSB_RVDC32(MRST_DPLL_A
);
244 dev_priv
->saveHTOTAL_A
= PSB_RVDC32(HTOTAL_A
);
245 dev_priv
->saveHBLANK_A
= PSB_RVDC32(HBLANK_A
);
246 dev_priv
->saveHSYNC_A
= PSB_RVDC32(HSYNC_A
);
247 dev_priv
->saveVTOTAL_A
= PSB_RVDC32(VTOTAL_A
);
248 dev_priv
->saveVBLANK_A
= PSB_RVDC32(VBLANK_A
);
249 dev_priv
->saveVSYNC_A
= PSB_RVDC32(VSYNC_A
);
250 dev_priv
->saveBCLRPAT_A
= PSB_RVDC32(BCLRPAT_A
);
251 dev_priv
->saveDSPACNTR
= PSB_RVDC32(DSPACNTR
);
252 dev_priv
->saveDSPASTRIDE
= PSB_RVDC32(DSPASTRIDE
);
253 dev_priv
->saveDSPAADDR
= PSB_RVDC32(DSPABASE
);
254 dev_priv
->saveDSPASURF
= PSB_RVDC32(DSPASURF
);
255 dev_priv
->saveDSPALINOFF
= PSB_RVDC32(DSPALINOFF
);
256 dev_priv
->saveDSPATILEOFF
= PSB_RVDC32(DSPATILEOFF
);
258 /* Save cursor regs */
259 dev_priv
->saveDSPACURSOR_CTRL
= PSB_RVDC32(CURACNTR
);
260 dev_priv
->saveDSPACURSOR_BASE
= PSB_RVDC32(CURABASE
);
261 dev_priv
->saveDSPACURSOR_POS
= PSB_RVDC32(CURAPOS
);
263 /* Save palette (gamma) */
264 for (i
= 0; i
< 256; i
++)
265 dev_priv
->save_palette_a
[i
] = PSB_RVDC32(PALETTE_A
+ (i
<< 2));
267 if (dev_priv
->hdmi_priv
)
270 /* Save performance state */
271 dev_priv
->savePERF_MODE
= PSB_RVDC32(MRST_PERF_MODE
);
274 dev_priv
->savePP_CONTROL
= PSB_RVDC32(PP_CONTROL
);
275 dev_priv
->savePFIT_PGM_RATIOS
= PSB_RVDC32(PFIT_PGM_RATIOS
);
276 dev_priv
->savePFIT_AUTO_RATIOS
= PSB_RVDC32(PFIT_AUTO_RATIOS
);
277 dev_priv
->saveBLC_PWM_CTL
= PSB_RVDC32(BLC_PWM_CTL
);
278 dev_priv
->saveBLC_PWM_CTL2
= PSB_RVDC32(BLC_PWM_CTL2
);
279 dev_priv
->saveLVDS
= PSB_RVDC32(LVDS
);
280 dev_priv
->savePFIT_CONTROL
= PSB_RVDC32(PFIT_CONTROL
);
281 dev_priv
->savePP_ON_DELAYS
= PSB_RVDC32(LVDSPP_ON
);
282 dev_priv
->savePP_OFF_DELAYS
= PSB_RVDC32(LVDSPP_OFF
);
283 dev_priv
->savePP_DIVISOR
= PSB_RVDC32(PP_CYCLE
);
286 dev_priv
->saveOV_OVADD
= PSB_RVDC32(OV_OVADD
);
287 dev_priv
->saveOV_OGAMC0
= PSB_RVDC32(OV_OGAMC0
);
288 dev_priv
->saveOV_OGAMC1
= PSB_RVDC32(OV_OGAMC1
);
289 dev_priv
->saveOV_OGAMC2
= PSB_RVDC32(OV_OGAMC2
);
290 dev_priv
->saveOV_OGAMC3
= PSB_RVDC32(OV_OGAMC3
);
291 dev_priv
->saveOV_OGAMC4
= PSB_RVDC32(OV_OGAMC4
);
292 dev_priv
->saveOV_OGAMC5
= PSB_RVDC32(OV_OGAMC5
);
295 dev_priv
->saveHISTOGRAM_INT_CONTROL_REG
=
296 PSB_RVDC32(HISTOGRAM_INT_CONTROL
);
297 dev_priv
->saveHISTOGRAM_LOGIC_CONTROL_REG
=
298 PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL
);
299 dev_priv
->savePWM_CONTROL_LOGIC
= PSB_RVDC32(PWM_CONTROL_LOGIC
);
301 if (dev_priv
->iLVDS_enable
) {
302 /* Shut down the panel */
303 PSB_WVDC32(0, PP_CONTROL
);
306 pp_stat
= PSB_RVDC32(PP_STATUS
);
307 } while (pp_stat
& 0x80000000);
309 /* Turn off the plane */
310 PSB_WVDC32(0x58000000, DSPACNTR
);
311 /* Trigger the plane disable */
312 PSB_WVDC32(0, DSPASURF
);
318 PSB_WVDC32(0x0, PIPEACONF
);
323 PSB_WVDC32(0, MRST_DPLL_A
);
329 * mrst_restore_display_registers - restore lost register state
330 * @dev: our DRM device
332 * Restore register state that was lost during suspend and resume.
334 static int mrst_restore_display_registers(struct drm_device
*dev
)
336 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
340 /* Display arbitration + watermarks */
341 PSB_WVDC32(dev_priv
->saveDSPARB
, DSPARB
);
342 PSB_WVDC32(dev_priv
->saveDSPFW1
, DSPFW1
);
343 PSB_WVDC32(dev_priv
->saveDSPFW2
, DSPFW2
);
344 PSB_WVDC32(dev_priv
->saveDSPFW3
, DSPFW3
);
345 PSB_WVDC32(dev_priv
->saveDSPFW4
, DSPFW4
);
346 PSB_WVDC32(dev_priv
->saveDSPFW5
, DSPFW5
);
347 PSB_WVDC32(dev_priv
->saveDSPFW6
, DSPFW6
);
348 PSB_WVDC32(dev_priv
->saveCHICKENBIT
, DSPCHICKENBIT
);
350 /* Make sure VGA plane is off. it initializes to on after reset!*/
351 PSB_WVDC32(0x80000000, VGACNTRL
);
354 PSB_WVDC32(dev_priv
->saveFPA0
, MRST_FPA0
);
355 PSB_WVDC32(dev_priv
->saveFPA1
, MRST_FPA1
);
357 /* Actually enable it */
358 PSB_WVDC32(dev_priv
->saveDPLL_A
, MRST_DPLL_A
);
362 PSB_WVDC32(dev_priv
->saveHTOTAL_A
, HTOTAL_A
);
363 PSB_WVDC32(dev_priv
->saveHBLANK_A
, HBLANK_A
);
364 PSB_WVDC32(dev_priv
->saveHSYNC_A
, HSYNC_A
);
365 PSB_WVDC32(dev_priv
->saveVTOTAL_A
, VTOTAL_A
);
366 PSB_WVDC32(dev_priv
->saveVBLANK_A
, VBLANK_A
);
367 PSB_WVDC32(dev_priv
->saveVSYNC_A
, VSYNC_A
);
368 PSB_WVDC32(dev_priv
->savePIPEASRC
, PIPEASRC
);
369 PSB_WVDC32(dev_priv
->saveBCLRPAT_A
, BCLRPAT_A
);
371 /* Restore performance mode*/
372 PSB_WVDC32(dev_priv
->savePERF_MODE
, MRST_PERF_MODE
);
375 if (dev_priv
->iLVDS_enable
)
376 PSB_WVDC32(dev_priv
->savePIPEACONF
, PIPEACONF
);
378 /* Set up the plane*/
379 PSB_WVDC32(dev_priv
->saveDSPALINOFF
, DSPALINOFF
);
380 PSB_WVDC32(dev_priv
->saveDSPASTRIDE
, DSPASTRIDE
);
381 PSB_WVDC32(dev_priv
->saveDSPATILEOFF
, DSPATILEOFF
);
383 /* Enable the plane */
384 PSB_WVDC32(dev_priv
->saveDSPACNTR
, DSPACNTR
);
385 PSB_WVDC32(dev_priv
->saveDSPASURF
, DSPASURF
);
387 /* Enable Cursor A */
388 PSB_WVDC32(dev_priv
->saveDSPACURSOR_CTRL
, CURACNTR
);
389 PSB_WVDC32(dev_priv
->saveDSPACURSOR_POS
, CURAPOS
);
390 PSB_WVDC32(dev_priv
->saveDSPACURSOR_BASE
, CURABASE
);
392 /* Restore palette (gamma) */
393 for (i
= 0; i
< 256; i
++)
394 PSB_WVDC32(dev_priv
->save_palette_a
[i
], PALETTE_A
+ (i
<< 2));
396 if (dev_priv
->hdmi_priv
)
397 mrst_hdmi_restore(dev
);
399 if (dev_priv
->iLVDS_enable
) {
400 PSB_WVDC32(dev_priv
->saveBLC_PWM_CTL2
, BLC_PWM_CTL2
);
401 PSB_WVDC32(dev_priv
->saveLVDS
, LVDS
); /*port 61180h*/
402 PSB_WVDC32(dev_priv
->savePFIT_CONTROL
, PFIT_CONTROL
);
403 PSB_WVDC32(dev_priv
->savePFIT_PGM_RATIOS
, PFIT_PGM_RATIOS
);
404 PSB_WVDC32(dev_priv
->savePFIT_AUTO_RATIOS
, PFIT_AUTO_RATIOS
);
405 PSB_WVDC32(dev_priv
->saveBLC_PWM_CTL
, BLC_PWM_CTL
);
406 PSB_WVDC32(dev_priv
->savePP_ON_DELAYS
, LVDSPP_ON
);
407 PSB_WVDC32(dev_priv
->savePP_OFF_DELAYS
, LVDSPP_OFF
);
408 PSB_WVDC32(dev_priv
->savePP_DIVISOR
, PP_CYCLE
);
409 PSB_WVDC32(dev_priv
->savePP_CONTROL
, PP_CONTROL
);
412 /* Wait for cycle delay */
414 pp_stat
= PSB_RVDC32(PP_STATUS
);
415 } while (pp_stat
& 0x08000000);
417 /* Wait for panel power up */
419 pp_stat
= PSB_RVDC32(PP_STATUS
);
420 } while (pp_stat
& 0x10000000);
422 /* Restore HW overlay */
423 PSB_WVDC32(dev_priv
->saveOV_OVADD
, OV_OVADD
);
424 PSB_WVDC32(dev_priv
->saveOV_OGAMC0
, OV_OGAMC0
);
425 PSB_WVDC32(dev_priv
->saveOV_OGAMC1
, OV_OGAMC1
);
426 PSB_WVDC32(dev_priv
->saveOV_OGAMC2
, OV_OGAMC2
);
427 PSB_WVDC32(dev_priv
->saveOV_OGAMC3
, OV_OGAMC3
);
428 PSB_WVDC32(dev_priv
->saveOV_OGAMC4
, OV_OGAMC4
);
429 PSB_WVDC32(dev_priv
->saveOV_OGAMC5
, OV_OGAMC5
);
432 PSB_WVDC32(dev_priv
->saveHISTOGRAM_INT_CONTROL_REG
,
433 HISTOGRAM_INT_CONTROL
);
434 PSB_WVDC32(dev_priv
->saveHISTOGRAM_LOGIC_CONTROL_REG
,
435 HISTOGRAM_LOGIC_CONTROL
);
436 PSB_WVDC32(dev_priv
->savePWM_CONTROL_LOGIC
, PWM_CONTROL_LOGIC
);
442 * mrst_power_down - power down the display island
443 * @dev: our DRM device
445 * Power down the display interface of our device
447 static int mrst_power_down(struct drm_device
*dev
)
449 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
453 pwr_mask
= PSB_PWRGT_DISPLAY_MASK
;
454 outl(pwr_mask
, dev_priv
->ospm_base
+ PSB_PM_SSC
);
457 pwr_sts
= inl(dev_priv
->ospm_base
+ PSB_PM_SSS
);
458 if ((pwr_sts
& pwr_mask
) == pwr_mask
)
469 * Restore power to the specified island(s) (powergating)
471 static int mrst_power_up(struct drm_device
*dev
)
473 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
474 u32 pwr_mask
= PSB_PWRGT_DISPLAY_MASK
;
475 u32 pwr_sts
, pwr_cnt
;
477 pwr_cnt
= inl(dev_priv
->ospm_base
+ PSB_PM_SSC
);
478 pwr_cnt
&= ~pwr_mask
;
479 outl(pwr_cnt
, (dev_priv
->ospm_base
+ PSB_PM_SSC
));
482 pwr_sts
= inl(dev_priv
->ospm_base
+ PSB_PM_SSS
);
483 if ((pwr_sts
& pwr_mask
) == 0)
491 #if defined(CONFIG_X86_MRST)
492 static void mrst_lvds_cache_bl(struct drm_device
*dev
)
494 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
496 intel_scu_ipc_ioread8(0x28, &(dev_priv
->saveBKLTCNT
));
497 intel_scu_ipc_ioread8(0x29, &(dev_priv
->saveBKLTREQ
));
498 intel_scu_ipc_ioread8(0x2A, &(dev_priv
->saveBKLTBRTL
));
501 static void mrst_mm_bl_power(struct drm_device
*dev
, bool on
)
503 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
506 intel_scu_ipc_iowrite8(0x2A, dev_priv
->saveBKLTBRTL
);
507 intel_scu_ipc_iowrite8(0x28, dev_priv
->saveBKLTCNT
);
508 intel_scu_ipc_iowrite8(0x29, dev_priv
->saveBKLTREQ
);
510 intel_scu_ipc_iowrite8(0x2A, 0);
511 intel_scu_ipc_iowrite8(0x28, 0);
512 intel_scu_ipc_iowrite8(0x29, 0);
516 static const struct psb_ops mrst_mm_chip_ops
= {
517 .name
= "Moorestown MM ",
521 .sgx_offset
= MRST_SGX_OFFSET
,
523 .crtc_helper
= &mrst_helper_funcs
,
524 .crtc_funcs
= &psb_intel_crtc_funcs
,
526 .output_init
= mrst_output_init
,
528 .lvds_bl_power
= mrst_mm_bl_power
,
529 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
530 .backlight_init
= mrst_backlight_init
,
533 .init_pm
= mrst_init_pm
,
534 .save_regs
= mrst_save_display_registers
,
535 .restore_regs
= mrst_restore_display_registers
,
536 .power_down
= mrst_power_down
,
537 .power_up
= mrst_power_up
,
544 static void oaktrail_teardown(struct drm_device
*dev
)
546 mrst_hdmi_teardown(dev
);
549 static const struct psb_ops oaktrail_chip_ops
= {
554 .sgx_offset
= MRST_SGX_OFFSET
,
556 .chip_setup
= mid_chip_setup
,
557 .chip_teardown
= oaktrail_teardown
,
558 .crtc_helper
= &mrst_helper_funcs
,
559 .crtc_funcs
= &psb_intel_crtc_funcs
,
561 .output_init
= mrst_output_init
,
563 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
564 .backlight_init
= mrst_backlight_init
,
567 .init_pm
= mrst_init_pm
,
568 .save_regs
= mrst_save_display_registers
,
569 .restore_regs
= mrst_restore_display_registers
,
570 .power_down
= mrst_power_down
,
571 .power_up
= mrst_power_up
,
577 * mrst_chip_setup - perform the initial chip init
578 * @dev: Our drm_device
580 * Figure out which incarnation we are and then scan the firmware for
581 * tables and information.
583 static int mrst_chip_setup(struct drm_device
*dev
)
585 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
587 switch (mrst_device_ident(dev
)) {
588 case DEVICE_OAKTRAIL
:
589 /* Dual CRTC, PC compatible, HDMI, I2C #2 */
590 dev_priv
->ops
= &oaktrail_chip_ops
;
591 mrst_hdmi_setup(dev
);
592 return mid_chip_setup(dev
);
593 #if defined(CONFIG_X86_MRST)
594 case DEVICE_MOORESTOWN_MM
:
595 /* Single CRTC, No HDMI, I2C #0, BL control */
596 mrst_lvds_cache_bl(dev
);
597 dev_priv
->ops
= &mrst_mm_chip_ops
;
598 return mid_chip_setup(dev
);
599 case DEVICE_MOORESTOWN
:
600 /* Dual CRTC, No HDMI(?), I2C #1 */
601 return mid_chip_setup(dev
);
604 dev_err(dev
->dev
, "unsupported device type.\n");
609 const struct psb_ops mrst_chip_ops
= {
610 .name
= "Moorestown",
614 .sgx_offset
= MRST_SGX_OFFSET
,
616 .chip_setup
= mrst_chip_setup
,
617 .crtc_helper
= &mrst_helper_funcs
,
618 .crtc_funcs
= &psb_intel_crtc_funcs
,
620 .output_init
= mrst_output_init
,
622 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
623 .backlight_init
= mrst_backlight_init
,
626 .init_pm
= mrst_init_pm
,
627 .save_regs
= mrst_save_display_registers
,
628 .restore_regs
= mrst_restore_display_registers
,
629 .power_down
= mrst_power_down
,
630 .power_up
= mrst_power_up
,