Ticket #1293: ek_radeon_dual_dvi_patch1.diff
File ek_radeon_dual_dvi_patch1.diff, 35.4 KB (added by , 17 years ago) |
---|
-
src/add-ons/kernel/drivers/graphics/radeon/init.c
15 15 */ 16 16 17 17 #include "dac_regs.h" 18 #include "tv_out_regs.h" 18 19 #include "fp_regs.h" 19 20 #include "mmio.h" 20 21 #include "radeon_driver.h" … … 266 267 // so we let the first accelerant take care of it 267 268 si->theatre_channel = -1; 268 269 269 /* si->ports[0].disp_type = di->disp_type[0];270 si->ports[1].disp_type = di->disp_type[1];*/271 270 si->crtc[0].crtc_idx = 0; 272 271 si->crtc[0].flatpanel_port = 0; 273 272 si->crtc[1].crtc_idx = 1; 274 273 si->crtc[1].flatpanel_port = 1; 275 274 si->num_crtc = di->num_crtc; 276 275 277 si->flatpanels[0] = di->fp_info; 276 if (di->is_mobility) 277 si->flatpanels[0] = di->fp_info; 278 278 279 si->pll = di->pll; 279 /* si->ram = di->ram; 280 strcpy( si->ram_type, di->ram_type );*/ 281 //si->local_mem_size = di->local_mem_size; 282 280 283 281 // create virtual card info; don't allow access by apps - 284 282 // they'll clone it 285 283 sprintf( buffer, "%04X_%04X_%02X%02X%02X virtual card 0", … … 306 304 di->vc->assigned_crtc[0] = true; 307 305 di->vc->assigned_crtc[1] = si->num_crtc > 1; 308 306 di->vc->controlled_displays = 309 dd_tv_crt | dd_crt | dd_lvds | dd_dvi | dd_ ctv | dd_stv;307 dd_tv_crt | dd_crt | dd_lvds | dd_dvi | dd_dvi_ext | dd_ctv | dd_stv; 310 308 311 309 di->vc->fb_mem_handle = 0; 312 310 di->vc->cursor.mem_handle = 0; … … 324 322 if( di->asic == rt_rv100 && di->is_mobility) 325 323 di->dac2_cntl = INREG( di->regs, RADEON_DAC_CNTL2 ); 326 324 325 memcpy(&si->tmds_pll, &di->tmds_pll, sizeof(di->tmds_pll)); 326 si->tmds_pll_cntl = INREG( di->regs, RADEON_TMDS_PLL_CNTL); 327 si->tmds_transmitter_cntl = INREG( di->regs, RADEON_TMDS_TRANSMITTER_CNTL); 328 327 329 // print these out to capture bios status... 328 if ( di->is_mobility ) { 329 SHOW_INFO0( 4, "Copy of Laptop Display Regs for Reference:"); 330 SHOW_INFO( 4, "LVDS CNTL = %8lx", INREG( di->regs, RADEON_LVDS_GEN_CNTL )); 331 SHOW_INFO( 4, "FP1 CNTL = %8lx", INREG( di->regs, RADEON_FP_GEN_CNTL )); 332 SHOW_INFO( 4, "FP2 CNTL = %8lx", INREG( di->regs, RADEON_FP2_GEN_CNTL )); 333 } 330 // if ( di->is_mobility ) { 331 SHOW_INFO0( 2, "Copy of Laptop Display Regs for Reference:"); 332 SHOW_INFO( 2, "LVDS GEN = %8lx", INREG( di->regs, RADEON_LVDS_GEN_CNTL )); 333 SHOW_INFO( 2, "LVDS PLL = %8lx", INREG( di->regs, RADEON_LVDS_PLL_CNTL )); 334 SHOW_INFO( 2, "TMDS PLL = %8lx", INREG( di->regs, RADEON_TMDS_PLL_CNTL )); 335 SHOW_INFO( 2, "TMDS TRANS = %8lx", INREG( di->regs, RADEON_TMDS_TRANSMITTER_CNTL )); 336 SHOW_INFO( 2, "FP1 GEN = %8lx", INREG( di->regs, RADEON_FP_GEN_CNTL )); 337 SHOW_INFO( 2, "FP2 GEN = %8lx", INREG( di->regs, RADEON_FP2_GEN_CNTL )); 338 SHOW_INFO( 2, "TV DAC = %8lx", INREG( di->regs, RADEON_TV_DAC_CNTL )); //not setup right when ext dvi 339 // } 334 340 335 341 result = Radeon_InitPCIGART( di ); 336 342 if( result < 0 ) -
src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h
116 116 disp_entity routing; 117 117 118 118 general_pll_info pll; 119 tmds_pll_info tmds_pll[4]; 119 120 ram_info ram; 120 121 char ram_type[32]; // human-readable name of ram type 121 122 uint32 local_mem_size; -
src/add-ons/kernel/drivers/graphics/radeon/bios.c
31 31 32 32 #define RADEON_BIOS8(v) (di->rom.rom_ptr[v]) 33 33 #define RADEON_BIOS16(v) ((di->rom.rom_ptr[v]) | \ 34 34 (di->rom.rom_ptr[(v) + 1] << 8)) 35 35 #define RADEON_BIOS32(v) ((di->rom.rom_ptr[v]) | \ 36 (di->rom.rom_ptr[(v) + 1] << 8)\37 (di->rom.rom_ptr[(v) + 2] << 16)\38 36 (di->rom.rom_ptr[(v) + 1] << 8) | \ 37 (di->rom.rom_ptr[(v) + 2] << 16) | \ 38 (di->rom.rom_ptr[(v) + 3] << 24)) 39 39 40 40 static const char ati_rom_sig[] = "761295520"; 41 41 42 static const tmds_pll_info default_tmds_pll[14][4] = 43 { 44 {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // r100 45 {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // rv100 46 {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, // rs100 47 {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // rv200 48 {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // rs200 49 {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // r200 50 {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, // rv250 51 {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, // rs300 52 {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, // rv280 53 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, // r300 54 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, // r350 55 {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, // rv350 56 {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, // rv380 57 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, // r420 58 }; 59 60 42 61 // find address of ROM; 43 62 // this code is really nasty as maintaining the radeon signatures 44 63 // is almost impossible (the signatures provided by ATI are always out-dated); … … 691 710 >> RADEON_CRTC_V_SYNC_WID_SHIFT); 692 711 } 693 712 713 //snaffled from X.org hope it works... 714 static void Radeon_GetTMDSInfoFromBios( device_info *di ) 715 { 716 uint32 tmp, maxfreq; 717 uint32 found = FALSE; 718 int i, n; 719 uint16 bios_header; 694 720 721 bios_header = RADEON_BIOS16( 0x48 ); 722 723 for (i = 0; i < 4; i++) { 724 di->tmds_pll[i].value = 0; 725 di->tmds_pll[i].freq = 0; 726 } 727 728 if (di->is_atombios) 729 { 730 int master_data_start; 731 master_data_start = RADEON_BIOS16( bios_header + 32 ); 732 733 if((tmp = RADEON_BIOS16 (master_data_start + 18))) { 734 735 maxfreq = RADEON_BIOS16(tmp + 4); 736 737 for (i = 0; i < 4; i++) { 738 di->tmds_pll[i].freq = RADEON_BIOS16(tmp + i * 6 + 6); 739 // This assumes each field in TMDS_PLL has 6 bit as in R300/R420 740 di->tmds_pll[i].value = ((RADEON_BIOS8(tmp + i * 6 + 8) & 0x3f) | 741 ((RADEON_BIOS8(tmp + i * 6 + 10) & 0x3f) << 6) | 742 ((RADEON_BIOS8(tmp + i * 6 + 9) & 0xf) << 12) | 743 ((RADEON_BIOS8(tmp + i * 6 + 11) & 0xf) << 16)); 744 SHOW_ERROR( 2, "TMDS PLL from BIOS: %ld %lx", 745 di->tmds_pll[i].freq, di->tmds_pll[i].value); 746 747 if (maxfreq == di->tmds_pll[i].freq) { 748 di->tmds_pll[i].freq = 0xffffffff; 749 break; 750 } 751 } 752 found = TRUE; 753 } 754 } else { 755 756 tmp = RADEON_BIOS16(bios_header + 0x34); 757 if (tmp) { 758 SHOW_ERROR( 2, "DFP table revision: %d", RADEON_BIOS8(tmp)); 759 if (RADEON_BIOS8(tmp) == 3) { 760 n = RADEON_BIOS8(tmp + 5) + 1; 761 if (n > 4) 762 n = 4; 763 for (i = 0; i < n; i++) { 764 di->tmds_pll[i].value = RADEON_BIOS32(tmp + i * 10 + 0x08); 765 di->tmds_pll[i].freq = RADEON_BIOS16(tmp + i * 10 + 0x10); 766 } 767 found = TRUE; 768 } else if (RADEON_BIOS8(tmp) == 4) { 769 int stride = 0; 770 n = RADEON_BIOS8(tmp + 5) + 1; 771 if (n > 4) 772 n = 4; 773 for (i = 0; i < n; i++) { 774 di->tmds_pll[i].value = RADEON_BIOS32(tmp + stride + 0x08); 775 di->tmds_pll[i].freq = RADEON_BIOS16(tmp + stride + 0x10); 776 if (i == 0) 777 stride += 10; 778 else 779 stride += 6; 780 } 781 found = TRUE; 782 } 783 784 // revision 4 has some problem as it appears in RV280, 785 // comment it off for now, use default instead 786 /* 787 else if (RADEON_BIOS8(tmp) == 4) { 788 int stride = 0; 789 n = RADEON_BIOS8(tmp + 5) + 1; 790 if (n > 4) n = 4; 791 for (i = 0; i < n; i++) { 792 di->tmds_pll[i].value = RADEON_BIOS32(tmp + stride + 0x08); 793 di->tmds_pll[i].freq = RADEON_BIOS16(tmp + stride + 0x10); 794 if (i == 0) 795 stride += 10; 796 else 797 stride += 6; 798 } 799 found = TRUE; 800 } 801 */ 802 803 } 804 } 805 806 if (found == FALSE) { 807 for (i = 0; i < 4; i++) { 808 di->tmds_pll[i].value = default_tmds_pll[di->asic][i].value; 809 di->tmds_pll[i].freq = default_tmds_pll[di->asic][i].freq; 810 SHOW_ERROR( 2, "TMDS PLL from DEFAULTS: %ld %lx", 811 di->tmds_pll[i].freq, di->tmds_pll[i].value); 812 } 813 } 814 } 815 695 816 /* 696 817 // get everything in terms of monitors connected to the card 697 818 static void Radeon_GetBIOSMon( device_info *di ) … … 964 1085 di->routing.port_info[0].dac_type = dac_unknown; 965 1086 di->routing.port_info[0].tmds_type = tmds_unknown; 966 1087 di->routing.port_info[0].connector_type = connector_none; 1088 1089 di->routing.port_info[1].mon_type = mt_unknown; 1090 di->routing.port_info[1].ddc_type = ddc_none_detected; 1091 di->routing.port_info[1].dac_type = dac_unknown; 1092 di->routing.port_info[1].tmds_type = tmds_unknown; 1093 di->routing.port_info[1].connector_type = connector_none; 967 1094 968 1095 if ( !Radeon_GetConnectorInfoFromBIOS( di ) ) 969 1096 { … … 981 1108 982 1109 } 983 1110 Radeon_GetFPData( di ); 1111 Radeon_GetTMDSInfoFromBios( di ); 984 1112 Radeon_DetectRAM( di ); 985 1113 986 1114 Radeon_UnmapDevice( di ); -
src/add-ons/accelerants/radeon/radeon_accelerant.h
32 32 33 33 #define DEBUG_MSG_PREFIX "Radeon - " 34 34 35 #define DEBUG_MAX_LEVEL_FLOW 235 #define DEBUG_MAX_LEVEL_FLOW 3 36 36 37 37 #include "debug_ext.h" 38 38 -
src/add-ons/accelerants/radeon/ProposeDisplayMode.c
148 148 int eff_virtual_width; 149 149 fp_info *flatpanel = &si->flatpanels[crtc->flatpanel_port]; 150 150 151 SHOW_FLOW( 4, "CRTC %d, DVI %d", (crtc == &si->crtc[0]) ? 0 : 1, crtc->flatpanel_port ); 152 SHOW_FLOW( 4, "X %d, virtX %d", target->timing.h_display, target->virtual_width); 153 SHOW_FLOW( 4, "fpRes %dx%d", flatpanel->panel_xres, flatpanel->panel_yres); 154 151 155 // save refresh rate - we want to leave this (artifical) value untouched 152 156 // don't use floating point, we are in kernel mode 153 157 target_refresh = … … 163 167 // for flat panels, check maximum resolution; 164 168 // all the other tricks (like fixed resolution and resulting scaling) 165 169 // are done automagically by set_display_mode 166 if( (crtc->chosen_displays & (dd_lvds | dd_dvi | dd_dvi_ext)) != 0 ) {170 if( (crtc->chosen_displays & (dd_lvds | dd_dvi)) != 0 ) { 167 171 if( target->timing.h_display > flatpanel->panel_xres ) 168 172 target->timing.h_display = flatpanel->panel_xres; 169 173 … … 171 175 target->timing.v_display = flatpanel->panel_yres; 172 176 } 173 177 178 // for secondary flat panels there is no RMX unit for 179 // scaling up lower resolutions. Until we can do centered timings 180 // we need to disable the screen unless it is the native resolution. 181 // if the DVI input has a scaler we would need to know about it somehow... 182 if( (crtc->chosen_displays & dd_dvi_ext) != 0 ) { 183 SHOW_FLOW0( 4, "external (secondary) DVI cannot support non-native resolutions" ); 184 if( ( target->timing.h_display != flatpanel->panel_xres ) || 185 ( target->timing.v_display != flatpanel->panel_yres ) ) 186 return B_ERROR; 187 } 188 174 189 /* 175 190 // the TV-Out encoder can "only" handle up to 1024x768 176 191 if( (head->chosen_displays & (dd_ctv | dd_stv)) != 0 ) { … … 325 340 if( target->timing.pixel_clock / 10 > pll->max_pll_freq || 326 341 target->timing.pixel_clock / 10 * 12 < pll->min_pll_freq ) 327 342 { 328 SHOW_ERROR( 2, "pixel_clock (%ld) out of range (%d, %d)", target->timing.pixel_clock,343 SHOW_ERROR( 4, "pixel_clock (%ld) out of range (%d, %d)", target->timing.pixel_clock, 329 344 pll->max_pll_freq * 10, pll->min_pll_freq / 12 ); 330 345 return B_ERROR; 331 346 } … … 371 386 372 387 // make sure we haven't shrunk virtual height too much 373 388 if (target->virtual_height < target->timing.v_display) { 374 SHOW_ERROR( 2, "not enough memory for this mode (could show only %d of %d lines)",389 SHOW_ERROR( 4, "not enough memory for this mode (could show only %d of %d lines)", 375 390 target->virtual_height, target->timing.v_display ); 376 391 return B_ERROR; 377 392 } … … 516 531 { 517 532 shared_info *si = ai->si; 518 533 519 fp_info *fp_info = &si->flatpanels[0]; 534 fp_info *fp_info = &si->flatpanels[0]; //todo fix the hardcoding what about ext dvi? 520 535 521 if( (ai->vc->connected_displays & (dd_dvi | dd_ lvds)) != 0 ) {536 if( (ai->vc->connected_displays & (dd_dvi | dd_dvi_ext | dd_lvds)) != 0 ) { 522 537 display_mode mode; 523 538 SHOW_FLOW0( 2, "" ); 524 539 mode.virtual_width = mode.timing.h_display = fp_info->panel_xres; 525 540 mode.virtual_height = mode.timing.v_display = fp_info->panel_yres; 526 541 … … 631 646 Radeon_DetectMultiMode( vc, target ); 632 647 Radeon_VerifyMultiMode( vc, si, target ); 633 648 634 SHOW_FLOW0( 3, "wished:" );635 SHOW_FLOW( 3, "H: %4d %4d %4d %4d (v=%4d)",649 SHOW_FLOW0( 2, "wished:" ); 650 SHOW_FLOW( 2, "H: %4d %4d %4d %4d (v=%4d)", 636 651 target->timing.h_display, target->timing.h_sync_start, 637 652 target->timing.h_sync_end, target->timing.h_total, target->virtual_width ); 638 SHOW_FLOW( 3, "V: %4d %4d %4d %4d (h=%4d)",653 SHOW_FLOW( 2, "V: %4d %4d %4d %4d (h=%4d)", 639 654 target->timing.v_display, target->timing.v_sync_start, 640 655 target->timing.v_sync_end, target->timing.v_total, target->virtual_height ); 641 SHOW_FLOW( 3, "clk: %ld", target->timing.pixel_clock );656 SHOW_FLOW( 2, "clk: %ld", target->timing.pixel_clock ); 642 657 643 658 // we must assure that each ProposeMode call doesn't tweak the mode in 644 659 // a way that it cannot be handled by the other port anymore … … 659 674 result2 = B_OK; 660 675 } 661 676 662 SHOW_INFO0( 4, "got:" );663 SHOW_INFO( 4, "H: %4d %4d %4d %4d (v=%4d)",677 SHOW_INFO0( 2, "got:" ); 678 SHOW_INFO( 2, "H: %4d %4d %4d %4d (v=%4d)", 664 679 target->timing.h_display, target->timing.h_sync_start, 665 680 target->timing.h_sync_end, target->timing.h_total, target->virtual_width ); 666 SHOW_INFO( 4, "V: %4d %4d %4d %4d (h=%4d)",681 SHOW_INFO( 2, "V: %4d %4d %4d %4d (h=%4d)", 667 682 target->timing.v_display, target->timing.v_sync_start, 668 683 target->timing.v_sync_end, target->timing.v_total, target->virtual_height ); 669 SHOW_INFO( 4, "clk: %ld", target->timing.pixel_clock );684 SHOW_INFO( 2, "clk: %ld", target->timing.pixel_clock ); 670 685 671 686 Radeon_HideMultiMode( vc, target ); 672 687 -
src/add-ons/accelerants/radeon/monitor_detection.c
269 269 RADEON_DAC_FORCE_DATA_SEL_RGB | 270 270 (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT )); 271 271 272 272 old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 ); 273 273 274 274 // enable CRT mode of TV-DAC and enable comparator 275 275 tmp = old_dac_cntl2 | RADEON_DAC2_CLK_SEL_CRT | RADEON_DAC2_CMP_EN; 276 276 277 277 OUTREG( regs, RADEON_DAC_CNTL2, tmp ); 278 278 279 279 snooze( 10000 ); 280 280 281 281 // check connection of blue data signal to see whether there is a CRT 282 282 found = (INREG( regs, RADEON_DAC_CNTL2 ) & RADEON_DAC2_CMP_OUT_B) != 0; 283 283 284 284 // clean up the mess 285 285 OUTREG( regs, RADEON_DAC_CNTL2, old_dac_cntl2 ); 286 286 OUTREG( regs, RADEON_DAC_EXT_CNTL, 0 ); 287 287 OUTREG( regs, RADEON_TV_DAC_CNTL, old_tv_dac_cntl ); … … 289 289 290 290 OUTREGP( regs, RADEON_GPIOPAD_A, old_radeon_gpiopad_a, ~1 ); 291 291 292 292 return found; 293 293 } 294 294 295 295 … … 800 800 } 801 801 802 802 // read edid data of flat panel and setup its timing accordingly 803 static status_t Radeon_StoreFPEDID( accelerator_info *ai, const edid1_info *edid )803 static status_t Radeon_StoreFPEDID( accelerator_info *ai, int port, const edid1_info *edid ) 804 804 { 805 fp_info *fp = &ai->si->flatpanels[ 0];805 fp_info *fp = &ai->si->flatpanels[port]; 806 806 uint32 max_hsize, max_vsize; 807 807 808 808 //SHOW_FLOW0( 2, "EDID data read from DVI port via DDC2:" ); … … 954 954 // use DDC to detect monitors - if we can read DDC, there must be a monitor 955 955 for ( i = 0; i < 2; i++ ) 956 956 { 957 if (routes->port_info[i].mon_type != mt_unknown ) { 958 SHOW_FLOW0( 2, "known type, skpping detection" ); 959 continue; 960 } 957 //TODO could skip edid reading instead if we already have it, but what 958 //if monitors have been hot swapped? Also rely on edid for DVI-D detection 959 //if (routes->port_info[i].mon_type != mt_unknown ) { 960 // SHOW_FLOW0( 2, "known type, skpping detection" ); 961 // continue; 962 //} 961 963 962 964 memset( &routes->port_info[i].edid , 0, sizeof(edid1_info) ); 963 965 switch ( routes->port_info[i].ddc_type ) { … … 993 995 // both LDVS and TMDS are disable, we still need to treat it as a LVDS panel. 994 996 if ( routes->port_info[i].tmds_type == tmds_ext ){ 995 997 // store info about DVI-connected flat-panel 996 if( Radeon_StoreFPEDID( ai, &routes->port_info[i].edid ) == B_OK ) {998 if( Radeon_StoreFPEDID( ai, i, &routes->port_info[i].edid ) == B_OK ) { 997 999 SHOW_INFO0( 2, "Found Ext Laptop DVI" ); 998 1000 routes->port_info[i].mon_type = mt_dfp; 1001 ai->si->flatpanels[i].is_fp2 = true; 999 1002 displays |= dd_dvi_ext; 1000 1003 } else { 1001 1004 SHOW_ERROR0( 2, "Disabled Ext DVI - invalid EDID" ); … … 1003 1006 } else { 1004 1007 if( INREG( ai->regs, RADEON_FP_GEN_CNTL) & (1 << 7) || ( !si->is_mobility ) ) { 1005 1008 // store info about DVI-connected flat-panel 1006 if( Radeon_StoreFPEDID( ai, &routes->port_info[i].edid ) == B_OK ) {1009 if( Radeon_StoreFPEDID( ai, i, &routes->port_info[i].edid ) == B_OK ) { 1007 1010 SHOW_INFO0( 2, "Found DVI" ); 1008 1011 routes->port_info[i].mon_type = mt_dfp; 1009 1012 displays |= dd_dvi; … … 1015 1018 routes->port_info[i].mon_type = mt_lcd; 1016 1019 displays |= dd_lvds; 1017 1020 } 1021 ai->si->flatpanels[1].is_fp2 = FALSE; 1018 1022 } 1019 1023 } else { 1020 1024 // must be the analog portion of DVI … … 1049 1053 if ( si->is_mobility && (INREG( ai->regs, RADEON_FP2_GEN_CNTL) & RADEON_FP2_FPON)) { 1050 1054 SHOW_INFO0( 2, "Found Ext Laptop DVI" ); 1051 1055 routes->port_info[1].mon_type = mt_dfp; 1052 displays |= dd_dvi ;1056 displays |= dd_dvi_ext; 1053 1057 } 1054 1058 } 1055 1059 -
src/add-ons/accelerants/radeon/SetDisplayMode.c
23 23 #include "fp_regs.h" 24 24 #include "gpiopad_regs.h" 25 25 26 #include "pll_regs.h" 27 #include "tv_out_regs.h" 28 #include "config_regs.h" 29 #include "ddc_regs.h" 30 #include "pll_access.h" 31 #include "theatre_regs.h" 26 32 #include "set_mode.h" 33 #include "ddc.h" 27 34 35 #include "set_mode.h" 36 28 37 #include <string.h> 29 38 30 voidRadeon_SetMode(39 status_t Radeon_SetMode( 31 40 accelerator_info *ai, crtc_info *crtc, display_mode *mode, impactv_params *tv_params ); 32 41 33 42 // round virtual width up to next valid size … … 94 103 95 104 // set display mode of one head; 96 105 // port restrictions, like fixed-sync TFTs connected to it, are taken care of 97 voidRadeon_SetMode(106 status_t Radeon_SetMode( 98 107 accelerator_info *ai, crtc_info *crtc, display_mode *mode, impactv_params *tv_params ) 99 108 { 100 109 virtual_card *vc = ai->vc; … … 126 135 // is determined by the physical resolution; 127 136 // also, all timing is fixed 128 137 if( (disp_devices & (dd_lvds | dd_dvi | dd_dvi_ext)) != 0 ) { 138 SHOW_FLOW0( 0, "requested resolution higher than native panel" ); 129 139 if( mode->timing.h_display > fp_info->panel_xres ) 130 140 mode->timing.h_display = fp_info->panel_xres; 131 141 if( mode->timing.v_display > fp_info->panel_yres ) 132 142 mode->timing.v_display = fp_info->panel_yres; 133 143 144 if( (disp_devices & dd_dvi_ext) != 0 ) { 145 SHOW_FLOW0( 0, "requested resolution less than second native panel" ); 146 if( mode->timing.h_display < fp_info->panel_xres ) 147 mode->timing.h_display = fp_info->panel_xres; 148 if( mode->timing.v_display < fp_info->panel_yres ) 149 mode->timing.v_display = fp_info->panel_yres; 150 151 //TODO at this point we know we are going to do centered timing 152 //need to set flags to a. blank the unused memory, b.center screen 153 //for now it's in the top corner, and surrounded by garbage. 154 // although if the DVI panels are the same size and we are cloning 155 // we can switch the FP2 source to RMX, and drive both screens from 156 // the RMX unit. 157 } 134 158 mode->timing.h_total = mode->timing.h_display + fp_info->h_blank; 135 159 mode->timing.h_sync_start = mode->timing.h_display + fp_info->h_over_plus; 136 160 mode->timing.h_sync_end = mode->timing.h_sync_start + fp_info->h_sync_width; … … 254 278 Radeon_TheatreProgramTVRegisters( ai, &impactv_values ); 255 279 } 256 280 281 // spit out some debug stuff in a radeontool stylee 282 SHOW_FLOW0( 0, "" ); 283 SHOW_FLOW( 0, "RADEON_DAC_CNTL %08X ", INREG( regs, RADEON_DAC_CNTL )); 284 SHOW_FLOW( 0, "RADEON_DAC_CNTL2 %08X ", INREG( regs, RADEON_DAC_CNTL2 )); 285 SHOW_FLOW( 0, "RADEON_TV_DAC_CNTL %08X ", INREG( regs, RADEON_TV_DAC_CNTL )); 286 SHOW_FLOW( 0, "RADEON_DISP_OUTPUT_CNTL %08X ", INREG( regs, RADEON_DISP_OUTPUT_CNTL )); 287 SHOW_FLOW( 0, "RADEON_AUX_SC_CNTL %08X ", INREG( regs, RADEON_AUX_SC_CNTL )); 288 SHOW_FLOW( 0, "RADEON_CRTC_EXT_CNTL %08X ", INREG( regs, RADEON_CRTC_EXT_CNTL )); 289 SHOW_FLOW( 0, "RADEON_CRTC_GEN_CNTL %08X ", INREG( regs, RADEON_CRTC_GEN_CNTL )); 290 SHOW_FLOW( 0, "RADEON_CRTC2_GEN_CNTL %08X ", INREG( regs, RADEON_CRTC2_GEN_CNTL )); 291 SHOW_FLOW( 0, "RADEON_DISP_MISC_CNTL %08X ", INREG( regs, RADEON_DISP_MISC_CNTL )); 292 SHOW_FLOW( 0, "RADEON_FP_GEN_CNTL %08X ", INREG( regs, RADEON_FP_GEN_CNTL )); 293 SHOW_FLOW( 0, "RADEON_FP2_GEN_CNTL %08X ", INREG( regs, RADEON_FP2_GEN_CNTL )); 294 SHOW_FLOW( 0, "RADEON_LVDS_GEN_CNTL %08X ", INREG( regs, RADEON_LVDS_GEN_CNTL )); 295 SHOW_FLOW( 0, "RADEON_TMDS_PLL_CNTL %08X ", INREG( regs, RADEON_TMDS_PLL_CNTL )); 296 SHOW_FLOW( 0, "RADEON_TMDS_TRANSMITTER_CNTL %08X ", INREG( regs, RADEON_TMDS_TRANSMITTER_CNTL )); 297 SHOW_FLOW( 0, "RADEON_FP_H_SYNC_STRT_WID %08X ", INREG( regs, RADEON_FP_H_SYNC_STRT_WID )); 298 SHOW_FLOW( 0, "RADEON_FP_V_SYNC_STRT_WID %08X ", INREG( regs, RADEON_FP_V_SYNC_STRT_WID )); 299 SHOW_FLOW( 0, "RADEON_FP_H2_SYNC_STRT_WID %08X ", INREG( regs, RADEON_FP_H2_SYNC_STRT_WID )); 300 SHOW_FLOW( 0, "RADEON_FP_V2_SYNC_STRT_WID %08X ", INREG( regs, RADEON_FP_V2_SYNC_STRT_WID )); 301 // spit end 302 257 303 crtc->active_displays = disp_devices; 258 304 259 305 // programming is over, so hardware can be used again … … 263 309 // TBD: this won't work if another virtual card was using it, 264 310 // but currently, virtual cards don't work anyway... 265 311 si->active_overlay.crtc_idx = -1; 312 313 return B_OK; 266 314 } 267 315 268 316 … … 432 480 { 433 481 routing_regs routing_values; 434 482 impactv_params tv_params; 483 status_t err1 , err2; 484 err1 = err2 = B_OK; 435 485 436 486 // we first switch off all output, so the monitor(s) won't get invalid signals 437 487 if( vc->assigned_crtc[0] ) { … … 451 501 452 502 // then change the mode 453 503 if( vc->used_crtc[0] ) 454 Radeon_SetMode( ai, &si->crtc[0], &mode, &tv_params );504 err1 = Radeon_SetMode( ai, &si->crtc[0], &mode, &tv_params ); 455 505 if( vc->used_crtc[1] ) 456 Radeon_SetMode( ai, &si->crtc[1], &mode, &tv_params );506 err2 = Radeon_SetMode( ai, &si->crtc[1], &mode, &tv_params ); 457 507 508 509 SHOW_FLOW( 2, "SetModes 1=%s, 2=%s", 510 (err1 == B_OK) ? "OK" : "FAIL", (err2 == B_OK) ? "OK" : "FAIL"); 511 458 512 // setup signal routing 459 513 Radeon_ReadMonitorRoutingRegs( ai, &routing_values ); 460 514 Radeon_CalcMonitorRouting( ai, &tv_params, &routing_values ); … … 462 516 463 517 // finally, switch display(s) on 464 518 if( vc->used_crtc[0] ) 465 Radeon_SetDPMS( ai, 0, B_DPMS_ON);519 Radeon_SetDPMS( ai, 0, (err1 == B_OK) ? B_DPMS_ON : B_DPMS_SUSPEND ); 466 520 if( vc->used_crtc[1] ) 467 Radeon_SetDPMS( ai, 1, B_DPMS_ON);521 Radeon_SetDPMS( ai, 1, (err2 == B_OK) ? B_DPMS_ON : B_DPMS_SUSPEND ); 468 522 469 523 OUTREGP( ai->regs, RADEON_CRTC_EXT_CNTL, 0, ~RADEON_CRTC_DISPLAY_DIS ); 470 524 } -
src/add-ons/accelerants/radeon/monitor_routing.c
634 634 else if( ai->si->num_crtc > 1 && (crtc2_displays & ~(dd_stv | dd_ctv)) == 0 && vc->assigned_crtc[1] ) 635 635 crtc2_displays |= dd_tv_crt; 636 636 } 637 638 if( (display_devices & dd_dvi_ext) != 0 ) 639 crtc2_displays |= dd_dvi_ext; 640 641 SHOW_FLOW( 2, "CRTC1: 0x%x, CRTC2: 0x%x", crtc1_displays, crtc2_displays ); 637 642 638 SHOW_FLOW( 3, "CRTC1: 0x%x, CRTC2: 0x%x", crtc1_displays, crtc2_displays );639 640 643 *crtc1 = crtc1_displays; 641 644 *crtc2 = crtc2_displays; 642 645 } … … 651 654 shared_info *si = ai->si; 652 655 display_device_e display_devices = vc->connected_displays; 653 656 654 if (ai->si->settings.force_lcd) { 657 if (ai->si->settings.force_lcd) { 655 658 use_laptop_panel = true; 656 659 SHOW_FLOW0( 2, "LCD Forced Used by Kernel Settings"); 657 660 } -
src/add-ons/accelerants/radeon/set_mode.h
98 98 typedef struct { 99 99 uint32 fp_gen_cntl; 100 100 uint32 fp_panel_cntl; 101 uint32 lvds_gen_cntl; 101 uint32 lvds_gen_cntl; 102 uint32 tmds_pll_cntl; 103 uint32 tmds_trans_cntl; 102 104 uint32 fp_h_sync_strt_wid; 103 105 uint32 fp_v_sync_strt_wid; 104 106 uint32 fp2_gen_cntl; 105 107 106 108 uint32 fp2_h_sync_strt_wid; 107 109 uint32 fp2_v_sync_strt_wid; 108 110 109 111 // RMX registers 110 112 uint32 fp_horz_stretch; 111 113 uint32 fp_vert_stretch; 112 114 113 115 // Bios values used by Mobility Asics 114 116 uint32 bios_4_scratch; -
src/add-ons/accelerants/radeon/flat_panel.c
108 108 accelerator_info *ai, fp_regs *values ) 109 109 { 110 110 vuint8 *regs = ai->regs; 111 111 SHOW_FLOW0( 2, "" ); 112 112 OUTREG( regs, RADEON_FP_HORZ_STRETCH, values->fp_horz_stretch ); 113 113 OUTREG( regs, RADEON_FP_VERT_STRETCH, values->fp_vert_stretch ); 114 114 } … … 119 119 { 120 120 vuint8 *regs = ai->regs; 121 121 122 values->fp_gen_cntl = INREG( regs, RADEON_FP_GEN_CNTL ); 123 values->fp2_gen_cntl = INREG( regs, RADEON_FP2_GEN_CNTL ); 124 values->lvds_gen_cntl = INREG( regs, RADEON_LVDS_GEN_CNTL ); 122 values->fp_gen_cntl = INREG( regs, RADEON_FP_GEN_CNTL ); 123 values->fp2_gen_cntl = INREG( regs, RADEON_FP2_GEN_CNTL ); 124 values->lvds_gen_cntl = INREG( regs, RADEON_LVDS_GEN_CNTL ); 125 values->tmds_pll_cntl = INREG( regs, RADEON_TMDS_PLL_CNTL ); 126 values->tmds_trans_cntl = INREG( regs, RADEON_TMDS_TRANSMITTER_CNTL ); 125 127 values->fp_h_sync_strt_wid = INREG( regs, RADEON_FP_H_SYNC_STRT_WID ); 126 128 values->fp_v_sync_strt_wid = INREG( regs, RADEON_FP_V_SYNC_STRT_WID ); 127 129 values->fp2_h_sync_strt_wid = INREG( regs, RADEON_FP_H2_SYNC_STRT_WID ); … … 130 132 values->bios_5_scratch = INREG( regs, RADEON_BIOS_5_SCRATCH ); 131 133 values->bios_6_scratch = INREG( regs, RADEON_BIOS_6_SCRATCH ); 132 134 133 SHOW_FLOW( 2, "before: fp_gen_cntl=%08lx, horz=%08lx, vert=%08lx, lvds_gen_cntl=%08lx", 134 values->fp_gen_cntl, values->fp_horz_stretch, values->fp_vert_stretch, 135 values->lvds_gen_cntl ); 135 if (ai->si->asic == rt_rv280) { 136 // bit 22 of TMDS_PLL_CNTL is read-back inverted 137 values->tmds_pll_cntl ^= (1 << 22); 138 } 139 140 SHOW_FLOW( 2, "before: fp_gen_cntl=%08lx, horz=%08lx, vert=%08lx, lvds_gen_cntl=%08lx", 141 values->fp_gen_cntl, values->fp_horz_stretch, values->fp_vert_stretch, 142 values->lvds_gen_cntl ); 136 143 } 137 144 138 145 // calculcate flat panel crtc registers; … … 141 148 accelerator_info *ai, crtc_info *crtc, 142 149 fp_info *fp_port, crtc_regs *crtc_values, fp_regs *values ) 143 150 { 151 int i; 152 uint32 tmp = values->tmds_pll_cntl & 0xfffff; 153 144 154 // setup synchronization position 145 155 // (most values are ignored according to fp_gen_cntl, but at least polarity 146 156 // and pixel precise horizontal sync position are always used) 147 157 if( fp_port->is_fp2 ) { 158 SHOW_FLOW0( 2, "is_fp2" ); 148 159 values->fp2_h_sync_strt_wid = crtc_values->crtc_h_sync_strt_wid; 149 160 values->fp2_v_sync_strt_wid = crtc_values->crtc_v_sync_strt_wid; 150 161 } else { 162 SHOW_FLOW0( 2, "fp1" ); 151 163 values->fp_h_sync_strt_wid = crtc_values->crtc_h_sync_strt_wid; 152 164 values->fp_v_sync_strt_wid = crtc_values->crtc_v_sync_strt_wid; 153 165 } 154 166 155 if( fp_port->is_fp2 ) 156 values->fp2_gen_cntl = 0; 157 else { 167 if( fp_port->is_fp2 ) { 168 // should retain POST values (esp bit 28) 169 values->fp2_gen_cntl &= (0xFFFF0000); 170 171 } else { 158 172 // setup magic CRTC shadowing 159 173 values->fp_gen_cntl &= 160 174 ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN | … … 169 183 RADEON_FP_CRTC_DONT_SHADOW_HEND; 170 184 } 171 185 186 for (i = 0; i < 4; i++) { 187 if (ai->si->tmds_pll[i].freq == 0) 188 break; 189 if ((uint32)(fp_port->dot_clock) < ai->si->tmds_pll[i].freq) { 190 tmp = ai->si->tmds_pll[i].value ; 191 break; 192 } 193 } 194 195 if (IS_R300_VARIANT || (ai->si->asic == rt_rv280)) { 196 if (tmp & 0xfff00000) { 197 values->tmds_pll_cntl = tmp; 198 } else { 199 values->tmds_pll_cntl = ai->si->tmds_pll_cntl & 0xfff00000; 200 values->tmds_pll_cntl |= tmp; 201 } 202 } else { 203 values->tmds_pll_cntl = tmp; 204 } 205 206 values->tmds_trans_cntl = ai->si->tmds_transmitter_cntl 207 & ~(RADEON_TMDS_TRANSMITTER_PLLRST); 208 209 if (IS_R300_VARIANT || (ai->si->asic == rt_r200) || (ai->si->num_crtc == 1)) 210 values->tmds_trans_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN); 211 else // weird, RV chips got this bit reversed? 212 values->tmds_trans_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN); 213 214 172 215 // enable proper transmitter 173 216 if( (crtc->chosen_displays & dd_lvds) != 0 ) { 174 217 // using LVDS means there cannot be a DVI monitor 218 SHOW_FLOW0( 2, "lvds" ); 175 219 values->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); 176 220 values->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); 177 221 178 222 } else if( !fp_port->is_fp2 ) { 179 223 // DVI on internal transmitter 224 SHOW_FLOW0( 2, "DVI INT" ); 180 225 values->fp_gen_cntl |= RADEON_FP_FPON | RADEON_FP_TMDS_EN; 181 226 // enabling 8 bit data may be dangerous; BIOS should have taken care of that 182 227 values->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; 183 228 184 229 } else { 185 230 // DVI on external transmitter 231 SHOW_FLOW0( 2, "DVI EXT" ); 186 232 values->fp2_gen_cntl |= RADEON_FP2_FPON | RADEON_FP_PANEL_FORMAT; 187 233 values->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN; 188 234 235 //hack in missing bits test... 236 //values->fp2_gen_cntl |= (1 << 22) | (1 << 28); 237 189 238 if( ai->si->asic >= rt_r200 ) 190 239 values->fp2_gen_cntl |= RADEON_FP2_DV0_EN; 191 240 } 192 241 193 SHOW_FLOW( 2, "after: fp_gen_cntl=%08lx, horz=%08lx, vert=%08lx, lvds_gen_cntl=%08lx",194 values->fp_gen_cntl, values->fp _horz_stretch, values->fp_vert_stretch,242 SHOW_FLOW( 2, "after: fp_gen_cntl=%08lx, fp2_gen_cntl=%08lx, horz=%08lx, vert=%08lx, lvds_gen_cntl=%08lx", 243 values->fp_gen_cntl, values->fp2_gen_cntl, values->fp_horz_stretch, values->fp_vert_stretch, 195 244 values->lvds_gen_cntl ); 196 245 } 197 246 … … 209 258 OUTREGP( regs, RADEON_FP_GEN_CNTL, values->fp_gen_cntl, RADEON_FP_SEL_CRTC2 ); 210 259 211 260 if( fp_port->is_fp2 ) { 261 SHOW_FLOW0( 2, "is_fp2" ); 212 262 OUTREGP( regs, RADEON_FP2_GEN_CNTL, values->fp2_gen_cntl, 263 ~(RADEON_FP2_SOURCE_SEL_MASK | RADEON_FP2_SRC_SEL_MASK)); 264 OUTREGP( regs, RADEON_FP2_GEN_CNTL, values->fp2_gen_cntl, 213 265 RADEON_FP2_SOURCE_SEL_CRTC2 | RADEON_FP2_SRC_SEL_CRTC2 ); 214 266 OUTREG( regs, RADEON_FP_H2_SYNC_STRT_WID, values->fp2_h_sync_strt_wid ); 215 267 OUTREG( regs, RADEON_FP_V2_SYNC_STRT_WID, values->fp2_v_sync_strt_wid ); 216 268 } else { 269 SHOW_FLOW0( 2, "is_fp1" ); 217 270 OUTREG( regs, RADEON_FP_H_SYNC_STRT_WID, values->fp_h_sync_strt_wid ); 218 271 OUTREG( regs, RADEON_FP_V_SYNC_STRT_WID, values->fp_v_sync_strt_wid ); 219 272 } -
headers/private/graphics/radeon/fp_regs.h
35 35 # define RADEON_FP2_PANEL_FORMAT (1 << 3) 36 36 # define RADEON_FP2_SOURCE_SEL_MASK (3 << 10) 37 37 # define RADEON_FP2_SOURCE_SEL_CRTC2 (1 << 10) 38 # define RADEON_FP2_SOURCE_SEL_RMX (2 << 10) 38 39 # define RADEON_FP2_SRC_SEL_MASK (3 << 13) 39 40 # define RADEON_FP2_SRC_SEL_CRTC2 (1 << 13) 40 41 # define RADEON_FP2_FP_POL (1 << 16) … … 68 69 # define RADEON_VERT_STRETCH_BLEND (1 << 26) 69 70 # define RADEON_VERT_AUTO_RATIO_EN (1 << 27) 70 71 # define RADEON_VERT_STRETCH_RESERVED 0xf1000000 72 73 #define RADEON_TMDS_PLL_CNTL 0x02a8 74 #define RADEON_TMDS_TRANSMITTER_CNTL 0x02a4 75 # define RADEON_TMDS_TRANSMITTER_PLLEN 1 76 # define RADEON_TMDS_TRANSMITTER_PLLRST 2 77 71 78 #define RADEON_FP_H_SYNC_STRT_WID 0x02c4 72 79 #define RADEON_FP_V_SYNC_STRT_WID 0x02c8 73 80 … … 80 87 # define RADEON_LVDS_DIGON (1 << 18) 81 88 # define RADEON_LVDS_BLON (1 << 19) 82 89 # define RADEON_LVDS_SEL_CRTC2 (1 << 23) 90 #define RADEON_LVDS_PLL_CNTL 0x02d4 91 # define RADEON_HSYNC_DELAY_SHIFT 28 92 # define RADEON_HSYNC_DELAY_MASK (0xf << 28) 83 93 84 94 #define RADEON_FP_CRTC2_H_TOTAL_DISP 0x0350 85 95 #define RADEON_FP_CRTC2_V_TOTAL_DISP 0x0354 -
headers/private/graphics/radeon/radeon_interface.h
348 348 uint32 best_vco; // preferred VCO frequency (0 for don't care) 349 349 } pll_info; 350 350 351 // info for ext tmds pll 352 typedef struct { 353 uint32 freq; 354 uint32 value; 355 } tmds_pll_info; 351 356 352 357 // one overlay buffer 353 358 typedef struct overlay_buffer_node { … … 520 525 uint16 device_id; // PCI device id 521 526 uint8 revision; // PCI device revision 522 527 523 //bool has_crtc2; // has second CRTC524 528 radeon_type asic; // ASIC version 525 bool is_mobility; // mobility version526 bool is_igp; // 529 bool is_mobility; // mobility version 530 bool is_igp; // might need to know if it's an integrated chip 527 531 bool is_atombios; 528 tv_chip_type tv_chip; // type of TV-Out encoder 532 533 tv_chip_type tv_chip; // type of TV-Out encoder 529 534 bool new_pll; // r300 style PLL 530 bool has_no_i2c; // I2C is broken531 uint16 panel_pwr_delay; // delay for LCD backlight to stabilise532 uint8 theatre_channel; // VIP channel of Rage Theatre (if applicable)535 bool has_no_i2c; // I2C is broken 536 uint16 panel_pwr_delay; // delay for LCD backlight to stabilise 537 uint8 theatre_channel; // VIP channel of Rage Theatre (if applicable) 533 538 534 539 general_pll_info pll; 535 540 tmds_pll_info tmds_pll[4]; 541 536 542 area_id regs_area; // area of memory mapped registers 537 543 area_id ROM_area; // area of ROM 538 //area_id fb_area; // area of frame buffer539 544 void *framebuffer_pci; // physical address of frame buffer (aka local memory) 540 545 // this is a hack needed by BeOS 541 546 542 547 crtc_info crtc[2]; // info about each crtc 543 548 uint8 num_crtc; // number of physical heads … … 557 562 uint32 active_vc; // currently selected virtual card in terms of 2D acceleration 558 563 559 564 uint32 dac_cntl2; // content of dac_cntl2 register 565 uint32 tmds_pll_cntl; // undocumented here be dragons 566 uint32 tmds_transmitter_cntl; // undocumented here be dragons 560 567 561 568 overlay_info pending_overlay; // overlay to be shown 562 569 overlay_info active_overlay; // overlay shown