root/drivers/video/fbdev/geode/suspend_gx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gx_save_regs
  2. gx_set_dotpll
  3. gx_restore_gfx_proc
  4. gx_restore_display_ctlr
  5. gx_restore_video_proc
  6. gx_restore_regs
  7. gx_disable_graphics
  8. gx_enable_graphics
  9. gx_powerdown
  10. gx_powerup

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *   Copyright (C) 2007 Advanced Micro Devices, Inc.
   4  *   Copyright (C) 2008 Andres Salomon <dilinger@debian.org>
   5  */
   6 #include <linux/fb.h>
   7 #include <asm/io.h>
   8 #include <asm/msr.h>
   9 #include <linux/cs5535.h>
  10 #include <asm/delay.h>
  11 
  12 #include "gxfb.h"
  13 
  14 #ifdef CONFIG_PM
  15 
  16 static void gx_save_regs(struct gxfb_par *par)
  17 {
  18         int i;
  19 
  20         /* wait for the BLT engine to stop being busy */
  21         do {
  22                 i = read_gp(par, GP_BLT_STATUS);
  23         } while (i & (GP_BLT_STATUS_BLT_PENDING | GP_BLT_STATUS_BLT_BUSY));
  24 
  25         /* save MSRs */
  26         rdmsrl(MSR_GX_MSR_PADSEL, par->msr.padsel);
  27         rdmsrl(MSR_GLCP_DOTPLL, par->msr.dotpll);
  28 
  29         write_dc(par, DC_UNLOCK, DC_UNLOCK_UNLOCK);
  30 
  31         /* save registers */
  32         memcpy(par->gp, par->gp_regs, sizeof(par->gp));
  33         memcpy(par->dc, par->dc_regs, sizeof(par->dc));
  34         memcpy(par->vp, par->vid_regs, sizeof(par->vp));
  35         memcpy(par->fp, par->vid_regs + VP_FP_START, sizeof(par->fp));
  36 
  37         /* save the palette */
  38         write_dc(par, DC_PAL_ADDRESS, 0);
  39         for (i = 0; i < ARRAY_SIZE(par->pal); i++)
  40                 par->pal[i] = read_dc(par, DC_PAL_DATA);
  41 }
  42 
  43 static void gx_set_dotpll(uint32_t dotpll_hi)
  44 {
  45         uint32_t dotpll_lo;
  46         int i;
  47 
  48         rdmsrl(MSR_GLCP_DOTPLL, dotpll_lo);
  49         dotpll_lo |= MSR_GLCP_DOTPLL_DOTRESET;
  50         dotpll_lo &= ~MSR_GLCP_DOTPLL_BYPASS;
  51         wrmsr(MSR_GLCP_DOTPLL, dotpll_lo, dotpll_hi);
  52 
  53         /* wait for the PLL to lock */
  54         for (i = 0; i < 200; i++) {
  55                 rdmsrl(MSR_GLCP_DOTPLL, dotpll_lo);
  56                 if (dotpll_lo & MSR_GLCP_DOTPLL_LOCK)
  57                         break;
  58                 udelay(1);
  59         }
  60 
  61         /* PLL set, unlock */
  62         dotpll_lo &= ~MSR_GLCP_DOTPLL_DOTRESET;
  63         wrmsr(MSR_GLCP_DOTPLL, dotpll_lo, dotpll_hi);
  64 }
  65 
  66 static void gx_restore_gfx_proc(struct gxfb_par *par)
  67 {
  68         int i;
  69 
  70         for (i = 0; i < ARRAY_SIZE(par->gp); i++) {
  71                 switch (i) {
  72                 case GP_VECTOR_MODE:
  73                 case GP_BLT_MODE:
  74                 case GP_BLT_STATUS:
  75                 case GP_HST_SRC:
  76                         /* don't restore these registers */
  77                         break;
  78                 default:
  79                         write_gp(par, i, par->gp[i]);
  80                 }
  81         }
  82 }
  83 
  84 static void gx_restore_display_ctlr(struct gxfb_par *par)
  85 {
  86         int i;
  87 
  88         for (i = 0; i < ARRAY_SIZE(par->dc); i++) {
  89                 switch (i) {
  90                 case DC_UNLOCK:
  91                         /* unlock the DC; runs first */
  92                         write_dc(par, DC_UNLOCK, DC_UNLOCK_UNLOCK);
  93                         break;
  94 
  95                 case DC_GENERAL_CFG:
  96                         /* write without the enables */
  97                         write_dc(par, i, par->dc[i] & ~(DC_GENERAL_CFG_VIDE |
  98                                         DC_GENERAL_CFG_ICNE |
  99                                         DC_GENERAL_CFG_CURE |
 100                                         DC_GENERAL_CFG_DFLE));
 101                         break;
 102 
 103                 case DC_DISPLAY_CFG:
 104                         /* write without the enables */
 105                         write_dc(par, i, par->dc[i] & ~(DC_DISPLAY_CFG_VDEN |
 106                                         DC_DISPLAY_CFG_GDEN |
 107                                         DC_DISPLAY_CFG_TGEN));
 108                         break;
 109 
 110                 case DC_RSVD_0:
 111                 case DC_RSVD_1:
 112                 case DC_RSVD_2:
 113                 case DC_RSVD_3:
 114                 case DC_RSVD_4:
 115                 case DC_LINE_CNT:
 116                 case DC_PAL_ADDRESS:
 117                 case DC_PAL_DATA:
 118                 case DC_DFIFO_DIAG:
 119                 case DC_CFIFO_DIAG:
 120                 case DC_RSVD_5:
 121                         /* don't restore these registers */
 122                         break;
 123                 default:
 124                         write_dc(par, i, par->dc[i]);
 125                 }
 126         }
 127 
 128         /* restore the palette */
 129         write_dc(par, DC_PAL_ADDRESS, 0);
 130         for (i = 0; i < ARRAY_SIZE(par->pal); i++)
 131                 write_dc(par, DC_PAL_DATA, par->pal[i]);
 132 }
 133 
 134 static void gx_restore_video_proc(struct gxfb_par *par)
 135 {
 136         int i;
 137 
 138         wrmsrl(MSR_GX_MSR_PADSEL, par->msr.padsel);
 139 
 140         for (i = 0; i < ARRAY_SIZE(par->vp); i++) {
 141                 switch (i) {
 142                 case VP_VCFG:
 143                         /* don't enable video yet */
 144                         write_vp(par, i, par->vp[i] & ~VP_VCFG_VID_EN);
 145                         break;
 146 
 147                 case VP_DCFG:
 148                         /* don't enable CRT yet */
 149                         write_vp(par, i, par->vp[i] &
 150                                         ~(VP_DCFG_DAC_BL_EN | VP_DCFG_VSYNC_EN |
 151                                         VP_DCFG_HSYNC_EN | VP_DCFG_CRT_EN));
 152                         break;
 153 
 154                 case VP_GAR:
 155                 case VP_GDR:
 156                 case VP_RSVD_0:
 157                 case VP_RSVD_1:
 158                 case VP_RSVD_2:
 159                 case VP_RSVD_3:
 160                 case VP_CRC32:
 161                 case VP_AWT:
 162                 case VP_VTM:
 163                         /* don't restore these registers */
 164                         break;
 165                 default:
 166                         write_vp(par, i, par->vp[i]);
 167                 }
 168         }
 169 }
 170 
 171 static void gx_restore_regs(struct gxfb_par *par)
 172 {
 173         int i;
 174 
 175         gx_set_dotpll((uint32_t) (par->msr.dotpll >> 32));
 176         gx_restore_gfx_proc(par);
 177         gx_restore_display_ctlr(par);
 178         gx_restore_video_proc(par);
 179 
 180         /* Flat Panel */
 181         for (i = 0; i < ARRAY_SIZE(par->fp); i++) {
 182                 if (i != FP_PM && i != FP_RSVD_0)
 183                         write_fp(par, i, par->fp[i]);
 184         }
 185 }
 186 
 187 static void gx_disable_graphics(struct gxfb_par *par)
 188 {
 189         /* shut down the engine */
 190         write_vp(par, VP_VCFG, par->vp[VP_VCFG] & ~VP_VCFG_VID_EN);
 191         write_vp(par, VP_DCFG, par->vp[VP_DCFG] & ~(VP_DCFG_DAC_BL_EN |
 192                         VP_DCFG_VSYNC_EN | VP_DCFG_HSYNC_EN | VP_DCFG_CRT_EN));
 193 
 194         /* turn off the flat panel */
 195         write_fp(par, FP_PM, par->fp[FP_PM] & ~FP_PM_P);
 196 
 197 
 198         /* turn off display */
 199         write_dc(par, DC_UNLOCK, DC_UNLOCK_UNLOCK);
 200         write_dc(par, DC_GENERAL_CFG, par->dc[DC_GENERAL_CFG] &
 201                         ~(DC_GENERAL_CFG_VIDE | DC_GENERAL_CFG_ICNE |
 202                         DC_GENERAL_CFG_CURE | DC_GENERAL_CFG_DFLE));
 203         write_dc(par, DC_DISPLAY_CFG, par->dc[DC_DISPLAY_CFG] &
 204                         ~(DC_DISPLAY_CFG_VDEN | DC_DISPLAY_CFG_GDEN |
 205                         DC_DISPLAY_CFG_TGEN));
 206         write_dc(par, DC_UNLOCK, DC_UNLOCK_LOCK);
 207 }
 208 
 209 static void gx_enable_graphics(struct gxfb_par *par)
 210 {
 211         uint32_t fp;
 212 
 213         fp = read_fp(par, FP_PM);
 214         if (par->fp[FP_PM] & FP_PM_P) {
 215                 /* power on the panel if not already power{ed,ing} on */
 216                 if (!(fp & (FP_PM_PANEL_ON|FP_PM_PANEL_PWR_UP)))
 217                         write_fp(par, FP_PM, par->fp[FP_PM]);
 218         } else {
 219                 /* power down the panel if not already power{ed,ing} down */
 220                 if (!(fp & (FP_PM_PANEL_OFF|FP_PM_PANEL_PWR_DOWN)))
 221                         write_fp(par, FP_PM, par->fp[FP_PM]);
 222         }
 223 
 224         /* turn everything on */
 225         write_vp(par, VP_VCFG, par->vp[VP_VCFG]);
 226         write_vp(par, VP_DCFG, par->vp[VP_DCFG]);
 227         write_dc(par, DC_DISPLAY_CFG, par->dc[DC_DISPLAY_CFG]);
 228         /* do this last; it will enable the FIFO load */
 229         write_dc(par, DC_GENERAL_CFG, par->dc[DC_GENERAL_CFG]);
 230 
 231         /* lock the door behind us */
 232         write_dc(par, DC_UNLOCK, DC_UNLOCK_LOCK);
 233 }
 234 
 235 int gx_powerdown(struct fb_info *info)
 236 {
 237         struct gxfb_par *par = info->par;
 238 
 239         if (par->powered_down)
 240                 return 0;
 241 
 242         gx_save_regs(par);
 243         gx_disable_graphics(par);
 244 
 245         par->powered_down = 1;
 246         return 0;
 247 }
 248 
 249 int gx_powerup(struct fb_info *info)
 250 {
 251         struct gxfb_par *par = info->par;
 252 
 253         if (!par->powered_down)
 254                 return 0;
 255 
 256         gx_restore_regs(par);
 257         gx_enable_graphics(par);
 258 
 259         par->powered_down  = 0;
 260         return 0;
 261 }
 262 
 263 #endif

/* [<][>][^][v][top][bottom][index][help] */