2 *-----------------------------------------------------------------------------
3 * Filename: micro_mode_plb.c
5 *-----------------------------------------------------------------------------
6 * Copyright (c) 2002-2010, Intel Corporation.
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 *-----------------------------------------------------------------------------
28 * Napa Core implementations for the mode dispatch functions.
29 * NOTE: This file is designed to produce tiny code and is used in the
30 * vbios port. Make sure that all MMIO reads and writes do all mmio
31 * calculation within the OS_READ and OS_WRITE macros so that this code
32 * will be correctly removed.
33 * This is OK -> EMGD_READ32( MMIO(display) + foo_offset )
34 * This is NOT OK -> mmio = MMIO(display)
35 * EMGD_READ32(mmio + foo_offset)
36 *-----------------------------------------------------------------------------
39 #define MODULE_NAME hal.mode
53 #include <mode_access.h>
58 #include <plb/context.h>
60 #include "drm_emgd_private.h"
62 #include "../cmn/match.h"
63 #include "../cmn/mode_dispatch.h"
67 * @addtogroup display_group
74 * Exports from the other components of this module.
77 extern int program_clock_plb(igd_display_context_t *display,
78 igd_clock_t *clock, unsigned long dclk);
79 extern mode_full_dispatch_t mode_full_dispatch_plb;
81 static unsigned long gpio_plb[] = {
91 mode_data_plb_t device_data_plb[1] = {
93 0x000b0000, /* plane a preservation */
94 0x00000000, /* plane b/c preservation */
95 0x01000000, /* pipe preservation */
96 0, /* port preservation */
97 0x490A010A, /* watermark/burst length 1 */
98 0x14100D0A, /* watermark/burst length 2*/
99 0x00007770, /* watermark/burst length 3 */
100 0x0B0C9812, /* watermark/burst length self */
102 0x00001D9C, /* dsp arb */
112 void disable_vga_plb (unsigned char *mmio)
119 /* Disable VGA plane if it is enabled. */
120 temp = EMGD_READ32(EMGD_MMIO(mmio) + VGACNTRL);
121 if ((temp & BIT31) == 0) {
123 READ_VGA(mmio, SR_PORT, 0x01, sr01);
125 /* Turn on SR01 bit 5 */
126 WRITE_VGA(mmio, SR_PORT, 0x01, sr01|BIT(5));
130 temp |= BIT31; /* set bit 31 to disable */
131 temp &= ~BIT30; /* clear bit 30 to get VGA display in normal size */
132 EMGD_WRITE32(temp, EMGD_MMIO(mmio) + VGACNTRL);
135 * When turing off the VGA plane the palette sometimes gets stuck.
136 * if we do a couple reads to the palette it will unstuck.
138 if((1L<<31) & EMGD_READ32( EMGD_MMIO(mmio) + PIPEA_CONF )) {
139 EMGD_DEBUG("VGA Palette workaround");
140 EMGD_READ32(EMGD_MMIO(mmio) + DPALETTE_A);
141 EMGD_READ32(EMGD_MMIO(mmio) + DPALETTE_A);
143 if((1L<<31) & EMGD_READ32( EMGD_MMIO(mmio) + PIPEB_CONF )) {
144 EMGD_DEBUG("VGA Palette workaround");
145 EMGD_READ32(EMGD_MMIO(mmio) + DPALETTE_B);
146 EMGD_READ32(EMGD_MMIO(mmio) + DPALETTE_B);
154 * @param display_handle
155 * @param palette_entry
156 * @param palette_color
158 * @return 0 on success
159 * @return -IGD_INVAL on failure
161 static int igd_set_palette_entry_plb(
162 igd_display_h display_handle,
163 unsigned long palette_entry,
164 unsigned long palette_color)
166 /* Too Slow For Tracing */
168 /* Return if Pipe is not on */
169 if(!((1L<<31) & EMGD_READ32(MMIO(display_handle) +
170 PIPE(display_handle)->pipe_reg))) {
174 EMGD_DEBUG("%x : %ld : %lx", display_handle,
175 palette_entry, palette_color);
177 EMGD_WRITE32(palette_color, MMIO(display_handle) +
178 PIPE(display_handle)->palette_reg + palette_entry * 4);
185 * @param display_handle
186 * @param palette_entry
187 * @param palette_color
189 * @return 0 on success
190 * @return -IGD_INVAL on failure
192 static int igd_get_palette_entry_plb(
193 igd_display_h display_handle,
194 unsigned long palette_entry,
195 unsigned long *palette_color)
197 /* Too Slow For Tracing */
199 /* Return if Pipe is not on */
200 if(!((1L<<31) & EMGD_READ32(MMIO(display_handle) +
201 PIPE(display_handle)->pipe_reg))) {
205 *palette_color = 0xffffff & EMGD_READ32(MMIO(display_handle) +
206 PIPE(display_handle)->palette_reg + palette_entry * 4);
214 * @param time_interval
216 * @return 0 on success
217 * @return 1 on failure
219 int wait_for_vblank_timeout_plb(
221 unsigned long pipe_reg,
222 unsigned long time_interval)
225 unsigned long pipe_status_reg = pipe_reg + PIPE_STATUS_OFFSET;
228 unsigned long request_for;
231 EMGD_DEBUG("Parameters: MMIO = %p, pipe_reg = %lx, time_interval = %lx",
232 mmio, pipe_reg, time_interval);
234 /* If pipe is off then just return */
235 if(!((1L<<31) & EMGD_READ32(EMGD_MMIO(mmio) + pipe_reg))) {
236 EMGD_DEBUG("Pipe disabled/Off");
242 * When VGA plane is on the normal wait for vblank won't work
245 if(!(EMGD_READ32(EMGD_MMIO(mmio) + 0x71400) & 0x80000000)) {
246 EMGD_DEBUG("VGA Plane On");
251 /* 1. Request the interrupt handler to record the next VBlank: */
252 request_for = VBINT_REQUEST(VBINT_WAIT,
253 (pipe_status_reg == PIPEA_STAT) ? VBINT_PORT2 : VBINT_PORT4);
254 mode_context->dispatch->full->request_vblanks(request_for, mmio);
256 /* 2. Wait & poll for the next VBlank: */
257 timeout = OS_SET_ALARM(time_interval);
260 tmp = mode_context->dispatch->full->vblank_occured(request_for);
261 } while ((tmp == 0x00) && (!OS_TEST_ALARM(timeout)));
263 EMGD_ERROR_EXIT("Timeout waiting for VBLANK");
269 /* 3. End our request for the next VBlank: */
270 mode_context->dispatch->full->end_request(request_for, mmio);
275 } /* wait_for_vblank_timeout_plb */
282 * @return 0 on success
283 * @return 1 on failure
285 int wait_for_vblank_plb(unsigned char *mmio,
286 unsigned long pipe_reg)
288 return wait_for_vblank_timeout_plb(mmio, pipe_reg, 100);
289 } /* wait_for_vblank_plb */
293 * This procedure waits for the next vertical blanking (vertical retrace)
294 * period. If the display is already in a vertical blanking period, this
297 * Note: A timeout is included to prevent an endless loop.
299 * @param display_handle
301 * @return FALSE if timed out
303 static int igd_wait_vblank_plb(igd_display_h display_handle)
306 return wait_for_vblank_plb(MMIO(display_handle),
307 PIPE(display_handle)->pipe_reg);
313 * Get the stride and stereo values based on the display. This is also used
314 * by the MI instructions.
316 * @param display Pointer to hardware device instance data
319 * @param flags Should the stereo be for the frontbuffer or backbuffer?
321 * @return stride - Stride of the display
322 * @return stereo - Stereo address of the display
324 static int mode_get_stride_stereo_plb(igd_display_context_t *display,
325 unsigned long *stride,
326 unsigned long *stereo,
329 unsigned long pitch = PLANE(display)->fb_info->screen_pitch;
330 igd_timing_info_t *timing = PIPE(display)->timing;
331 unsigned long base_offset;
333 base_offset = PLANE(display)->fb_info->visible_offset;
338 /* For field replication, valid for interlaced modes only
339 * set stereo = fb_base,
342 if (timing->mode_info_flags & IGD_SCAN_INTERLACE) {
344 if(timing->mode_info_flags & IGD_LINE_DOUBLE) {
345 /* Interlaced + Line double flags means field replication.
346 * same lines are sent for both fields. Program the
347 * second eye to be same as the first.
349 *stereo = base_offset;
351 /* Regular interlaced. Second eye starts on line 2.
352 * Skip every other line.
354 *stereo = base_offset + pitch;
364 * @param display Pointer to hardware device instance data
368 static void program_pipe_vga_plb(
369 igd_display_context_t *display)
371 igd_timing_info_t *timing;
372 unsigned long vga_control;
373 unsigned long upscale = 0;
380 * We cannot set a VGA mode unless the display planes are turned off.
381 * This becomes evident during a Windows BSOD. Since neither Windows
382 * nor IEGD got a chance to turn off these registers, and the VGA mode was
383 * set by the VBIOS, the screen gets corrupted. In order to fix this
384 * problem, we will turn the cursor and display planes here.
386 * Note: Removing previous partial-fix in favor of this complete one.
389 WRITE_MMIO_REG(display, 0x70080, 0);
390 WRITE_MMIO_REG(display, 0x70084, 0);
392 WRITE_MMIO_REG(display, 0x700C0, 0);
393 WRITE_MMIO_REG(display, 0x700C4, 0);
395 WRITE_MMIO_REG(display, 0x70180, 0);
396 WRITE_MMIO_REG(display, 0x70184, 0);
398 WRITE_MMIO_REG(display, 0x71180, 0);
399 WRITE_MMIO_REG(display, 0x71184, 0);
401 WRITE_MMIO_REG(display, 0x72180, 0);
402 WRITE_MMIO_REG(display, 0x72184, 0);
406 * VGA Plane can attach to only one pipe at a time. LVDS can
407 * only attach to pipe B. We need to use the display passed to
408 * determine the pipe number to use. (Plba is same as Alm).
412 * We can come here with following cases:
413 * 1. magic->vga CRT, DVI type displays
414 * 2. native->vga int-lvds, and up-scaling lvds displays
415 * 3. pipe->vga TV and other unscaled-lvds displays
417 vga_control = READ_MMIO_REG(display, 0x71400);
418 vga_control &= 0x18e3ff00;
421 timing = PIPE(display)->timing;
422 if(!timing->extn_ptr) {
423 EMGD_ERROR_EXIT("No Extension pointer in program_pipe_vga_plb");
427 /* Find UPSCALING attr value*/
428 pi_pd_find_attr_and_value(PORT_OWNER(display),
429 PD_ATTR_ID_PANEL_FIT,
430 0,/*no PD_FLAG for UPSCALING */
431 NULL, /* dont need the attr ptr*/
433 /* this PI func will not modify value of upscale if attr does not exist */
435 /* magic->vga or native->vga cases */
436 if ((timing->width == 720 && timing->height == 400) || upscale) {
441 if((timing->width >= 800) && !upscale) {
442 EMGD_DEBUG("Enable VGA Border");
443 vga_control |= (1L<<26);
446 if(timing->width == 640) {
447 EMGD_DEBUG("Enable Nine Dot Disable");
448 vga_control |= (1L<<18);
452 EMGD_DEBUG("Enable VGA Center Centering");
453 vga_control |= 1L<<24;
455 if(timing->height >= 960) {
456 if(timing->width >= 1280) {
457 EMGD_DEBUG("Enable VGA 2x (Nine Dot Disable)");
458 vga_control |= (1L<<30) | (1L<<18);
462 if(PORT_OWNER(display)->port_type == IGD_PORT_LVDS) {
463 EMGD_DEBUG("Enable VGA Upper-Left Centering & Nine Dot Disable");
464 vga_control |= (1L<<25 | (1L<<18));
465 } else if (upscale) {
466 EMGD_DEBUG("Enable VGA Center Upper-left for upscale ports");
467 vga_control |= 1L<<25;
471 if(PIPE(display)->pipe_num) {
472 vga_control |= 1L<<29;
475 program_pipe_vga(display, (igd_timing_info_t *)timing->extn_ptr);
476 WRITE_MMIO_REG(display, 0x71400, vga_control);
483 * Program Display Plane Values.
485 * @param display Pointer to hardware device instance data
490 static void program_plane_plb(igd_display_context_t *display,
491 unsigned long status)
493 unsigned long stereo;
494 unsigned long stride;
496 unsigned long plane_control;
497 igd_timing_info_t *timing;
498 igd_framebuffer_info_t *fb_info = PLANE(display)->fb_info;
499 unsigned long plane_reg = PLANE(display)->plane_reg;
500 unsigned long start_addr_reg = DSPAADDR;
504 EMGD_DEBUG("Program Plane: %s", status?"ENABLE":"DISABLE");
505 EMGD_DEBUG("Device power state: D%ld", GET_DEVICE_POWER_STATE(display));
507 igd_wait_vblank_plb((igd_display_h)display);
509 plane_control = EMGD_READ32(MMIO(display) + plane_reg);
510 if(PLANE(display)->plane_reg == DSPACNTR) {
511 plane_control &= device_data_plb->plane_a_preserve;
513 else { /* if it's plane b or plane c */
514 plane_control &= device_data_plb->plane_b_c_preserve;
515 start_addr_reg = 0x71184;
518 if((status == FALSE) ||
519 (GET_DEVICE_POWER_STATE(display) != IGD_POWERSTATE_D0)) {
522 * Note: The vga programming code does not have an "off". So
523 * when programming the plane to off we make sure VGA is off
526 disable_vga_plb(MMIO(display));
529 * To turn off plane A or B, the program have to triger the plane A or B
530 * start register. Or else, it will not work.
532 EMGD_WRITE32(plane_control, MMIO(display) + plane_reg);
533 EMGD_WRITE32(EMGD_READ32(MMIO(display) + start_addr_reg),
534 MMIO(display) + start_addr_reg);
536 igd_wait_vblank_plb((igd_display_h)display);
540 * Note: The very first pass through this function will be with
541 * status false and timings == NULL. Don't use the timings before
544 timing = PIPE(display)->timing;
545 /* There is a special case code for legacy VGA modes */
546 while (timing->extn_ptr) {
547 timing = (igd_timing_info_t *)timing->extn_ptr;
549 if(MODE_IS_VGA(timing)) {
550 program_plane_vga(display, timing);
554 disable_vga_plb(MMIO(display));
556 size = (((unsigned long)timing->height - 1)<<16) |
557 (unsigned long)(timing->width - 1);
559 /* enable plane, select pipe, enable gamma correction logic */
560 plane_control |= 0x80000000 | (PIPE(display)->pipe_num<<24);
561 PIPE(display)->plane = PLANE(display);
563 plane_control |= (1<<30);
566 /* Here the settings:
567 * If line + pixel dbling, set 21,20 to 01b, and set Horz Multiply
568 * If line dbling only, set 21,20 to 11b
569 * If pixel dbling only, set 21,20 to 00b, but set Horz Multiply
570 * If no doubling, set 21,20 to 00b (no Horz Multiply)
572 * --> both progressive/interlaced modes
574 * --> progressive modes only
577 if (!(timing->mode_info_flags & IGD_SCAN_INTERLACE)) {
578 /* Line doubling in progressive mode requires special bits */
579 if (timing->mode_info_flags & IGD_LINE_DOUBLE) {
580 /* BIT 20 for line & pixel doubling*/
581 plane_control |= BIT20;
582 /* check later, if no pixel doubling, set bit 21 too*/
585 if (timing->mode_info_flags & IGD_PIXEL_DOUBLE) {
586 /* Horz pixel multiply must be set for double */
587 plane_control |= BIT11;
588 /* TODO -> Plba can more than double,
589 It can 3X, 4X etc. These arent exposed now */
591 else if(plane_control & BIT20){
592 /* For line ONLY doubling, set bit 21 also '1' */
593 plane_control |= BIT21;
596 mode_get_stride_stereo_plb(display, &stride, &stereo, 0);
598 /* set color depth */
599 switch (IGD_PF_DEPTH(fb_info->pixel_format)) {
601 plane_control |= BIT27 | BIT30;
604 plane_control |= BIT28 | BIT26;
608 plane_control |= BIT28 | BIT27;
612 if(fb_info->flags & IGD_ENABLE_DISPLAY_GAMMA) {
613 plane_control |= (BIT30);
616 EMGD_DEBUG(" Plane Control = 0x%lx", plane_control);
617 EMGD_DEBUG(" Plane Base = 0x%lx", fb_info->visible_offset);
618 EMGD_DEBUG(" Plane Pitch = 0x%lx", stride);
619 EMGD_DEBUG(" Plane Size = 0x%lx", size);
621 EMGD_WRITE32(stride, MMIO(display) + plane_reg + DSP_STRIDE_OFFSET);
623 * In reality this only exists for plane B. It doesn't seem to hurt
624 * plane A so just do it anyway and save us another case.
626 EMGD_WRITE32(size, MMIO(display) + plane_reg + DSP_SIZE_OFFSET);
628 /*EMGD_WRITE32(stereo, MMIO(display) + plane_reg + DSP_STEREO_OFFSET);
629 - This register is Reserved ON plba */
630 EMGD_WRITE32(fb_info->visible_offset,
631 MMIO(display) + plane_reg + DSP_START_OFFSET);
633 /* It seems we need push or trigger plane A/B to start to work
634 * on Poulsbo, especially for sDVO port. Let's write plane control
635 * register and start address register at last.
637 EMGD_WRITE32(plane_control, MMIO(display) + plane_reg);
638 EMGD_WRITE32(EMGD_READ32(MMIO(display) + start_addr_reg),
639 MMIO(display) + start_addr_reg);
641 igd_wait_vblank_plb((igd_display_h)display);
648 * This function programs the Timing registers and clock registers and
649 * other control registers for PIPE.
656 static void program_pipe_plb(igd_display_context_t *display,
657 unsigned long status)
659 unsigned long timing_reg;
660 unsigned long pipe_conf;
661 unsigned long hactive, vactive;
662 igd_timing_info_t *pTimings;
665 igd_display_port_t *port;
670 EMGD_DEBUG("Program Pipe: %s", status?"ENABLE":"DISABLE");
671 EMGD_DEBUG("Device power state: D%ld", GET_DEVICE_POWER_STATE(display));
673 pipe_conf = device_data_plb->pipe_preserve &
674 EMGD_READ32(MMIO(display) + PIPE(display)->pipe_reg);
676 /* Reset the plane of this pipe back to NULL, it will be set on the
677 * call to program_plane, which is ok, since program_pipe occurs
678 * before program_plane */
679 PIPE(display)->plane = NULL;
681 if((status == FALSE) ||
682 (GET_DEVICE_POWER_STATE(display) == IGD_POWERSTATE_D3)) {
684 EMGD_WRITE32(pipe_conf & (~0x80000000),
685 MMIO(display) + PIPE(display)->pipe_reg);
690 pTimings = PIPE(display)->timing;
693 * If the mode is VGA and the PD says it handles all VGA modes without
694 * reprogramming then just set the mode and leave centering off.
696 if(pTimings->mode_info_flags & IGD_MODE_VESA) {
697 if (pTimings->mode_number <= VGA_MODE_NUM_MAX) {
698 /* Pipe timings and clocks are not used but it must be on anyway */
699 EMGD_WRITE32(pipe_conf | 0x80000000,
700 MMIO(display) + PIPE(display)->pipe_reg);
701 program_pipe_vga_plb(display);
705 set_256_palette(MMIO(display));
710 /* Program dot clock divisors. */
711 program_clock_plb(display, PIPE(display)->clock_reg, pTimings->dclk);
713 /* Program timing registers for the pipe */
714 timing_reg = PIPE(display)->timing_reg;
715 if (pTimings->mode_info_flags & IGD_PIXEL_DOUBLE) {
716 hactive = (unsigned long)pTimings->width*2 - 1;
718 hactive = (unsigned long)pTimings->width - 1;
721 if (pTimings->mode_info_flags & IGD_LINE_DOUBLE) {
722 if (pTimings->mode_info_flags & IGD_SCAN_INTERLACE) {
723 vactive = (unsigned long)pTimings->height - 1;
725 vactive = (unsigned long)pTimings->height*2 - 1;
728 if (pTimings->mode_info_flags & IGD_SCAN_INTERLACE) {
729 vactive = (unsigned long)pTimings->height/2 - 1;
731 vactive = (unsigned long)pTimings->height - 1;
736 * DPLL should be on at this point which is required for touching
740 /* reset the palette */
741 for (i = 0; i < 256; i++) {
742 EMGD_WRITE32(((i<<16) | (i<<8) | i),
743 MMIO(display) + PIPE(display)->palette_reg + i*4);
746 /* apply color correction */
747 port = PORT_OWNER(display);
748 for( i = 0; PD_ATTR_LIST_END != port->attributes[i].id; i++ ) {
750 if ((PD_ATTR_ID_FB_GAMMA == (port->attributes[i].id)) ||
751 (PD_ATTR_ID_FB_BRIGHTNESS == (port->attributes[i].id)) ||
752 (PD_ATTR_ID_FB_BRIGHTNESS == (port->attributes[i].id))) {
754 mode_context->dispatch->full->set_color_correct(display);
760 * NOTE: For size reasons the timng table contains unsigned short
761 * values. Don't shift them past 16. Use a temp instead.
762 * All register offsets and bit shift are verified for Napa
764 temp = ((unsigned long)pTimings->htotal << 16) | hactive;
765 EMGD_WRITE32(temp, MMIO(display) + timing_reg);
767 temp = ((unsigned long)pTimings->hblank_end << 16) |
768 (unsigned long)pTimings->hblank_start;
769 EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x04);
771 temp = ((unsigned long)pTimings->hsync_end << 16) |
772 (unsigned long)pTimings->hsync_start;
773 EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x08);
775 temp = ((unsigned long)pTimings->vtotal << 16) | vactive;
776 EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x0C);
778 temp = ((unsigned long)pTimings->vblank_end << 16) |
779 (unsigned long)pTimings->vblank_start;
780 EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x10);
782 temp = ((unsigned long)pTimings->vsync_end << 16) |
783 (unsigned long)pTimings->vsync_start;
784 EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x14);
787 * If there is a linked mode it is either the VGA or a scaled
788 * mode. If it is scaled then we need to use it as the source size.
790 if(pTimings->extn_ptr) {
791 igd_timing_info_t *scaled_timings =
792 (igd_timing_info_t *)pTimings->extn_ptr;
793 if((scaled_timings->mode_info_flags & IGD_MODE_VESA) &&
794 (scaled_timings->mode_number <= VGA_MODE_NUM_MAX)) {
795 temp = (hactive << 16) | vactive;
797 temp = (unsigned long)scaled_timings->width - 1;
798 temp = (temp << 16) |
799 (unsigned long)(scaled_timings->height - 1);
802 temp = (hactive << 16) | vactive;
804 EMGD_WRITE32(temp, MMIO(display) + timing_reg + 0x1C);
806 /* Set other registers */
809 * FIXME: max_dclk needs to be determined from core clock
810 * at init time. 915 etc has several skus with different
811 * clocks for the same device ID.
815 /* These values are derived from the Poulsbo B-Spec as
816 * the suggested values */
817 WRITE_MMIO_REG (display, FW_BLC1, device_data_plb->fw_blc1);
818 WRITE_MMIO_REG (display, FW_BLC2, device_data_plb->fw_blc2);
819 WRITE_MMIO_REG (display, FW_BLC3, device_data_plb->fw_blc3);
820 WRITE_MMIO_REG (display, FW_BLC_SELF, device_data_plb->fw_self);
821 WRITE_MMIO_REG (display, PIPEA_DISP_ARB_CTRL, device_data_plb->dsp_arb);
823 /* The SGX 2D engine can saturate the memory bus and starve
824 * the display engine causing visible screen tearing.
825 * This reduces the priority of the SGX vs. display engine
827 temp = READ_MMIO_REG (display, G_DEBUG);
828 WRITE_MMIO_REG (display, G_DEBUG, (temp | (1 << 11)));
830 pipe_conf |= PIPE_ENABLE;
831 WRITE_MMIO_REG(display, PIPE(display)->pipe_reg, pipe_conf);
834 * Set the VGA address range to 0xa0000 so that a normal (not VGA)
835 * mode can be accessed through 0xa0000 in a 16bit world.
837 WRITE_AR(MMIO(display), 0x10, 0xb);
838 WRITE_VGA(MMIO(display), GR_PORT, 0x06, 0x5);
839 WRITE_VGA(MMIO(display), GR_PORT, 0x10, 0x1);
841 if(pTimings->extn_ptr) {
842 /* This means either internal scaling (LVDS) or centered VGA */
843 pTimings = pTimings->extn_ptr;
844 if(pTimings->extn_ptr) {
845 /* This is both the scaled and centered VGA */
846 pTimings = pTimings->extn_ptr;
848 if(pTimings->mode_info_flags & IGD_MODE_VESA) {
849 if (pTimings->mode_number <= VGA_MODE_NUM_MAX) {
850 program_pipe_vga_plb(display);
853 set_256_palette(MMIO(display));
869 static void reset_plane_pipe_ports_plb(igd_context_t *context)
872 igd_display_pipe_t *pipe;
873 igd_display_port_t *port,*tv_port=NULL;
877 inter_module_dispatch_t *md;
882 * Disable all plane, pipe and port registers because the
883 * bios may have been using a different set. Only unset the
886 mmio = EMGD_MMIO(context->device_context.virt_mmadr);
887 md = &context->mod_dispatch;
889 disable_vga_plb(EMGD_MMIO(mmio));
893 while((port = md->dsp_get_next_port(context, port, 0)) != NULL) {
894 /* if the port is TV, then don't set the power to S3 as this causes
895 * blank screen on analog port after killx or cosole mode,
896 * probably because the external clock needs to be on till the pipes and
899 if (port->pd_driver) {
900 #ifndef CONFIG_FASTBOOT
901 if(port->pd_type == PD_DISPLAY_TVOUT) {
904 port->pd_driver->set_power(port->pd_context, IGD_POWERSTATE_D3);
909 /* Disable WRITE protection on PIPE B for parts with Int-LVDS*/
910 /* This should never happen as the panel power was set to D3 above */
911 if (port->port_reg == LVDSCNTR) {
912 if(EMGD_READ32(EMGD_MMIO(mmio) + LVDS_PNL_PWR_CTL) & 0x1) {
913 EMGD_WRITE32(0xABCD0000, EMGD_MMIO(mmio) + LVDS_PNL_PWR_CTL);
917 if((EMGD_READ32(EMGD_MMIO(mmio)+LVDS_PNL_PWR_STS)&BIT(31))==0) {
924 temp = EMGD_READ32(EMGD_MMIO(mmio) + port->port_reg);
925 EMGD_WRITE32((temp & ~BIT31), EMGD_MMIO(mmio) + port->port_reg);
928 /* disable plane C */
929 temp = EMGD_READ32(EMGD_MMIO(mmio) + DSPCCNTR);
931 EMGD_WRITE32(0x0, EMGD_MMIO(mmio) + DSPCCNTR);
932 EMGD_WRITE32(0x0, EMGD_MMIO(mmio) + DSPCCNTR + DSP_START_OFFSET);
936 while ((plane = md->dsp_get_next_plane(context, plane, 1)) != NULL) {
937 /* Only display display planes.
938 * Leave cursor, VGA, overlay, sprite planes alone since they will
939 * need a different disable bit/sequence.
941 temp = EMGD_READ32(EMGD_MMIO(mmio) + plane->plane_reg);
942 if ((plane->plane_features & IGD_PLANE_DISPLAY)) {
943 if ( temp & BIT31 ) {
944 if(plane->plane_reg == DSPACNTR) {
945 EMGD_WRITE32((temp & device_data_plb->plane_a_preserve),
946 EMGD_MMIO(mmio) + plane->plane_reg);
948 else { /* if it's plane b or plane c */
949 EMGD_WRITE32((temp & device_data_plb->plane_b_c_preserve),
950 EMGD_MMIO(mmio) + plane->plane_reg);
952 EMGD_WRITE32(0, EMGD_MMIO(mmio) + plane->plane_reg+4);
954 } else if ((plane->plane_features & IGD_PLANE_CURSOR)) {
955 EMGD_WRITE32((temp & 0xffffffe8),
956 EMGD_MMIO(mmio) + plane->plane_reg);
957 EMGD_WRITE32(0, EMGD_MMIO(mmio) + plane->plane_reg+4);
963 while ((pipe = md->dsp_get_next_pipe(context, pipe, 0))) {
964 wait_for_vblank_plb(EMGD_MMIO(mmio), pipe->pipe_reg);
965 temp = EMGD_READ32(EMGD_MMIO(mmio) + pipe->pipe_reg);
966 if ( temp & BIT31 ) {
967 EMGD_WRITE32((temp & device_data_plb->pipe_preserve),
968 EMGD_MMIO(mmio) + pipe->pipe_reg);
971 /* pipes and DPLLs are off, now set the power for TV */
972 if(tv_port && tv_port->pd_driver) {
973 tv_port->pd_driver->set_power(tv_port->pd_context, IGD_POWERSTATE_D3);
977 } /* end reset_plane_pipe_ports */
985 * @return 0 on success
986 * @return -IGD_ERROR_INVAL on failure
988 static int program_port_plb(igd_display_context_t *display,
989 unsigned short port_number,
990 unsigned long status)
992 unsigned long pipe_number;
993 unsigned long port_control;
994 unsigned long port_control_analog = 0;
995 unsigned long mult_port_control;
996 unsigned long pd_powerstate = 0;
997 unsigned long upscale = 0;
999 pd_timing_t local_timing;
1000 unsigned long port_type;
1003 /* get the pipe number */
1004 pipe_number = PIPE(display)->pipe_num;
1006 /* get the timings */
1007 timing = PIPE(display)->timing;
1009 /* keep the port type as local as we access it frequently */
1010 port_type = PORT(display, port_number)->port_type;
1012 /* Reading the preservation bits */
1013 port_control = PORT(display, port_number)->preserve &
1014 READ_MMIO_REG(display, PORT(display, port_number)->port_reg);
1016 /* Reading the preservation bits for SDVO Gang Mode */
1017 mult_port_control = PORT(display, port_number)->mult_preserve &
1018 READ_MMIO_REG(display, PORT(display, port_number)->port_reg);
1020 /* If status is false, quickly disable the display */
1021 if(status == FALSE) {
1022 ret = PORT(display, port_number)->pd_driver->set_power(
1023 PORT(display, port_number)->pd_context, PD_POWER_MODE_D3);
1026 EMGD_ERROR_EXIT("PD set_power() returned: 0x%x", ret);
1027 return -IGD_ERROR_INVAL;
1030 if(port_type == IGD_PORT_DIGITAL) {
1031 WRITE_MMIO_REG(display, PORT(display, port_number)->port_reg,
1034 if(PORT(display, port_number)->mult_port) {
1035 /* either gang mode or RGBA */
1036 WRITE_MMIO_REG(display,
1037 PORT(display, port_number)->mult_port->port_reg,
1040 } else if (port_type == IGD_PORT_ANALOG) {
1041 port_control |= (BIT11 | BIT10); /* put in D3 state */
1042 WRITE_MMIO_REG(display, PORT(display, port_number)->port_reg,
1050 EMGD_DEBUG("status isn't false, Check port enabled");
1052 if(! (PORT(display, port_number)->pt_info->flags & IGD_DISPLAY_ENABLE)) {
1057 * Is this is the magic mode then turn on VGA syncs
1059 EMGD_DEBUG("Check vga_sync");
1060 if(PORT(display, port_number)->vga_sync == 1) {
1062 * Is this is the magic mode then turn on VGA syncs
1064 EMGD_DEBUG("VGA sync true, is width x height 720 x 400?");
1065 if((timing->width == 720) && (timing->height == 400)) {
1066 EMGD_DEBUG("Modify port control and multi_port_control");
1067 port_control |= (1L<<15);
1068 mult_port_control |= (1L<<15);
1072 EMGD_DEBUG("Check analog port");
1073 if(port_type == IGD_PORT_ANALOG) {
1074 port_control |= (0x80000000 | (pipe_number<<30));
1075 if(timing->mode_info_flags & IGD_VSYNC_HIGH) {
1076 port_control |= (1L<<4);
1078 if(timing->mode_info_flags & IGD_HSYNC_HIGH) {
1079 port_control |= (1L<<3);
1081 /* To differentiate between analog and other ports */
1082 port_control_analog = port_control;
1085 EMGD_DEBUG("Get power state");
1086 EMGD_DEBUG("power state = %ld ", GET_DISPLAY_POWER_STATE(display, port_number));
1087 switch(GET_DISPLAY_POWER_STATE(display, port_number)) {
1088 case IGD_POWERSTATE_D0:
1089 EMGD_DEBUG("Power State is D0");
1090 pi_pd_find_attr_and_value(PORT(display, port_number),
1091 PD_ATTR_ID_PANEL_FIT,
1092 0, /*no PD_FLAG for UPSCALING */
1093 NULL, /* dont need the attr ptr*/
1095 if(port_type == IGD_PORT_DIGITAL) {
1096 /* Reach the end timing if upscaling is enabled */
1097 if (timing->extn_ptr && upscale) {
1098 timing = (pd_timing_t *)timing->extn_ptr;
1101 local_timing = *timing;
1103 /* For timings smaller than width 360 and height 200,
1104 * double the size. This is because the active area of the mode
1105 * is double the size of the resolution for these modes
1106 * - Very tricky huh */
1107 if (local_timing.width <= 360) {
1108 local_timing.width <<= 1;
1110 if (local_timing.height <= 200) {
1111 local_timing.height <<= 1;
1115 ret = PORT(display, port_number)->pd_driver->set_mode(
1116 PORT(display, port_number)->pd_context, &local_timing, 0);
1118 EMGD_ERROR_EXIT("PD set_mode returned: 0x%x", ret);
1119 return -IGD_ERROR_INVAL;
1122 /* in Plba B-Speecs, there are no bits, *
1123 * for the polarity of the H-sync/V-sync */
1125 /* in Plba B-Speecs, there are no bits, *
1126 * for data ordering/format for DVO data */
1127 /* Gang-Mode and RGBA models are "exclusive-or" */
1128 if((PORT(display, port_number)->pd_driver->flags) &
1129 PD_FLAG_GANG_MODE) {
1130 mult_port_control |= (1L<<16);
1131 } else if(PORT(display, port_number)->pd_type == PD_DISPLAY_RGBA) {
1132 mult_port_control |= (1L<<2);
1135 timing = PIPE(display)->timing;
1137 if(timing->dclk > 100000) {
1138 /* 100MPs < pixel rate < 200MPs */
1139 /* SDVO clock rate multiplier = 1x */
1141 port_control &= ~BIT23;
1142 mult_port_control |= ~BIT23;
1143 redundant code since BIT23 is
1144 already 0 at this point
1146 } else if(timing->dclk > 50000) {
1147 /* 50MPs < pixel rate < 100MPs */
1148 /* SDVO clock rate multiplier = 2x */
1149 port_control |= (1L<<23);
1150 mult_port_control |= (1L<<23);
1152 /* 25MPs < pixel rate < 50MPs */
1153 /* SDVO clock rate multiplier = 4x */
1154 port_control |= (3L<<23);
1155 mult_port_control |= (3L<<23);
1159 * BIT7 = enable the border
1160 * Do we need to disable the SDVO border for native
1161 * VGA timings(i.e., use DE)?
1162 * BIT22->BIT19 = setup the clock phase-9
1163 * BIT29 = enable the stall
1164 * Only set stall on DVO-B for gang mode
1165 * BIT30 = pipe number
1166 * BIT31 = port enable
1168 port_control |= ( ( pipe_number<<30 ) | (BIT31) | ((0x9l) << 19) |
1170 mult_port_control |= ( (BIT31) | ((0x9l) << 19) | (BIT7) );
1172 WRITE_MMIO_REG(display, PORT(display, port_number)->port_reg,
1175 if(PORT(display, port_number)->mult_port) { /* gang mode or rgba*/
1176 WRITE_MMIO_REG(display,
1177 PORT(display, port_number)->mult_port->port_reg,
1181 } else if(port_type == IGD_PORT_LVDS) {
1183 * There is a special case for LVDS scaling. If the timing is
1184 * the native one and the extension points to another non-vga
1185 * mode then send the extension pointer.
1187 /* Reach the end timing to get user requested mode */
1188 if(timing->extn_ptr) {
1189 timing = (pd_timing_t *)timing->extn_ptr;
1192 /* set mode will take care of port control */
1193 ret = PORT(display, port_number)->pd_driver->set_mode(
1194 PORT(display, port_number)->pd_context, (pd_timing_t *)timing,
1195 1<<PIPE(display)->pipe_num);
1197 EMGD_ERROR_EXIT("PD set_mode returned: 0x%x",ret);
1201 case IGD_POWERSTATE_D1:
1202 port_control_analog &= ~0x80000000;
1203 port_control_analog |= 0x00000800 &
1204 ~(PORT(display, port_number)->preserve);
1205 pd_powerstate =PD_POWER_MODE_D1;
1207 case IGD_POWERSTATE_D2:
1208 port_control_analog &= ~0x80000000;
1209 port_control_analog |= 0x00000400 &
1210 ~(PORT(display, port_number)->preserve);
1211 pd_powerstate = PD_POWER_MODE_D2;
1213 case IGD_POWERSTATE_D3:
1214 port_control_analog &= ~0x80000000;
1215 port_control_analog |= 0x00003c00 &
1216 ~(PORT(display, port_number)->preserve);
1217 pd_powerstate = PD_POWER_MODE_D3;
1220 EMGD_ERROR_EXIT("Invalid power state: 0x%lx",
1221 GET_DISPLAY_POWER_STATE(display, port_number));
1222 return -IGD_ERROR_INVAL;
1225 ret = PORT(display, port_number)->pd_driver->set_power(
1226 PORT(display, port_number)->pd_context, pd_powerstate);
1228 EMGD_ERROR_EXIT("PD set_power returned: 0x%x", ret);
1229 return -IGD_ERROR_INVAL;
1232 if(port_type == IGD_PORT_DIGITAL) {
1233 EMGD_DEBUG("Port_control = 0x%lx", port_control);
1235 WRITE_MMIO_REG(display, PORT(display, port_number)->port_reg,
1237 if(PORT(display, port_number)->mult_port) { /* gang mode or rgba*/
1238 WRITE_MMIO_REG(display,
1239 PORT(display, port_number)->mult_port->port_reg,
1249 * Status is currently not used
1252 * @param port_number
1255 * @return 0 on success
1256 * @return 1 on failure
1258 static int post_program_port_plb(igd_display_context_t *display,
1259 unsigned short port_number,
1260 unsigned long status)
1263 igd_display_port_t *port;
1264 igd_timing_info_t *timings;
1265 unsigned long portreg;
1269 port = PORT(display, port_number);
1270 timings = PIPE(display)->timing;
1273 * Writing the sDVO control register here works around a problem
1274 * where the sDVO port is not turning on when using a CH7308
1275 * card in a 915 GM based system and the port order is 5200.
1277 * In addition, post_set_mode() below, will report that the
1278 * "inputs are not trained", however, this does not seem to
1279 * have any negative effects.
1281 portreg = READ_MMIO_REG(display, port->port_reg);
1282 WRITE_MMIO_REG(display, port->port_reg, (portreg & ~BIT31));
1283 WRITE_MMIO_REG(display, port->port_reg, portreg);
1285 /* Reenable/Redisable other port */
1286 if (port->port_reg == 0x61140) {
1287 WRITE_MMIO_REG(display, 0x61160, READ_MMIO_REG(display,
1290 WRITE_MMIO_REG(display, 0x61140,
1291 READ_MMIO_REG(display, 0x61140));
1295 * Added for Lakeport A0
1296 * Port clock multiplier bits 4-7, needs to be rewritten
1298 WRITE_MMIO_REG(display, PIPE(display)->clock_reg->dpll_control,
1299 READ_MMIO_REG(display, PIPE(display)->clock_reg->dpll_control));
1301 /* We must wait for 150 us for the dpll clock to warm up */
1305 /* call post_set_mode() if exists */
1306 if (port->pd_driver->post_set_mode) {
1307 ret = port->pd_driver->post_set_mode(port->pd_context, timings,
1308 1<<PIPE(display)->pipe_num);
1310 EMGD_ERROR("PD post_set_mode returned: 0x%x", ret);
1318 int program_cdvo_plb(void)
1329 static unsigned long get_gpio_sets_plb(unsigned long **gpio)
1332 return sizeof(gpio_plb)/sizeof(unsigned long);
1340 * @return void - To small to trace
1342 static void filter_modes_plb(igd_context_t *context, igd_display_port_t *port,
1343 pd_timing_t *in_list)
1349 #ifndef CONFIG_MICRO
1350 int check_display_plb(igd_display_context_t *display,
1351 unsigned short port_number, unsigned long status){
1352 /* For poulsbo display should be working fine */
1357 mode_dispatch_t mode_dispatch_plb = {
1358 igd_set_palette_entry_plb,
1359 igd_get_palette_entry_plb,
1360 igd_wait_vblank_plb,
1364 post_program_port_plb,
1367 reset_plane_pipe_ports_plb,
1370 OPT_MICRO_VALUE(&check_display_plb, NULL),
1375 OPT_MICRO_VALUE(&mode_full_dispatch_plb, NULL),