1 /* 2 * Copyright (c) 2002, Thomas Kurschel 3 * Distributed under the terms of the MIT License. 4 */ 5 6 /*! Public mode-specific info functions */ 7 8 9 #include "radeon_accelerant.h" 10 #include "GlobalData.h" 11 #include "generic.h" 12 13 #include <GraphicsDefs.h> 14 15 16 status_t 17 GET_DISPLAY_MODE(display_mode *mode) 18 { 19 virtual_card *vc = ai->vc; 20 21 // TBD: there is a race condition if someone else is just setting it 22 // we won't lock up but return non-sense 23 24 *mode = vc->mode; 25 26 // we hide multi-monitor-mode because :- 27 // - we want to look like an ordinary single-screen driver 28 // - the multi-mode is already adapted to current screen configuration, 29 // and the mode should be configuration-independant 30 Radeon_HideMultiMode(vc, mode); 31 return B_OK; 32 } 33 34 35 status_t 36 GET_FRAME_BUFFER_CONFIG(frame_buffer_config *afb) 37 { 38 virtual_card *vc = ai->vc; 39 40 // TBD: race condition again 41 42 // easy again, as the last mode set stored the info in a convienient form 43 *afb = vc->fbc; 44 return B_OK; 45 } 46 47 48 status_t 49 GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high) 50 { 51 // we ignore stuff like DVI/LCD restrictions - 52 // they are handled automatically on set_display_mode 53 uint32 total_pix = (uint32)dm->timing.h_total * (uint32)dm->timing.v_total; 54 uint32 clock_limit = ai->si->pll.max_pll_freq * 10; 55 56 /* lower limit of about 48Hz vertical refresh */ 57 *low = (total_pix * 48L) / 1000L; 58 if (*low > clock_limit) 59 return B_ERROR; 60 61 *high = clock_limit; 62 return B_OK; 63 } 64 65 66 #ifdef __HAIKU__ 67 68 status_t 69 radeon_get_preferred_display_mode(display_mode* mode) 70 { 71 fp_info *fpInfo = &ai->si->flatpanels[0]; 72 disp_entity* routes = &ai->si->routing; 73 uint32 i; 74 75 if (routes->port_info[0].edid_valid || routes->port_info[1].edid_valid) { 76 // prefer EDID data in this case 77 return B_ERROR; 78 } 79 80 if ((ai->vc->connected_displays & (dd_dvi | dd_dvi_ext | dd_lvds)) == 0) 81 return B_NOT_SUPPORTED; 82 83 // Mode has already been added by addFPMode(), just return it 84 85 for (i = 0; i < ai->si->mode_count; ++i) { 86 if (ai->mode_list[i].timing.h_display == fpInfo->panel_xres 87 && ai->mode_list[i].timing.v_display == fpInfo->panel_yres 88 && ai->mode_list[i].virtual_width == fpInfo->panel_xres 89 && ai->mode_list[i].virtual_height == fpInfo->panel_yres 90 && ai->mode_list[i].space == B_RGB32_LITTLE) { 91 memcpy(mode, &ai->mode_list[i], sizeof(display_mode)); 92 return B_OK; 93 } 94 } 95 96 return B_ERROR; 97 } 98 99 100 status_t 101 radeon_get_edid_info(void* info, size_t size, uint32* _version) 102 { 103 disp_entity* routes = &ai->si->routing; 104 int32 index; 105 106 if (size < sizeof(struct edid1_info)) 107 return B_BUFFER_OVERFLOW; 108 109 if (routes->port_info[0].edid_valid) 110 index = 0; 111 else if (routes->port_info[1].edid_valid) 112 index = 1; 113 else 114 return B_ERROR; 115 116 memcpy(info, &routes->port_info[index].edid, sizeof(struct edid1_info)); 117 *_version = EDID_VERSION_1; 118 return B_OK; 119 } 120 121 #endif // __HAIKU__ 122 123 /* 124 Return the semaphore id that will be used to signal a vertical retrace 125 occured. 126 */ 127 sem_id 128 ACCELERANT_RETRACE_SEMAPHORE(void) 129 { 130 virtual_card *vc = ai->vc; 131 132 /* 133 NOTE: 134 The kernel driver created this for us. We don't know if the system is 135 using real interrupts, or if we're faking it, and we don't care. 136 If we choose not to support this at all, we'd just return B_ERROR here, 137 and the user wouldn't get any kind of vertical retrace support. 138 */ 139 // with multi-monitor mode, we have two vertical blanks! 140 // until we find a better solution, we always return virtual port 0, 141 // which may be either physical port 0 or 1 142 int crtcIndex; 143 144 if( vc->used_crtc[0] ) 145 crtcIndex = 0; 146 else 147 crtcIndex = 1; 148 149 //SHOW_INFO( 3, "semaphore: %x", ai->si->ports[physical_port].vblank ); 150 151 return ai->si->crtc[crtcIndex].vblank; 152 } 153