Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
[firefly-linux-kernel-4.4.55.git] / drivers / staging / gma500 / psb_powermgmt.c
1 /**************************************************************************
2  * Copyright (c) 2009, Intel Corporation.
3  * All Rights Reserved.
4
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * Authors:
25  *    Benjamin Defnet <benjamin.r.defnet@intel.com>
26  *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
27  * Massively reworked
28  *    Alan Cox <alan@linux.intel.com>
29  */
30 #include "psb_powermgmt.h"
31 #include "psb_drv.h"
32 #include "psb_reg.h"
33 #include "psb_intel_reg.h"
34 #include <linux/mutex.h>
35 #include <linux/pm_runtime.h>
36
37 static struct mutex power_mutex;
38
39 /**
40  *      gma_power_init          -       initialise power manager
41  *      @dev: our device
42  *
43  *      Set up for power management tracking of our hardware.
44  */
45 void gma_power_init(struct drm_device *dev)
46 {
47         struct drm_psb_private *dev_priv = dev->dev_private;
48
49         dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
50         dev_priv->ospm_base &= 0xffff;
51
52         dev_priv->display_power = true; /* We start active */
53         dev_priv->display_count = 0;    /* Currently no users */
54         dev_priv->suspended = false;    /* And not suspended */
55         mutex_init(&power_mutex);
56
57         if (!IS_MRST(dev)) {
58                 /* FIXME: wants further review */
59                 u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
60                 /* Disable 2D clock gating */
61                 gating &= ~3;
62                 gating |= 1;
63                 PSB_WSGX32(gating, PSB_CR_CLKGATECTL);
64                 PSB_RSGX32(PSB_CR_CLKGATECTL);
65         }
66 }
67
68 /**
69  *      gma_power_uninit        -       end power manager
70  *      @dev: device to end for
71  *
72  *      Undo the effects of gma_power_init
73  */
74 void gma_power_uninit(struct drm_device *dev)
75 {
76         mutex_destroy(&power_mutex);
77         pm_runtime_disable(&dev->pdev->dev);
78         pm_runtime_set_suspended(&dev->pdev->dev);
79 }
80
81
82 /**
83  *      save_display_registers  -       save registers lost on suspend
84  *      @dev: our DRM device
85  *
86  *      Save the state we need in order to be able to restore the interface
87  *      upon resume from suspend
88  */
89 static int save_display_registers(struct drm_device *dev)
90 {
91         struct drm_psb_private *dev_priv = dev->dev_private;
92         struct drm_crtc *crtc;
93         struct drm_connector *connector;
94
95         /* Display arbitration control + watermarks */
96         dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
97         dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
98         dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
99         dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
100         dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
101         dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
102         dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
103         dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
104
105         /* Save crtc and output state */
106         mutex_lock(&dev->mode_config.mutex);
107         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
108                 if (drm_helper_crtc_in_use(crtc))
109                         crtc->funcs->save(crtc);
110         }
111
112         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
113                 connector->funcs->save(connector);
114
115         mutex_unlock(&dev->mode_config.mutex);
116         return 0;
117 }
118
119 /**
120  *      restore_display_registers       -       restore lost register state
121  *      @dev: our DRM device
122  *
123  *      Restore register state that was lost during suspend and resume.
124  */
125 static int restore_display_registers(struct drm_device *dev)
126 {
127         struct drm_psb_private *dev_priv = dev->dev_private;
128         struct drm_crtc *crtc;
129         struct drm_connector *connector;
130
131         /* Display arbitration + watermarks */
132         PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
133         PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
134         PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
135         PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
136         PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
137         PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
138         PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
139         PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
140
141         /*make sure VGA plane is off. it initializes to on after reset!*/
142         PSB_WVDC32(0x80000000, VGACNTRL);
143
144         mutex_lock(&dev->mode_config.mutex);
145         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
146                 if (drm_helper_crtc_in_use(crtc))
147                         crtc->funcs->restore(crtc);
148
149         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
150                 connector->funcs->restore(connector);
151
152         mutex_unlock(&dev->mode_config.mutex);
153         return 0;
154 }
155
156 /**
157  *      power_down      -       power down the display island
158  *      @dev: our DRM device
159  *
160  *      Power down the display interface of our device
161  */
162 static void power_down(struct drm_device *dev)
163 {
164         struct drm_psb_private *dev_priv = dev->dev_private;
165         u32 pwr_mask ;
166         u32 pwr_sts;
167
168         if (IS_MRST(dev)) {
169                 pwr_mask = PSB_PWRGT_DISPLAY_MASK;
170                 outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC);
171
172                 while (true) {
173                         pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
174                         if ((pwr_sts & pwr_mask) == pwr_mask)
175                                 break;
176                         else
177                                 udelay(10);
178                 }
179                 dev_priv->display_power = false;
180         }
181 }
182
183
184 /**
185  *      gma_suspend_display     -       suspend the display logic
186  *      @dev: our DRM device
187  *
188  *      Suspend the display logic of the graphics interface
189  */
190 static void gma_suspend_display(struct drm_device *dev)
191 {
192         struct drm_psb_private *dev_priv = dev->dev_private;
193         int pp_stat;
194
195         if (dev_priv->suspended)
196                 return;
197
198         save_display_registers(dev);
199
200         if (dev_priv->iLVDS_enable) {
201                 /*shutdown the panel*/
202                 PSB_WVDC32(0, PP_CONTROL);
203
204                 do {
205                         pp_stat = PSB_RVDC32(PP_STATUS);
206                 } while (pp_stat & 0x80000000);
207
208                 /*turn off the plane*/
209                 PSB_WVDC32(0x58000000, DSPACNTR);
210                 PSB_WVDC32(0, DSPASURF);/*trigger the plane disable*/
211                 /*wait ~4 ticks*/
212                 msleep(4);
213
214                 /*turn off pipe*/
215                 PSB_WVDC32(0x0, PIPEACONF);
216                 /*wait ~8 ticks*/
217                 msleep(8);
218
219                 /*turn off PLLs*/
220                 PSB_WVDC32(0, MRST_DPLL_A);
221         } else {
222                 PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG);
223                 PSB_WVDC32(0x0, PIPEACONF);
224                 PSB_WVDC32(0x2faf0000, BLC_PWM_CTL);
225                 while (REG_READ(0x70008) & 0x40000000);
226                 while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY)
227                         != DPI_FIFO_EMPTY);
228                 PSB_WVDC32(0, DEVICE_READY_REG);
229                         /* turn off panel power */
230         }
231         power_down(dev);
232 }
233
234 /*
235  * power_up
236  *
237  * Description: Restore power to the specified island(s) (powergating)
238  */
239 static void power_up(struct drm_device *dev)
240 {
241         struct drm_psb_private *dev_priv = dev->dev_private;
242         u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK;
243         u32 pwr_sts, pwr_cnt;
244
245         if (IS_MRST(dev)) {
246                 pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
247                 pwr_cnt &= ~pwr_mask;
248                 outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
249
250                 while (true) {
251                         pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
252                         if ((pwr_sts & pwr_mask) == 0)
253                                 break;
254                         else
255                                 udelay(10);
256                 }
257         }
258         dev_priv->suspended = false;
259         dev_priv->display_power = true;
260 }
261
262 /**
263  *      gma_resume_display      -       resume display side logic
264  *
265  *      Resume the display hardware restoring state and enabling
266  *      as necessary.
267  */
268 static void gma_resume_display(struct pci_dev *pdev)
269 {
270         struct drm_device *dev = pci_get_drvdata(pdev);
271         struct drm_psb_private *dev_priv = dev->dev_private;
272
273         if (dev_priv->suspended == false)
274                 return;
275
276         /* turn on the display power island */
277         power_up(dev);
278
279         PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
280         pci_write_config_word(pdev, PSB_GMCH_CTRL,
281                         dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
282
283         /* Don't reinitialize the GTT as it is unnecessary.  The gtt is
284          * stored in memory so it will automatically be restored.  All
285          * we need to do is restore the PGETBL_CTL which we already do
286          * above.
287          */
288         /*psb_gtt_init(dev_priv->pg, 1);*/
289
290         restore_display_registers(dev);
291 }
292
293 /**
294  *      gma_suspend_pci         -       suspend PCI side
295  *      @pdev: PCI device
296  *
297  *      Perform the suspend processing on our PCI device state
298  */
299 static void gma_suspend_pci(struct pci_dev *pdev)
300 {
301         struct drm_device *dev = pci_get_drvdata(pdev);
302         struct drm_psb_private *dev_priv = dev->dev_private;
303         int bsm, vbt;
304
305         if (dev_priv->suspended)
306                 return;
307
308         pci_save_state(pdev);
309         pci_read_config_dword(pdev, 0x5C, &bsm);
310         dev_priv->saveBSM = bsm;
311         pci_read_config_dword(pdev, 0xFC, &vbt);
312         dev_priv->saveVBT = vbt;
313         pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr);
314         pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data);
315
316         pci_disable_device(pdev);
317         pci_set_power_state(pdev, PCI_D3hot);
318
319         dev_priv->suspended = true;
320 }
321
322 /**
323  *      gma_resume_pci          -       resume helper
324  *      @dev: our PCI device
325  *
326  *      Perform the resume processing on our PCI device state - rewrite
327  *      register state and re-enable the PCI device
328  */
329 static bool gma_resume_pci(struct pci_dev *pdev)
330 {
331         struct drm_device *dev = pci_get_drvdata(pdev);
332         struct drm_psb_private *dev_priv = dev->dev_private;
333         int ret;
334
335         if (!dev_priv->suspended)
336                 return true;
337
338         pci_set_power_state(pdev, PCI_D0);
339         pci_restore_state(pdev);
340         pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM);
341         pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT);
342         /* retoring MSI address and data in PCIx space */
343         pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr);
344         pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data);
345         ret = pci_enable_device(pdev);
346
347         if (ret != 0)
348                 dev_err(&pdev->dev, "pci_enable failed: %d\n", ret);
349         else
350                 dev_priv->suspended = false;
351         return !dev_priv->suspended;
352 }
353
354 /**
355  *      gma_power_suspend               -       bus callback for suspend
356  *      @pdev: our PCI device
357  *      @state: suspend type
358  *
359  *      Called back by the PCI layer during a suspend of the system. We
360  *      perform the necessary shut down steps and save enough state that
361  *      we can undo this when resume is called.
362  */
363 int gma_power_suspend(struct pci_dev *pdev, pm_message_t state)
364 {
365         struct drm_device *dev = pci_get_drvdata(pdev);
366         struct drm_psb_private *dev_priv = dev->dev_private;
367
368         mutex_lock(&power_mutex);
369         if (!dev_priv->suspended) {
370                 if (dev_priv->display_count) {
371                         mutex_unlock(&power_mutex);
372                         return -EBUSY;
373                 }
374                 psb_irq_uninstall(dev);
375                 gma_suspend_display(dev);
376                 gma_suspend_pci(pdev);
377         }
378         mutex_unlock(&power_mutex);
379         return 0;
380 }
381
382
383 /**
384  *      gma_power_resume                -       resume power
385  *      @pdev: PCI device
386  *
387  *      Resume the PCI side of the graphics and then the displays
388  */
389 int gma_power_resume(struct pci_dev *pdev)
390 {
391         struct drm_device *dev = pci_get_drvdata(pdev);
392
393         mutex_lock(&power_mutex);
394         gma_resume_pci(pdev);
395         gma_resume_display(pdev);
396         psb_irq_preinstall(dev);
397         psb_irq_postinstall(dev);
398         mutex_unlock(&power_mutex);
399         return 0;
400 }
401
402
403
404 /**
405  *      gma_power_is_on         -       returne true if power is on
406  *      @dev: our DRM device
407  *
408  *      Returns true if the display island power is on at this moment
409  */
410 bool gma_power_is_on(struct drm_device *dev)
411 {
412         struct drm_psb_private *dev_priv = dev->dev_private;
413         return dev_priv->display_power;
414 }
415
416
417 /**
418  *      gma_power_begin         -       begin requiring power
419  *      @dev: our DRM device
420  *      @force_on: true to force power on
421  *
422  *      Begin an action that requires the display power island is enabled.
423  *      We refcount the islands.
424  *
425  *      FIXME: locking
426  */
427 bool gma_power_begin(struct drm_device *dev, bool force_on)
428 {
429         struct drm_psb_private *dev_priv = dev->dev_private;
430         int ret;
431
432         /* Power already on ? */
433         if (dev_priv->display_power) {
434                 dev_priv->display_count++;
435                 pm_runtime_get(&dev->pdev->dev);
436                 return true;
437         }
438         if (force_on == false)
439                 return false;
440
441         /* Ok power up needed */
442         ret = gma_resume_pci(dev->pdev);
443         if (ret == 0) {
444                 psb_irq_preinstall(dev);
445                 psb_irq_postinstall(dev);
446                 pm_runtime_get(&dev->pdev->dev);
447                 dev_priv->display_count++;
448                 return true;
449         }
450         return false;
451 }
452
453
454 /**
455  *      gma_power_end           -       end use of power
456  *      @dev: Our DRM device
457  *
458  *      Indicate that one of our gma_power_begin() requested periods when
459  *      the diplay island power is needed has completed.
460  */
461 void gma_power_end(struct drm_device *dev)
462 {
463         struct drm_psb_private *dev_priv = dev->dev_private;
464         dev_priv->display_count--;
465         WARN_ON(dev_priv->display_count < 0);
466         pm_runtime_put(&dev->pdev->dev);
467 }
468
469 int psb_runtime_suspend(struct device *dev)
470 {
471         static pm_message_t dummy;
472         return gma_power_suspend(to_pci_dev(dev), dummy);
473 }
474
475 int psb_runtime_resume(struct device *dev)
476 {
477         return 0;
478 }
479
480 int psb_runtime_idle(struct device *dev)
481 {
482         struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev));
483         struct drm_psb_private *dev_priv = drmdev->dev_private;
484         if (dev_priv->display_count)
485                 return 0;
486         else
487                 return 1;
488 }
489