1 /* 2 * Copyright © 2010 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: 24 * Li Peng <peng.li@intel.com> 25 */ 26 27 #include <drm/drmP.h> 28 #include <drm/drm.h> 29 #include "psb_intel_drv.h" 30 #include "psb_intel_reg.h" 31 #include "psb_drv.h" 32 33 #define HDMI_READ(reg) readl(hdmi_dev->regs + (reg)) 34 #define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg)) 35 36 #define HDMI_HCR 0x1000 37 #define HCR_ENABLE_HDCP (1 << 5) 38 #define HCR_ENABLE_AUDIO (1 << 2) 39 #define HCR_ENABLE_PIXEL (1 << 1) 40 #define HCR_ENABLE_TMDS (1 << 0) 41 42 #define HDMI_HICR 0x1004 43 #define HDMI_HSR 0x1008 44 #define HDMI_HISR 0x100C 45 #define HDMI_DETECT_HDP (1 << 0) 46 47 #define HDMI_VIDEO_REG 0x3000 48 #define HDMI_UNIT_EN (1 << 7) 49 #define HDMI_MODE_OUTPUT (1 << 0) 50 #define HDMI_HBLANK_A 0x3100 51 52 #define HDMI_AUDIO_CTRL 0x4000 53 #define HDMI_ENABLE_AUDIO (1 << 0) 54 55 #define PCH_HTOTAL_B 0x3100 56 #define PCH_HBLANK_B 0x3104 57 #define PCH_HSYNC_B 0x3108 58 #define PCH_VTOTAL_B 0x310C 59 #define PCH_VBLANK_B 0x3110 60 #define PCH_VSYNC_B 0x3114 61 #define PCH_PIPEBSRC 0x311C 62 63 #define PCH_PIPEB_DSL 0x3800 64 #define PCH_PIPEB_SLC 0x3804 65 #define PCH_PIPEBCONF 0x3808 66 #define PCH_PIPEBSTAT 0x3824 67 68 #define CDVO_DFT 0x5000 69 #define CDVO_SLEWRATE 0x5004 70 #define CDVO_STRENGTH 0x5008 71 #define CDVO_RCOMP 0x500C 72 73 #define DPLL_CTRL 0x6000 74 #define DPLL_PDIV_SHIFT 16 75 #define DPLL_PDIV_MASK (0xf << 16) 76 #define DPLL_PWRDN (1 << 4) 77 #define DPLL_RESET (1 << 3) 78 #define DPLL_FASTEN (1 << 2) 79 #define DPLL_ENSTAT (1 << 1) 80 #define DPLL_DITHEN (1 << 0) 81 82 #define DPLL_DIV_CTRL 0x6004 83 #define DPLL_CLKF_MASK 0xffffffc0 84 #define DPLL_CLKR_MASK (0x3f) 85 86 #define DPLL_CLK_ENABLE 0x6008 87 #define DPLL_EN_DISP (1 << 31) 88 #define DPLL_SEL_HDMI (1 << 8) 89 #define DPLL_EN_HDMI (1 << 1) 90 #define DPLL_EN_VGA (1 << 0) 91 92 #define DPLL_ADJUST 0x600C 93 #define DPLL_STATUS 0x6010 94 #define DPLL_UPDATE 0x6014 95 #define DPLL_DFT 0x6020 96 97 struct intel_range { 98 int min, max; 99 }; 100 101 struct oaktrail_hdmi_limit { 102 struct intel_range vco, np, nr, nf; 103 }; 104 105 struct oaktrail_hdmi_clock { 106 int np; 107 int nr; 108 int nf; 109 int dot; 110 }; 111 112 #define VCO_MIN 320000 113 #define VCO_MAX 1650000 114 #define NP_MIN 1 115 #define NP_MAX 15 116 #define NR_MIN 1 117 #define NR_MAX 64 118 #define NF_MIN 2 119 #define NF_MAX 4095 120 121 static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = { 122 .vco = { .min = VCO_MIN, .max = VCO_MAX }, 123 .np = { .min = NP_MIN, .max = NP_MAX }, 124 .nr = { .min = NR_MIN, .max = NR_MAX }, 125 .nf = { .min = NF_MIN, .max = NF_MAX }, 126 }; 127 128 static void oaktrail_hdmi_audio_enable(struct drm_device *dev) 129 { 130 struct drm_psb_private *dev_priv = dev->dev_private; 131 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 132 133 HDMI_WRITE(HDMI_HCR, 0x67); 134 HDMI_READ(HDMI_HCR); 135 136 HDMI_WRITE(0x51a8, 0x10); 137 HDMI_READ(0x51a8); 138 139 HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1); 140 HDMI_READ(HDMI_AUDIO_CTRL); 141 } 142 143 static void oaktrail_hdmi_audio_disable(struct drm_device *dev) 144 { 145 struct drm_psb_private *dev_priv = dev->dev_private; 146 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 147 148 HDMI_WRITE(0x51a8, 0x0); 149 HDMI_READ(0x51a8); 150 151 HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0); 152 HDMI_READ(HDMI_AUDIO_CTRL); 153 154 HDMI_WRITE(HDMI_HCR, 0x47); 155 HDMI_READ(HDMI_HCR); 156 } 157 158 static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode) 159 { 160 static int dpms_mode = -1; 161 162 struct drm_device *dev = encoder->dev; 163 struct drm_psb_private *dev_priv = dev->dev_private; 164 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 165 u32 temp; 166 167 if (dpms_mode == mode) 168 return; 169 170 if (mode != DRM_MODE_DPMS_ON) 171 temp = 0x0; 172 else 173 temp = 0x99; 174 175 dpms_mode = mode; 176 HDMI_WRITE(HDMI_VIDEO_REG, temp); 177 } 178 179 static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, 180 struct drm_display_mode *mode) 181 { 182 if (mode->clock > 165000) 183 return MODE_CLOCK_HIGH; 184 if (mode->clock < 20000) 185 return MODE_CLOCK_LOW; 186 187 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 188 return MODE_NO_DBLESCAN; 189 190 return MODE_OK; 191 } 192 193 static bool oaktrail_hdmi_mode_fixup(struct drm_encoder *encoder, 194 const struct drm_display_mode *mode, 195 struct drm_display_mode *adjusted_mode) 196 { 197 return true; 198 } 199 200 static enum drm_connector_status 201 oaktrail_hdmi_detect(struct drm_connector *connector, bool force) 202 { 203 enum drm_connector_status status; 204 struct drm_device *dev = connector->dev; 205 struct drm_psb_private *dev_priv = dev->dev_private; 206 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 207 u32 temp; 208 209 temp = HDMI_READ(HDMI_HSR); 210 DRM_DEBUG_KMS("HDMI_HSR %x\n", temp); 211 212 if ((temp & HDMI_DETECT_HDP) != 0) 213 status = connector_status_connected; 214 else 215 status = connector_status_disconnected; 216 217 return status; 218 } 219 220 static const unsigned char raw_edid[] = { 221 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0, 222 0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78, 223 0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5, 224 0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01, 225 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0, 226 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a, 227 0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35, 228 0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44, 229 0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20, 230 0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a, 231 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d 232 }; 233 234 static int oaktrail_hdmi_get_modes(struct drm_connector *connector) 235 { 236 struct drm_device *dev = connector->dev; 237 struct drm_psb_private *dev_priv = dev->dev_private; 238 struct i2c_adapter *i2c_adap; 239 struct edid *edid; 240 struct drm_display_mode *mode, *t; 241 int i = 0, ret = 0; 242 243 i2c_adap = i2c_get_adapter(3); 244 if (i2c_adap == NULL) { 245 DRM_ERROR("No ddc adapter available!\n"); 246 edid = (struct edid *)raw_edid; 247 } else { 248 edid = (struct edid *)raw_edid; 249 /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */ 250 } 251 252 if (edid) { 253 drm_mode_connector_update_edid_property(connector, edid); 254 ret = drm_add_edid_modes(connector, edid); 255 } 256 257 /* 258 * prune modes that require frame buffer bigger than stolen mem 259 */ 260 list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { 261 if ((mode->hdisplay * mode->vdisplay * 4) >= dev_priv->vram_stolen_size) { 262 i++; 263 drm_mode_remove(connector, mode); 264 } 265 } 266 return ret - i; 267 } 268 269 static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder, 270 struct drm_display_mode *mode, 271 struct drm_display_mode *adjusted_mode) 272 { 273 struct drm_device *dev = encoder->dev; 274 275 oaktrail_hdmi_audio_enable(dev); 276 return; 277 } 278 279 static void oaktrail_hdmi_destroy(struct drm_connector *connector) 280 { 281 return; 282 } 283 284 static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = { 285 .dpms = oaktrail_hdmi_dpms, 286 .mode_fixup = oaktrail_hdmi_mode_fixup, 287 .prepare = psb_intel_encoder_prepare, 288 .mode_set = oaktrail_hdmi_mode_set, 289 .commit = psb_intel_encoder_commit, 290 }; 291 292 static const struct drm_connector_helper_funcs 293 oaktrail_hdmi_connector_helper_funcs = { 294 .get_modes = oaktrail_hdmi_get_modes, 295 .mode_valid = oaktrail_hdmi_mode_valid, 296 .best_encoder = psb_intel_best_encoder, 297 }; 298 299 static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = { 300 .dpms = drm_helper_connector_dpms, 301 .detect = oaktrail_hdmi_detect, 302 .fill_modes = drm_helper_probe_single_connector_modes, 303 .destroy = oaktrail_hdmi_destroy, 304 }; 305 306 static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder) 307 { 308 drm_encoder_cleanup(encoder); 309 } 310 311 static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = { 312 .destroy = oaktrail_hdmi_enc_destroy, 313 }; 314 315 void oaktrail_hdmi_init(struct drm_device *dev, 316 struct psb_intel_mode_device *mode_dev) 317 { 318 struct psb_intel_encoder *psb_intel_encoder; 319 struct psb_intel_connector *psb_intel_connector; 320 struct drm_connector *connector; 321 struct drm_encoder *encoder; 322 323 psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL); 324 if (!psb_intel_encoder) 325 return; 326 327 psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL); 328 if (!psb_intel_connector) 329 goto failed_connector; 330 331 connector = &psb_intel_connector->base; 332 encoder = &psb_intel_encoder->base; 333 drm_connector_init(dev, connector, 334 &oaktrail_hdmi_connector_funcs, 335 DRM_MODE_CONNECTOR_DVID); 336 337 drm_encoder_init(dev, encoder, 338 &oaktrail_hdmi_enc_funcs, 339 DRM_MODE_ENCODER_TMDS); 340 341 psb_intel_connector_attach_encoder(psb_intel_connector, 342 psb_intel_encoder); 343 344 psb_intel_encoder->type = INTEL_OUTPUT_HDMI; 345 drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs); 346 drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs); 347 348 connector->display_info.subpixel_order = SubPixelHorizontalRGB; 349 connector->interlace_allowed = false; 350 connector->doublescan_allowed = false; 351 drm_sysfs_connector_add(connector); 352 353 return; 354 355 failed_connector: 356 kfree(psb_intel_encoder); 357 } 358 359 static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = { 360 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) }, 361 { 0 } 362 }; 363 364 void oaktrail_hdmi_setup(struct drm_device *dev) 365 { 366 struct drm_psb_private *dev_priv = dev->dev_private; 367 struct pci_dev *pdev; 368 struct oaktrail_hdmi_dev *hdmi_dev; 369 int ret; 370 371 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL); 372 if (!pdev) 373 return; 374 375 hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL); 376 if (!hdmi_dev) { 377 dev_err(dev->dev, "failed to allocate memory\n"); 378 goto out; 379 } 380 381 382 ret = pci_enable_device(pdev); 383 if (ret) { 384 dev_err(dev->dev, "failed to enable hdmi controller\n"); 385 goto free; 386 } 387 388 hdmi_dev->mmio = pci_resource_start(pdev, 0); 389 hdmi_dev->mmio_len = pci_resource_len(pdev, 0); 390 hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len); 391 if (!hdmi_dev->regs) { 392 dev_err(dev->dev, "failed to map hdmi mmio\n"); 393 goto free; 394 } 395 396 hdmi_dev->dev = pdev; 397 pci_set_drvdata(pdev, hdmi_dev); 398 399 /* Initialize i2c controller */ 400 ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev); 401 if (ret) 402 dev_err(dev->dev, "HDMI I2C initialization failed\n"); 403 404 dev_priv->hdmi_priv = hdmi_dev; 405 oaktrail_hdmi_audio_disable(dev); 406 return; 407 408 free: 409 kfree(hdmi_dev); 410 out: 411 return; 412 } 413 414 void oaktrail_hdmi_teardown(struct drm_device *dev) 415 { 416 struct drm_psb_private *dev_priv = dev->dev_private; 417 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 418 struct pci_dev *pdev; 419 420 if (hdmi_dev) { 421 pdev = hdmi_dev->dev; 422 pci_set_drvdata(pdev, NULL); 423 oaktrail_hdmi_i2c_exit(pdev); 424 iounmap(hdmi_dev->regs); 425 kfree(hdmi_dev); 426 pci_dev_put(pdev); 427 } 428 } 429 430 /* save HDMI register state */ 431 void oaktrail_hdmi_save(struct drm_device *dev) 432 { 433 struct drm_psb_private *dev_priv = dev->dev_private; 434 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 435 struct psb_state *regs = &dev_priv->regs.psb; 436 struct psb_pipe *pipeb = &dev_priv->regs.pipe[1]; 437 int i; 438 439 /* dpll */ 440 hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL); 441 hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL); 442 hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST); 443 hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE); 444 hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE); 445 446 /* pipe B */ 447 pipeb->conf = PSB_RVDC32(PIPEBCONF); 448 pipeb->src = PSB_RVDC32(PIPEBSRC); 449 pipeb->htotal = PSB_RVDC32(HTOTAL_B); 450 pipeb->hblank = PSB_RVDC32(HBLANK_B); 451 pipeb->hsync = PSB_RVDC32(HSYNC_B); 452 pipeb->vtotal = PSB_RVDC32(VTOTAL_B); 453 pipeb->vblank = PSB_RVDC32(VBLANK_B); 454 pipeb->vsync = PSB_RVDC32(VSYNC_B); 455 456 hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF); 457 hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC); 458 hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B); 459 hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B); 460 hdmi_dev->savePCH_HSYNC_B = PSB_RVDC32(PCH_HSYNC_B); 461 hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B); 462 hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B); 463 hdmi_dev->savePCH_VSYNC_B = PSB_RVDC32(PCH_VSYNC_B); 464 465 /* plane */ 466 pipeb->cntr = PSB_RVDC32(DSPBCNTR); 467 pipeb->stride = PSB_RVDC32(DSPBSTRIDE); 468 pipeb->addr = PSB_RVDC32(DSPBBASE); 469 pipeb->surf = PSB_RVDC32(DSPBSURF); 470 pipeb->linoff = PSB_RVDC32(DSPBLINOFF); 471 pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF); 472 473 /* cursor B */ 474 regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR); 475 regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE); 476 regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS); 477 478 /* save palette */ 479 for (i = 0; i < 256; i++) 480 pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2)); 481 } 482 483 /* restore HDMI register state */ 484 void oaktrail_hdmi_restore(struct drm_device *dev) 485 { 486 struct drm_psb_private *dev_priv = dev->dev_private; 487 struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; 488 struct psb_state *regs = &dev_priv->regs.psb; 489 struct psb_pipe *pipeb = &dev_priv->regs.pipe[1]; 490 int i; 491 492 /* dpll */ 493 PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL); 494 PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL); 495 PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST); 496 PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE); 497 PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE); 498 DRM_UDELAY(150); 499 500 /* pipe */ 501 PSB_WVDC32(pipeb->src, PIPEBSRC); 502 PSB_WVDC32(pipeb->htotal, HTOTAL_B); 503 PSB_WVDC32(pipeb->hblank, HBLANK_B); 504 PSB_WVDC32(pipeb->hsync, HSYNC_B); 505 PSB_WVDC32(pipeb->vtotal, VTOTAL_B); 506 PSB_WVDC32(pipeb->vblank, VBLANK_B); 507 PSB_WVDC32(pipeb->vsync, VSYNC_B); 508 509 PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC); 510 PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B); 511 PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B); 512 PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B, PCH_HSYNC_B); 513 PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B); 514 PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B); 515 PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B, PCH_VSYNC_B); 516 517 PSB_WVDC32(pipeb->conf, PIPEBCONF); 518 PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF); 519 520 /* plane */ 521 PSB_WVDC32(pipeb->linoff, DSPBLINOFF); 522 PSB_WVDC32(pipeb->stride, DSPBSTRIDE); 523 PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF); 524 PSB_WVDC32(pipeb->cntr, DSPBCNTR); 525 PSB_WVDC32(pipeb->surf, DSPBSURF); 526 527 /* cursor B */ 528 PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR); 529 PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS); 530 PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE); 531 532 /* restore palette */ 533 for (i = 0; i < 256; i++) 534 PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2)); 535 } 536