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