root/drivers/gpu/drm/gma500/cdv_device.c

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

DEFINITIONS

This source file includes following definitions.
  1. cdv_disable_vga
  2. cdv_output_init
  3. cdv_backlight_combination_mode
  4. cdv_get_max_backlight
  5. cdv_get_brightness
  6. cdv_set_brightness
  7. cdv_backlight_init
  8. CDV_MSG_READ32
  9. CDV_MSG_WRITE32
  10. cdv_init_pm
  11. cdv_errata
  12. cdv_save_display_registers
  13. cdv_restore_display_registers
  14. cdv_power_down
  15. cdv_power_up
  16. cdv_hotplug_work_func
  17. cdv_hotplug_event
  18. cdv_hotplug_enable
  19. cdv_intel_attach_force_audio_property
  20. cdv_intel_attach_broadcast_rgb_property
  21. cdv_chip_setup

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /**************************************************************************
   3  * Copyright (c) 2011, Intel Corporation.
   4  * All Rights Reserved.
   5  *
   6  **************************************************************************/
   7 
   8 #include <linux/backlight.h>
   9 #include <linux/delay.h>
  10 
  11 #include <drm/drm.h>
  12 
  13 #include "cdv_device.h"
  14 #include "gma_device.h"
  15 #include "intel_bios.h"
  16 #include "psb_drv.h"
  17 #include "psb_intel_reg.h"
  18 #include "psb_reg.h"
  19 
  20 #define VGA_SR_INDEX            0x3c4
  21 #define VGA_SR_DATA             0x3c5
  22 
  23 static void cdv_disable_vga(struct drm_device *dev)
  24 {
  25         u8 sr1;
  26         u32 vga_reg;
  27 
  28         vga_reg = VGACNTRL;
  29 
  30         outb(1, VGA_SR_INDEX);
  31         sr1 = inb(VGA_SR_DATA);
  32         outb(sr1 | 1<<5, VGA_SR_DATA);
  33         udelay(300);
  34 
  35         REG_WRITE(vga_reg, VGA_DISP_DISABLE);
  36         REG_READ(vga_reg);
  37 }
  38 
  39 static int cdv_output_init(struct drm_device *dev)
  40 {
  41         struct drm_psb_private *dev_priv = dev->dev_private;
  42 
  43         drm_mode_create_scaling_mode_property(dev);
  44 
  45         cdv_disable_vga(dev);
  46 
  47         cdv_intel_crt_init(dev, &dev_priv->mode_dev);
  48         cdv_intel_lvds_init(dev, &dev_priv->mode_dev);
  49 
  50         /* These bits indicate HDMI not SDVO on CDV */
  51         if (REG_READ(SDVOB) & SDVO_DETECTED) {
  52                 cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
  53                 if (REG_READ(DP_B) & DP_DETECTED)
  54                         cdv_intel_dp_init(dev, &dev_priv->mode_dev, DP_B);
  55         }
  56 
  57         if (REG_READ(SDVOC) & SDVO_DETECTED) {
  58                 cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC);
  59                 if (REG_READ(DP_C) & DP_DETECTED)
  60                         cdv_intel_dp_init(dev, &dev_priv->mode_dev, DP_C);
  61         }
  62         return 0;
  63 }
  64 
  65 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
  66 
  67 /*
  68  *      Cedartrail Backlght Interfaces
  69  */
  70 
  71 static struct backlight_device *cdv_backlight_device;
  72 
  73 static int cdv_backlight_combination_mode(struct drm_device *dev)
  74 {
  75         return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE;
  76 }
  77 
  78 static u32 cdv_get_max_backlight(struct drm_device *dev)
  79 {
  80         u32 max = REG_READ(BLC_PWM_CTL);
  81 
  82         if (max == 0) {
  83                 DRM_DEBUG_KMS("LVDS Panel PWM value is 0!\n");
  84                 /* i915 does this, I believe which means that we should not
  85                  * smash PWM control as firmware will take control of it. */
  86                 return 1;
  87         }
  88 
  89         max >>= 16;
  90         if (cdv_backlight_combination_mode(dev))
  91                 max *= 0xff;
  92         return max;
  93 }
  94 
  95 static int cdv_get_brightness(struct backlight_device *bd)
  96 {
  97         struct drm_device *dev = bl_get_data(bd);
  98         u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
  99 
 100         if (cdv_backlight_combination_mode(dev)) {
 101                 u8 lbpc;
 102 
 103                 val &= ~1;
 104                 pci_read_config_byte(dev->pdev, 0xF4, &lbpc);
 105                 val *= lbpc;
 106         }
 107         return (val * 100)/cdv_get_max_backlight(dev);
 108 
 109 }
 110 
 111 static int cdv_set_brightness(struct backlight_device *bd)
 112 {
 113         struct drm_device *dev = bl_get_data(bd);
 114         int level = bd->props.brightness;
 115         u32 blc_pwm_ctl;
 116 
 117         /* Percentage 1-100% being valid */
 118         if (level < 1)
 119                 level = 1;
 120 
 121         level *= cdv_get_max_backlight(dev);
 122         level /= 100;
 123 
 124         if (cdv_backlight_combination_mode(dev)) {
 125                 u32 max = cdv_get_max_backlight(dev);
 126                 u8 lbpc;
 127 
 128                 lbpc = level * 0xfe / max + 1;
 129                 level /= lbpc;
 130 
 131                 pci_write_config_byte(dev->pdev, 0xF4, lbpc);
 132         }
 133 
 134         blc_pwm_ctl = REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
 135         REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl |
 136                                 (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
 137         return 0;
 138 }
 139 
 140 static const struct backlight_ops cdv_ops = {
 141         .get_brightness = cdv_get_brightness,
 142         .update_status  = cdv_set_brightness,
 143 };
 144 
 145 static int cdv_backlight_init(struct drm_device *dev)
 146 {
 147         struct drm_psb_private *dev_priv = dev->dev_private;
 148         struct backlight_properties props;
 149 
 150         memset(&props, 0, sizeof(struct backlight_properties));
 151         props.max_brightness = 100;
 152         props.type = BACKLIGHT_PLATFORM;
 153 
 154         cdv_backlight_device = backlight_device_register("psb-bl",
 155                                         NULL, (void *)dev, &cdv_ops, &props);
 156         if (IS_ERR(cdv_backlight_device))
 157                 return PTR_ERR(cdv_backlight_device);
 158 
 159         cdv_backlight_device->props.brightness =
 160                         cdv_get_brightness(cdv_backlight_device);
 161         backlight_update_status(cdv_backlight_device);
 162         dev_priv->backlight_device = cdv_backlight_device;
 163         dev_priv->backlight_enabled = true;
 164         return 0;
 165 }
 166 
 167 #endif
 168 
 169 /*
 170  *      Provide the Cedarview specific chip logic and low level methods
 171  *      for power management
 172  *
 173  *      FIXME: we need to implement the apm/ospm base management bits
 174  *      for this and the MID devices.
 175  */
 176 
 177 static inline u32 CDV_MSG_READ32(int domain, uint port, uint offset)
 178 {
 179         int mcr = (0x10<<24) | (port << 16) | (offset << 8);
 180         uint32_t ret_val = 0;
 181         struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
 182         pci_write_config_dword(pci_root, 0xD0, mcr);
 183         pci_read_config_dword(pci_root, 0xD4, &ret_val);
 184         pci_dev_put(pci_root);
 185         return ret_val;
 186 }
 187 
 188 static inline void CDV_MSG_WRITE32(int domain, uint port, uint offset,
 189                                    u32 value)
 190 {
 191         int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
 192         struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
 193         pci_write_config_dword(pci_root, 0xD4, value);
 194         pci_write_config_dword(pci_root, 0xD0, mcr);
 195         pci_dev_put(pci_root);
 196 }
 197 
 198 #define PSB_PM_SSC                      0x20
 199 #define PSB_PM_SSS                      0x30
 200 #define PSB_PWRGT_GFX_ON                0x02
 201 #define PSB_PWRGT_GFX_OFF               0x01
 202 #define PSB_PWRGT_GFX_D0                0x00
 203 #define PSB_PWRGT_GFX_D3                0x03
 204 
 205 static void cdv_init_pm(struct drm_device *dev)
 206 {
 207         struct drm_psb_private *dev_priv = dev->dev_private;
 208         u32 pwr_cnt;
 209         int domain = pci_domain_nr(dev->pdev->bus);
 210         int i;
 211 
 212         dev_priv->apm_base = CDV_MSG_READ32(domain, PSB_PUNIT_PORT,
 213                                                         PSB_APMBA) & 0xFFFF;
 214         dev_priv->ospm_base = CDV_MSG_READ32(domain, PSB_PUNIT_PORT,
 215                                                         PSB_OSPMBA) & 0xFFFF;
 216 
 217         /* Power status */
 218         pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD);
 219 
 220         /* Enable the GPU */
 221         pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
 222         pwr_cnt |= PSB_PWRGT_GFX_ON;
 223         outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
 224 
 225         /* Wait for the GPU power */
 226         for (i = 0; i < 5; i++) {
 227                 u32 pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
 228                 if ((pwr_sts & PSB_PWRGT_GFX_MASK) == 0)
 229                         return;
 230                 udelay(10);
 231         }
 232         dev_err(dev->dev, "GPU: power management timed out.\n");
 233 }
 234 
 235 static void cdv_errata(struct drm_device *dev)
 236 {
 237         /* Disable bonus launch.
 238          *      CPU and GPU competes for memory and display misses updates and
 239          *      flickers. Worst with dual core, dual displays.
 240          *
 241          *      Fixes were done to Win 7 gfx driver to disable a feature called
 242          *      Bonus Launch to work around the issue, by degrading
 243          *      performance.
 244          */
 245          CDV_MSG_WRITE32(pci_domain_nr(dev->pdev->bus), 3, 0x30, 0x08027108);
 246 }
 247 
 248 /**
 249  *      cdv_save_display_registers      -       save registers lost on suspend
 250  *      @dev: our DRM device
 251  *
 252  *      Save the state we need in order to be able to restore the interface
 253  *      upon resume from suspend
 254  */
 255 static int cdv_save_display_registers(struct drm_device *dev)
 256 {
 257         struct drm_psb_private *dev_priv = dev->dev_private;
 258         struct psb_save_area *regs = &dev_priv->regs;
 259         struct drm_connector *connector;
 260 
 261         dev_dbg(dev->dev, "Saving GPU registers.\n");
 262 
 263         pci_read_config_byte(dev->pdev, 0xF4, &regs->cdv.saveLBB);
 264 
 265         regs->cdv.saveDSPCLK_GATE_D = REG_READ(DSPCLK_GATE_D);
 266         regs->cdv.saveRAMCLK_GATE_D = REG_READ(RAMCLK_GATE_D);
 267 
 268         regs->cdv.saveDSPARB = REG_READ(DSPARB);
 269         regs->cdv.saveDSPFW[0] = REG_READ(DSPFW1);
 270         regs->cdv.saveDSPFW[1] = REG_READ(DSPFW2);
 271         regs->cdv.saveDSPFW[2] = REG_READ(DSPFW3);
 272         regs->cdv.saveDSPFW[3] = REG_READ(DSPFW4);
 273         regs->cdv.saveDSPFW[4] = REG_READ(DSPFW5);
 274         regs->cdv.saveDSPFW[5] = REG_READ(DSPFW6);
 275 
 276         regs->cdv.saveADPA = REG_READ(ADPA);
 277 
 278         regs->cdv.savePP_CONTROL = REG_READ(PP_CONTROL);
 279         regs->cdv.savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS);
 280         regs->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
 281         regs->saveBLC_PWM_CTL2 = REG_READ(BLC_PWM_CTL2);
 282         regs->cdv.saveLVDS = REG_READ(LVDS);
 283 
 284         regs->cdv.savePFIT_CONTROL = REG_READ(PFIT_CONTROL);
 285 
 286         regs->cdv.savePP_ON_DELAYS = REG_READ(PP_ON_DELAYS);
 287         regs->cdv.savePP_OFF_DELAYS = REG_READ(PP_OFF_DELAYS);
 288         regs->cdv.savePP_CYCLE = REG_READ(PP_CYCLE);
 289 
 290         regs->cdv.saveVGACNTRL = REG_READ(VGACNTRL);
 291 
 292         regs->cdv.saveIER = REG_READ(PSB_INT_ENABLE_R);
 293         regs->cdv.saveIMR = REG_READ(PSB_INT_MASK_R);
 294 
 295         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
 296                 connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF);
 297 
 298         return 0;
 299 }
 300 
 301 /**
 302  *      cdv_restore_display_registers   -       restore lost register state
 303  *      @dev: our DRM device
 304  *
 305  *      Restore register state that was lost during suspend and resume.
 306  *
 307  *      FIXME: review
 308  */
 309 static int cdv_restore_display_registers(struct drm_device *dev)
 310 {
 311         struct drm_psb_private *dev_priv = dev->dev_private;
 312         struct psb_save_area *regs = &dev_priv->regs;
 313         struct drm_connector *connector;
 314         u32 temp;
 315 
 316         pci_write_config_byte(dev->pdev, 0xF4, regs->cdv.saveLBB);
 317 
 318         REG_WRITE(DSPCLK_GATE_D, regs->cdv.saveDSPCLK_GATE_D);
 319         REG_WRITE(RAMCLK_GATE_D, regs->cdv.saveRAMCLK_GATE_D);
 320 
 321         /* BIOS does below anyway */
 322         REG_WRITE(DPIO_CFG, 0);
 323         REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N);
 324 
 325         temp = REG_READ(DPLL_A);
 326         if ((temp & DPLL_SYNCLOCK_ENABLE) == 0) {
 327                 REG_WRITE(DPLL_A, temp | DPLL_SYNCLOCK_ENABLE);
 328                 REG_READ(DPLL_A);
 329         }
 330 
 331         temp = REG_READ(DPLL_B);
 332         if ((temp & DPLL_SYNCLOCK_ENABLE) == 0) {
 333                 REG_WRITE(DPLL_B, temp | DPLL_SYNCLOCK_ENABLE);
 334                 REG_READ(DPLL_B);
 335         }
 336 
 337         udelay(500);
 338 
 339         REG_WRITE(DSPFW1, regs->cdv.saveDSPFW[0]);
 340         REG_WRITE(DSPFW2, regs->cdv.saveDSPFW[1]);
 341         REG_WRITE(DSPFW3, regs->cdv.saveDSPFW[2]);
 342         REG_WRITE(DSPFW4, regs->cdv.saveDSPFW[3]);
 343         REG_WRITE(DSPFW5, regs->cdv.saveDSPFW[4]);
 344         REG_WRITE(DSPFW6, regs->cdv.saveDSPFW[5]);
 345 
 346         REG_WRITE(DSPARB, regs->cdv.saveDSPARB);
 347         REG_WRITE(ADPA, regs->cdv.saveADPA);
 348 
 349         REG_WRITE(BLC_PWM_CTL2, regs->saveBLC_PWM_CTL2);
 350         REG_WRITE(LVDS, regs->cdv.saveLVDS);
 351         REG_WRITE(PFIT_CONTROL, regs->cdv.savePFIT_CONTROL);
 352         REG_WRITE(PFIT_PGM_RATIOS, regs->cdv.savePFIT_PGM_RATIOS);
 353         REG_WRITE(BLC_PWM_CTL, regs->saveBLC_PWM_CTL);
 354         REG_WRITE(PP_ON_DELAYS, regs->cdv.savePP_ON_DELAYS);
 355         REG_WRITE(PP_OFF_DELAYS, regs->cdv.savePP_OFF_DELAYS);
 356         REG_WRITE(PP_CYCLE, regs->cdv.savePP_CYCLE);
 357         REG_WRITE(PP_CONTROL, regs->cdv.savePP_CONTROL);
 358 
 359         REG_WRITE(VGACNTRL, regs->cdv.saveVGACNTRL);
 360 
 361         REG_WRITE(PSB_INT_ENABLE_R, regs->cdv.saveIER);
 362         REG_WRITE(PSB_INT_MASK_R, regs->cdv.saveIMR);
 363 
 364         /* Fix arbitration bug */
 365         cdv_errata(dev);
 366 
 367         drm_mode_config_reset(dev);
 368 
 369         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
 370                 connector->funcs->dpms(connector, DRM_MODE_DPMS_ON);
 371 
 372         /* Resume the modeset for every activated CRTC */
 373         drm_helper_resume_force_mode(dev);
 374         return 0;
 375 }
 376 
 377 static int cdv_power_down(struct drm_device *dev)
 378 {
 379         struct drm_psb_private *dev_priv = dev->dev_private;
 380         u32 pwr_cnt, pwr_mask, pwr_sts;
 381         int tries = 5;
 382 
 383         pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD);
 384         pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
 385         pwr_cnt |= PSB_PWRGT_GFX_OFF;
 386         pwr_mask = PSB_PWRGT_GFX_MASK;
 387 
 388         outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
 389 
 390         while (tries--) {
 391                 pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
 392                 if ((pwr_sts & pwr_mask) == PSB_PWRGT_GFX_D3)
 393                         return 0;
 394                 udelay(10);
 395         }
 396         return 0;
 397 }
 398 
 399 static int cdv_power_up(struct drm_device *dev)
 400 {
 401         struct drm_psb_private *dev_priv = dev->dev_private;
 402         u32 pwr_cnt, pwr_mask, pwr_sts;
 403         int tries = 5;
 404 
 405         pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD);
 406         pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
 407         pwr_cnt |= PSB_PWRGT_GFX_ON;
 408         pwr_mask = PSB_PWRGT_GFX_MASK;
 409 
 410         outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
 411 
 412         while (tries--) {
 413                 pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
 414                 if ((pwr_sts & pwr_mask) == PSB_PWRGT_GFX_D0)
 415                         return 0;
 416                 udelay(10);
 417         }
 418         return 0;
 419 }
 420 
 421 static void cdv_hotplug_work_func(struct work_struct *work)
 422 {
 423         struct drm_psb_private *dev_priv = container_of(work, struct drm_psb_private,
 424                                                         hotplug_work);                 
 425         struct drm_device *dev = dev_priv->dev;
 426 
 427         /* Just fire off a uevent and let userspace tell us what to do */
 428         drm_helper_hpd_irq_event(dev);
 429 }                       
 430 
 431 /* The core driver has received a hotplug IRQ. We are in IRQ context
 432    so extract the needed information and kick off queued processing */
 433    
 434 static int cdv_hotplug_event(struct drm_device *dev)
 435 {
 436         struct drm_psb_private *dev_priv = dev->dev_private;
 437         schedule_work(&dev_priv->hotplug_work);
 438         REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
 439         return 1;
 440 }
 441 
 442 static void cdv_hotplug_enable(struct drm_device *dev, bool on)
 443 {
 444         if (on) {
 445                 u32 hotplug = REG_READ(PORT_HOTPLUG_EN);
 446                 hotplug |= HDMIB_HOTPLUG_INT_EN | HDMIC_HOTPLUG_INT_EN |
 447                            HDMID_HOTPLUG_INT_EN | CRT_HOTPLUG_INT_EN;
 448                 REG_WRITE(PORT_HOTPLUG_EN, hotplug);
 449         }  else {
 450                 REG_WRITE(PORT_HOTPLUG_EN, 0);
 451                 REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
 452         }       
 453 }
 454 
 455 static const char *force_audio_names[] = {
 456         "off",
 457         "auto",
 458         "on",
 459 };
 460 
 461 void cdv_intel_attach_force_audio_property(struct drm_connector *connector)
 462 {
 463         struct drm_device *dev = connector->dev;
 464         struct drm_psb_private *dev_priv = dev->dev_private;
 465         struct drm_property *prop;
 466         int i;
 467 
 468         prop = dev_priv->force_audio_property;
 469         if (prop == NULL) {
 470                 prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
 471                                            "audio",
 472                                            ARRAY_SIZE(force_audio_names));
 473                 if (prop == NULL)
 474                         return;
 475 
 476                 for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
 477                         drm_property_add_enum(prop, i-1, force_audio_names[i]);
 478 
 479                 dev_priv->force_audio_property = prop;
 480         }
 481         drm_object_attach_property(&connector->base, prop, 0);
 482 }
 483 
 484 
 485 static const char *broadcast_rgb_names[] = {
 486         "Full",
 487         "Limited 16:235",
 488 };
 489 
 490 void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector)
 491 {
 492         struct drm_device *dev = connector->dev;
 493         struct drm_psb_private *dev_priv = dev->dev_private;
 494         struct drm_property *prop;
 495         int i;
 496 
 497         prop = dev_priv->broadcast_rgb_property;
 498         if (prop == NULL) {
 499                 prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
 500                                            "Broadcast RGB",
 501                                            ARRAY_SIZE(broadcast_rgb_names));
 502                 if (prop == NULL)
 503                         return;
 504 
 505                 for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++)
 506                         drm_property_add_enum(prop, i, broadcast_rgb_names[i]);
 507 
 508                 dev_priv->broadcast_rgb_property = prop;
 509         }
 510 
 511         drm_object_attach_property(&connector->base, prop, 0);
 512 }
 513 
 514 /* Cedarview */
 515 static const struct psb_offset cdv_regmap[2] = {
 516         {
 517                 .fp0 = FPA0,
 518                 .fp1 = FPA1,
 519                 .cntr = DSPACNTR,
 520                 .conf = PIPEACONF,
 521                 .src = PIPEASRC,
 522                 .dpll = DPLL_A,
 523                 .dpll_md = DPLL_A_MD,
 524                 .htotal = HTOTAL_A,
 525                 .hblank = HBLANK_A,
 526                 .hsync = HSYNC_A,
 527                 .vtotal = VTOTAL_A,
 528                 .vblank = VBLANK_A,
 529                 .vsync = VSYNC_A,
 530                 .stride = DSPASTRIDE,
 531                 .size = DSPASIZE,
 532                 .pos = DSPAPOS,
 533                 .base = DSPABASE,
 534                 .surf = DSPASURF,
 535                 .addr = DSPABASE,
 536                 .status = PIPEASTAT,
 537                 .linoff = DSPALINOFF,
 538                 .tileoff = DSPATILEOFF,
 539                 .palette = PALETTE_A,
 540         },
 541         {
 542                 .fp0 = FPB0,
 543                 .fp1 = FPB1,
 544                 .cntr = DSPBCNTR,
 545                 .conf = PIPEBCONF,
 546                 .src = PIPEBSRC,
 547                 .dpll = DPLL_B,
 548                 .dpll_md = DPLL_B_MD,
 549                 .htotal = HTOTAL_B,
 550                 .hblank = HBLANK_B,
 551                 .hsync = HSYNC_B,
 552                 .vtotal = VTOTAL_B,
 553                 .vblank = VBLANK_B,
 554                 .vsync = VSYNC_B,
 555                 .stride = DSPBSTRIDE,
 556                 .size = DSPBSIZE,
 557                 .pos = DSPBPOS,
 558                 .base = DSPBBASE,
 559                 .surf = DSPBSURF,
 560                 .addr = DSPBBASE,
 561                 .status = PIPEBSTAT,
 562                 .linoff = DSPBLINOFF,
 563                 .tileoff = DSPBTILEOFF,
 564                 .palette = PALETTE_B,
 565         }
 566 };
 567 
 568 static int cdv_chip_setup(struct drm_device *dev)
 569 {
 570         struct drm_psb_private *dev_priv = dev->dev_private;
 571         INIT_WORK(&dev_priv->hotplug_work, cdv_hotplug_work_func);
 572 
 573         if (pci_enable_msi(dev->pdev))
 574                 dev_warn(dev->dev, "Enabling MSI failed!\n");
 575         dev_priv->regmap = cdv_regmap;
 576         gma_get_core_freq(dev);
 577         psb_intel_opregion_init(dev);
 578         psb_intel_init_bios(dev);
 579         cdv_hotplug_enable(dev, false);
 580         return 0;
 581 }
 582 
 583 /* CDV is much like Poulsbo but has MID like SGX offsets and PM */
 584 
 585 const struct psb_ops cdv_chip_ops = {
 586         .name = "GMA3600/3650",
 587         .accel_2d = 0,
 588         .pipes = 2,
 589         .crtcs = 2,
 590         .hdmi_mask = (1 << 0) | (1 << 1),
 591         .lvds_mask = (1 << 1),
 592         .sdvo_mask = (1 << 0),
 593         .cursor_needs_phys = 0,
 594         .sgx_offset = MRST_SGX_OFFSET,
 595         .chip_setup = cdv_chip_setup,
 596         .errata = cdv_errata,
 597 
 598         .crtc_helper = &cdv_intel_helper_funcs,
 599         .crtc_funcs = &cdv_intel_crtc_funcs,
 600         .clock_funcs = &cdv_clock_funcs,
 601 
 602         .output_init = cdv_output_init,
 603         .hotplug = cdv_hotplug_event,
 604         .hotplug_enable = cdv_hotplug_enable,
 605 
 606 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
 607         .backlight_init = cdv_backlight_init,
 608 #endif
 609 
 610         .init_pm = cdv_init_pm,
 611         .save_regs = cdv_save_display_registers,
 612         .restore_regs = cdv_restore_display_registers,
 613         .save_crtc = gma_crtc_save,
 614         .restore_crtc = gma_crtc_restore,
 615         .power_down = cdv_power_down,
 616         .power_up = cdv_power_up,
 617         .update_wm = cdv_update_wm,
 618         .disable_sr = cdv_disable_sr,
 619 };

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