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 **************************************************************************/
25 #include "psb_intel_reg.h"
26 #include <asm/intel_scu_ipc.h>
28 /* IPC message and command defines used to enable/disable mipi panel voltages */
29 #define IPC_MSG_PANEL_ON_OFF 0xE9
30 #define IPC_CMD_PANEL_ON 1
31 #define IPC_CMD_PANEL_OFF 0
33 static int mrst_output_init(struct drm_device
*dev
)
35 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
36 if (dev_priv
->iLVDS_enable
) {
37 mrst_lvds_init(dev
, &dev_priv
->mode_dev
);
40 dev_err(dev
->dev
, "DSI is not supported\n");
45 * Provide the Moorestown specific chip logic and low level methods
48 static void mrst_init_pm(struct drm_device
*dev
)
53 * mrst_save_display_registers - save registers lost on suspend
54 * @dev: our DRM device
56 * Save the state we need in order to be able to restore the interface
57 * upon resume from suspend
59 static int mrst_save_display_registers(struct drm_device
*dev
)
61 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
62 struct drm_crtc
*crtc
;
63 struct drm_connector
*connector
;
65 /* Display arbitration control + watermarks */
66 dev_priv
->saveDSPARB
= PSB_RVDC32(DSPARB
);
67 dev_priv
->saveDSPFW1
= PSB_RVDC32(DSPFW1
);
68 dev_priv
->saveDSPFW2
= PSB_RVDC32(DSPFW2
);
69 dev_priv
->saveDSPFW3
= PSB_RVDC32(DSPFW3
);
70 dev_priv
->saveDSPFW4
= PSB_RVDC32(DSPFW4
);
71 dev_priv
->saveDSPFW5
= PSB_RVDC32(DSPFW5
);
72 dev_priv
->saveDSPFW6
= PSB_RVDC32(DSPFW6
);
73 dev_priv
->saveCHICKENBIT
= PSB_RVDC32(DSPCHICKENBIT
);
75 /* Save crtc and output state */
76 mutex_lock(&dev
->mode_config
.mutex
);
77 list_for_each_entry(crtc
, &dev
->mode_config
.crtc_list
, head
) {
78 if (drm_helper_crtc_in_use(crtc
))
79 crtc
->funcs
->save(crtc
);
82 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
)
83 connector
->funcs
->save(connector
);
85 mutex_unlock(&dev
->mode_config
.mutex
);
90 * mrst_restore_display_registers - restore lost register state
91 * @dev: our DRM device
93 * Restore register state that was lost during suspend and resume.
95 static int mrst_restore_display_registers(struct drm_device
*dev
)
97 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
98 struct drm_crtc
*crtc
;
99 struct drm_connector
*connector
;
102 if (!dev_priv
->iLVDS_enable
) {
103 #ifdef CONFIG_X86_MRST
104 intel_scu_ipc_simple_command(IPC_MSG_PANEL_ON_OFF
,
106 /* FIXME: can we avoid this delay ? */
107 msleep(2000); /* wait 2 seconds */
111 /* Display arbitration + watermarks */
112 PSB_WVDC32(dev_priv
->saveDSPARB
, DSPARB
);
113 PSB_WVDC32(dev_priv
->saveDSPFW1
, DSPFW1
);
114 PSB_WVDC32(dev_priv
->saveDSPFW2
, DSPFW2
);
115 PSB_WVDC32(dev_priv
->saveDSPFW3
, DSPFW3
);
116 PSB_WVDC32(dev_priv
->saveDSPFW4
, DSPFW4
);
117 PSB_WVDC32(dev_priv
->saveDSPFW5
, DSPFW5
);
118 PSB_WVDC32(dev_priv
->saveDSPFW6
, DSPFW6
);
119 PSB_WVDC32(dev_priv
->saveCHICKENBIT
, DSPCHICKENBIT
);
121 /*make sure VGA plane is off. it initializes to on after reset!*/
122 PSB_WVDC32(0x80000000, VGACNTRL
);
124 mutex_lock(&dev
->mode_config
.mutex
);
125 list_for_each_entry(crtc
, &dev
->mode_config
.crtc_list
, head
)
126 if (drm_helper_crtc_in_use(crtc
))
127 crtc
->funcs
->restore(crtc
);
129 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
)
130 connector
->funcs
->restore(connector
);
132 mutex_unlock(&dev
->mode_config
.mutex
);
134 if (dev_priv
->iLVDS_enable
) {
135 /*shutdown the panel*/
136 PSB_WVDC32(0, PP_CONTROL
);
138 pp_stat
= PSB_RVDC32(PP_STATUS
);
139 } while (pp_stat
& 0x80000000);
141 /* Turn off the plane */
142 PSB_WVDC32(0x58000000, DSPACNTR
);
143 PSB_WVDC32(0, DSPASURF
);/*trigger the plane disable*/
147 PSB_WVDC32(0x0, PIPEACONF
);
152 PSB_WVDC32(0, MRST_DPLL_A
);
154 PSB_WVDC32(DPI_SHUT_DOWN
, DPI_CONTROL_REG
);
155 PSB_WVDC32(0x0, PIPEACONF
);
156 PSB_WVDC32(0x2faf0000, BLC_PWM_CTL
);
157 while (REG_READ(0x70008) & 0x40000000)
159 while ((PSB_RVDC32(GEN_FIFO_STAT_REG
) & DPI_FIFO_EMPTY
)
162 PSB_WVDC32(0, DEVICE_READY_REG
);
163 /* Turn off panel power */
164 #ifdef CONFIG_X86_MRST /* FIXME: kill define once modular */
165 intel_scu_ipc_simple_command(IPC_MSG_PANEL_ON_OFF
,
173 * mrst_power_down - power down the display island
174 * @dev: our DRM device
176 * Power down the display interface of our device
178 static int mrst_power_down(struct drm_device
*dev
)
180 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
184 pwr_mask
= PSB_PWRGT_DISPLAY_MASK
;
185 outl(pwr_mask
, dev_priv
->ospm_base
+ PSB_PM_SSC
);
188 pwr_sts
= inl(dev_priv
->ospm_base
+ PSB_PM_SSS
);
189 if ((pwr_sts
& pwr_mask
) == pwr_mask
)
200 * Restore power to the specified island(s) (powergating)
202 static int mrst_power_up(struct drm_device
*dev
)
204 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
205 u32 pwr_mask
= PSB_PWRGT_DISPLAY_MASK
;
206 u32 pwr_sts
, pwr_cnt
;
208 pwr_cnt
= inl(dev_priv
->ospm_base
+ PSB_PM_SSC
);
209 pwr_cnt
&= ~pwr_mask
;
210 outl(pwr_cnt
, (dev_priv
->ospm_base
+ PSB_PM_SSC
));
213 pwr_sts
= inl(dev_priv
->ospm_base
+ PSB_PM_SSS
);
214 if ((pwr_sts
& pwr_mask
) == 0)
222 const struct psb_ops mrst_chip_ops
= {
223 .output_init
= mrst_output_init
,
224 .init_pm
= mrst_init_pm
,
225 .save_regs
= mrst_save_display_registers
,
226 .restore_regs
= mrst_restore_display_registers
,
227 .power_down
= mrst_power_down
,
228 .power_up
= mrst_power_up
,