1a90ebd77SClemens Zeidler /* 2d5c3acacSAlexander von Gluck IV * Copyright 2006-2011, Haiku, Inc. All Rights Reserved. 3a90ebd77SClemens Zeidler * Distributed under the terms of the MIT License. 4a90ebd77SClemens Zeidler * 5a90ebd77SClemens Zeidler * Support for i915 chipset and up based on the X driver, 6a90ebd77SClemens Zeidler * Copyright 2006-2007 Intel Corporation. 7a90ebd77SClemens Zeidler * 8a90ebd77SClemens Zeidler * Authors: 9a90ebd77SClemens Zeidler * Axel Dörfler, axeld@pinc-software.de 10d5c3acacSAlexander von Gluck IV * Alexander von Gluck, kallisti5@unixzen.com 11a90ebd77SClemens Zeidler */ 12a90ebd77SClemens Zeidler 13a90ebd77SClemens Zeidler 14a90ebd77SClemens Zeidler #include "accelerant_protos.h" 15a90ebd77SClemens Zeidler #include "accelerant.h" 16d77ff85eSAlexander von Gluck IV #include "bios.h" 17a90ebd77SClemens Zeidler #include "utility.h" 18d5c3acacSAlexander von Gluck IV #include "mode.h" 196ab8261bSAlexander von Gluck IV #include "display.h" 20d3e8b642SAlexander von Gluck IV #include "pll.h" 21a90ebd77SClemens Zeidler 22a90ebd77SClemens Zeidler #include <stdio.h> 23a90ebd77SClemens Zeidler #include <string.h> 24a90ebd77SClemens Zeidler #include <math.h> 25a90ebd77SClemens Zeidler 26192781ddSAlexander von Gluck IV #include <create_display_modes.h> 27192781ddSAlexander von Gluck IV 28a90ebd77SClemens Zeidler 29a90ebd77SClemens Zeidler #define TRACE_MODE 30a90ebd77SClemens Zeidler #ifdef TRACE_MODE 31a90ebd77SClemens Zeidler extern "C" void _sPrintf(const char *format, ...); 32d5c3acacSAlexander von Gluck IV # define TRACE(x...) _sPrintf("radeon_hd: " x) 33a90ebd77SClemens Zeidler #else 34d5c3acacSAlexander von Gluck IV # define TRACE(x...) ; 35a90ebd77SClemens Zeidler #endif 36a90ebd77SClemens Zeidler 37a90ebd77SClemens Zeidler 38a90ebd77SClemens Zeidler status_t 39a90ebd77SClemens Zeidler create_mode_list(void) 40a90ebd77SClemens Zeidler { 41f35af704SAlexander von Gluck IV // TODO : multi-monitor? for now we use VESA and not gDisplay edid 42f35af704SAlexander von Gluck IV 43192781ddSAlexander von Gluck IV const color_space kRadeonHDSpaces[] = {B_RGB32_LITTLE, B_RGB24_LITTLE, 44192781ddSAlexander von Gluck IV B_RGB16_LITTLE, B_RGB15_LITTLE, B_CMAP8}; 45a90ebd77SClemens Zeidler 46192781ddSAlexander von Gluck IV gInfo->mode_list_area = create_display_modes("radeon HD modes", 472613175eSAlexander von Gluck IV gInfo->shared_info->has_edid ? &gInfo->shared_info->edid_info : NULL, 482613175eSAlexander von Gluck IV NULL, 0, kRadeonHDSpaces, 49192781ddSAlexander von Gluck IV sizeof(kRadeonHDSpaces) / sizeof(kRadeonHDSpaces[0]), 50192781ddSAlexander von Gluck IV is_mode_supported, &gInfo->mode_list, &gInfo->shared_info->mode_count); 51192781ddSAlexander von Gluck IV if (gInfo->mode_list_area < B_OK) 52192781ddSAlexander von Gluck IV return gInfo->mode_list_area; 53a90ebd77SClemens Zeidler 54192781ddSAlexander von Gluck IV gInfo->shared_info->mode_list_area = gInfo->mode_list_area; 55d5c3acacSAlexander von Gluck IV 56a90ebd77SClemens Zeidler return B_OK; 57a90ebd77SClemens Zeidler } 58a90ebd77SClemens Zeidler 59a90ebd77SClemens Zeidler 60a90ebd77SClemens Zeidler // #pragma mark - 61a90ebd77SClemens Zeidler 62a90ebd77SClemens Zeidler 63a90ebd77SClemens Zeidler uint32 64a90ebd77SClemens Zeidler radeon_accelerant_mode_count(void) 65a90ebd77SClemens Zeidler { 66333bd770SAlexander von Gluck IV TRACE("%s\n", __func__); 67a90ebd77SClemens Zeidler 68a90ebd77SClemens Zeidler return gInfo->shared_info->mode_count; 69a90ebd77SClemens Zeidler } 70a90ebd77SClemens Zeidler 71a90ebd77SClemens Zeidler 72a90ebd77SClemens Zeidler status_t 73a90ebd77SClemens Zeidler radeon_get_mode_list(display_mode *modeList) 74a90ebd77SClemens Zeidler { 75333bd770SAlexander von Gluck IV TRACE("%s\n", __func__); 76a90ebd77SClemens Zeidler memcpy(modeList, gInfo->mode_list, 77a90ebd77SClemens Zeidler gInfo->shared_info->mode_count * sizeof(display_mode)); 78a90ebd77SClemens Zeidler return B_OK; 79a90ebd77SClemens Zeidler } 80a90ebd77SClemens Zeidler 81a90ebd77SClemens Zeidler 8288bfef92SAlexander von Gluck IV status_t 8388bfef92SAlexander von Gluck IV radeon_get_edid_info(void* info, size_t size, uint32* edid_version) 8488bfef92SAlexander von Gluck IV { 85f35af704SAlexander von Gluck IV // TODO : multi-monitor? for now we use VESA and not gDisplay edid 86f35af704SAlexander von Gluck IV 8788bfef92SAlexander von Gluck IV TRACE("%s\n", __func__); 8888bfef92SAlexander von Gluck IV if (!gInfo->shared_info->has_edid) 8988bfef92SAlexander von Gluck IV return B_ERROR; 9088bfef92SAlexander von Gluck IV if (size < sizeof(struct edid1_info)) 9188bfef92SAlexander von Gluck IV return B_BUFFER_OVERFLOW; 9288bfef92SAlexander von Gluck IV 9388bfef92SAlexander von Gluck IV memcpy(info, &gInfo->shared_info->edid_info, sizeof(struct edid1_info)); 9488bfef92SAlexander von Gluck IV *edid_version = EDID_VERSION_1; 9588bfef92SAlexander von Gluck IV 9688bfef92SAlexander von Gluck IV return B_OK; 9788bfef92SAlexander von Gluck IV } 9888bfef92SAlexander von Gluck IV 9988bfef92SAlexander von Gluck IV 100*7934da0fSAlexander von Gluck IV uint32 101*7934da0fSAlexander von Gluck IV radeon_dpms_capabilities(void) 102*7934da0fSAlexander von Gluck IV { 103*7934da0fSAlexander von Gluck IV // These should be pretty universally supported on Radeon HD cards 104*7934da0fSAlexander von Gluck IV return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF; 105*7934da0fSAlexander von Gluck IV } 106*7934da0fSAlexander von Gluck IV 107*7934da0fSAlexander von Gluck IV 108*7934da0fSAlexander von Gluck IV uint32 109*7934da0fSAlexander von Gluck IV radeon_dpms_mode(void) 110*7934da0fSAlexander von Gluck IV { 111*7934da0fSAlexander von Gluck IV // TODO : this really isn't a good long-term solution 112*7934da0fSAlexander von Gluck IV // we may need to look at the encoder dpms scratch registers 113*7934da0fSAlexander von Gluck IV return gInfo->dpms_mode; 114*7934da0fSAlexander von Gluck IV } 115*7934da0fSAlexander von Gluck IV 116*7934da0fSAlexander von Gluck IV 117b54c8119SAlexander von Gluck IV void 118b54c8119SAlexander von Gluck IV radeon_dpms_set(int mode) 119b54c8119SAlexander von Gluck IV { 120b54c8119SAlexander von Gluck IV switch(mode) { 121b54c8119SAlexander von Gluck IV case B_DPMS_ON: 122936aec74SAlexander von Gluck IV TRACE("%s: ON\n", __func__); 123b54c8119SAlexander von Gluck IV for (uint8 id = 0; id < MAX_DISPLAY; id++) { 124b54c8119SAlexander von Gluck IV if (gDisplay[id]->active == false) 125b54c8119SAlexander von Gluck IV continue; 126936aec74SAlexander von Gluck IV display_crtc_lock(id, ATOM_ENABLE); 127b54c8119SAlexander von Gluck IV display_crtc_power(id, ATOM_ENABLE); 128b54c8119SAlexander von Gluck IV display_crtc_memreq(id, ATOM_ENABLE); 129b54c8119SAlexander von Gluck IV display_crtc_blank(id, ATOM_DISABLE); 130936aec74SAlexander von Gluck IV display_crtc_lock(id, ATOM_DISABLE); 131b54c8119SAlexander von Gluck IV } 132b54c8119SAlexander von Gluck IV break; 133b54c8119SAlexander von Gluck IV case B_DPMS_STAND_BY: 134b54c8119SAlexander von Gluck IV case B_DPMS_SUSPEND: 135b54c8119SAlexander von Gluck IV case B_DPMS_OFF: 136936aec74SAlexander von Gluck IV TRACE("%s: OFF\n", __func__); 137b54c8119SAlexander von Gluck IV for (uint8 id = 0; id < MAX_DISPLAY; id++) { 138b54c8119SAlexander von Gluck IV if (gDisplay[id]->active == false) 139b54c8119SAlexander von Gluck IV continue; 140936aec74SAlexander von Gluck IV display_crtc_lock(id, ATOM_ENABLE); 141b54c8119SAlexander von Gluck IV display_crtc_blank(id, ATOM_ENABLE); 142b54c8119SAlexander von Gluck IV display_crtc_memreq(id, ATOM_DISABLE); 143b54c8119SAlexander von Gluck IV display_crtc_power(id, ATOM_DISABLE); 144936aec74SAlexander von Gluck IV display_crtc_lock(id, ATOM_DISABLE); 145b54c8119SAlexander von Gluck IV } 146b54c8119SAlexander von Gluck IV break; 147b54c8119SAlexander von Gluck IV } 148*7934da0fSAlexander von Gluck IV gInfo->dpms_mode = mode; 149b54c8119SAlexander von Gluck IV } 150b54c8119SAlexander von Gluck IV 151b54c8119SAlexander von Gluck IV 152a90ebd77SClemens Zeidler status_t 153a90ebd77SClemens Zeidler radeon_set_display_mode(display_mode *mode) 154a90ebd77SClemens Zeidler { 155f35af704SAlexander von Gluck IV // TODO : multi-monitor? for now we use VESA and not gDisplay edid 1566ab8261bSAlexander von Gluck IV // Set mode on each display 1576ab8261bSAlexander von Gluck IV for (uint8 id = 0; id < MAX_DISPLAY; id++) { 158b54c8119SAlexander von Gluck IV if (gDisplay[id]->active == false) 1596ab8261bSAlexander von Gluck IV continue; 160f2fe29a0SAlexander von Gluck IV 161ffb494caSAlexander von Gluck IV uint16 connector_index = gDisplay[id]->connector_index; 16217b66d82SAlexander von Gluck IV 163b54c8119SAlexander von Gluck IV // *** encoder prep 164b54c8119SAlexander von Gluck IV encoder_output_lock(true); 1651fca5eafSAlexander von Gluck IV encoder_dpms_set(id, gConnector[connector_index]->encoder.object_id, 166ffb494caSAlexander von Gluck IV B_DPMS_OFF); 16717b66d82SAlexander von Gluck IV encoder_assign_crtc(id); 168e53d6375SAlexander von Gluck IV 169b54c8119SAlexander von Gluck IV // *** CRT controler prep 170b54c8119SAlexander von Gluck IV display_crtc_lock(id, ATOM_ENABLE); 171936aec74SAlexander von Gluck IV display_crtc_blank(id, ATOM_ENABLE); 172936aec74SAlexander von Gluck IV display_crtc_memreq(id, ATOM_DISABLE); 173936aec74SAlexander von Gluck IV display_crtc_power(id, ATOM_DISABLE); 174f35af704SAlexander von Gluck IV 175b54c8119SAlexander von Gluck IV // *** CRT controler mode set 17617b66d82SAlexander von Gluck IV // TODO : program SS 177e7d0abaeSAlexander von Gluck IV pll_set(ATOM_PPLL1, mode->timing.pixel_clock, id); 178e7d0abaeSAlexander von Gluck IV // TODO : check if ATOM_PPLL1 is used and use ATOM_PPLL2 if so 1796da3f7d4SAlexander von Gluck IV display_crtc_set_dtd(id, mode); 180b54c8119SAlexander von Gluck IV 181b54c8119SAlexander von Gluck IV // TODO : vvvv : atombios_crtc_set_base 1827c91a33cSAlexander von Gluck IV display_crtc_fb_set_dce1(id, mode); 183b54c8119SAlexander von Gluck IV // atombios_overscan_setup 1846da3f7d4SAlexander von Gluck IV display_crtc_scale(id, mode); 1856ab8261bSAlexander von Gluck IV 186b54c8119SAlexander von Gluck IV // *** encoder mode set 187b54c8119SAlexander von Gluck IV encoder_mode_set(id, mode->timing.pixel_clock); 188b54c8119SAlexander von Gluck IV 189b54c8119SAlexander von Gluck IV // *** CRT controler commit 190936aec74SAlexander von Gluck IV display_crtc_blank(id, ATOM_DISABLE); 191936aec74SAlexander von Gluck IV display_crtc_memreq(id, ATOM_ENABLE); 192936aec74SAlexander von Gluck IV display_crtc_power(id, ATOM_ENABLE); 1936da3f7d4SAlexander von Gluck IV display_crtc_lock(id, ATOM_DISABLE); 194b54c8119SAlexander von Gluck IV 195b54c8119SAlexander von Gluck IV // *** encoder commit 1961fca5eafSAlexander von Gluck IV encoder_dpms_set(id, gConnector[connector_index]->encoder.object_id, 197ffb494caSAlexander von Gluck IV B_DPMS_ON); 198b54c8119SAlexander von Gluck IV encoder_output_lock(false); 1996ab8261bSAlexander von Gluck IV } 2006604b1b6SAlexander von Gluck IV 201aa2a6e33SAlexander von Gluck IV int32 crtstatus = Read32(CRT, D1CRTC_STATUS); 2025f6744a8SAlexander von Gluck IV TRACE("CRT0 Status: 0x%X\n", crtstatus); 203f2fe29a0SAlexander von Gluck IV crtstatus = Read32(CRT, D2CRTC_STATUS); 204f2fe29a0SAlexander von Gluck IV TRACE("CRT1 Status: 0x%X\n", crtstatus); 2053be5e036SAlexander von Gluck IV 206a90ebd77SClemens Zeidler return B_OK; 207a90ebd77SClemens Zeidler } 208a90ebd77SClemens Zeidler 209a90ebd77SClemens Zeidler 210a90ebd77SClemens Zeidler status_t 211a90ebd77SClemens Zeidler radeon_get_display_mode(display_mode *_currentMode) 212a90ebd77SClemens Zeidler { 213d5c3acacSAlexander von Gluck IV TRACE("%s\n", __func__); 214a90ebd77SClemens Zeidler 215192781ddSAlexander von Gluck IV *_currentMode = gInfo->shared_info->current_mode; 216a90ebd77SClemens Zeidler return B_OK; 217a90ebd77SClemens Zeidler } 218a90ebd77SClemens Zeidler 219a90ebd77SClemens Zeidler 220a90ebd77SClemens Zeidler status_t 221a90ebd77SClemens Zeidler radeon_get_frame_buffer_config(frame_buffer_config *config) 222a90ebd77SClemens Zeidler { 223d5c3acacSAlexander von Gluck IV TRACE("%s\n", __func__); 224a90ebd77SClemens Zeidler 2253be5e036SAlexander von Gluck IV config->frame_buffer = gInfo->shared_info->frame_buffer; 2263be5e036SAlexander von Gluck IV config->frame_buffer_dma = (uint8 *)gInfo->shared_info->frame_buffer_phys; 22751a43d0fSAlexander von Gluck IV 228a90ebd77SClemens Zeidler config->bytes_per_row = gInfo->shared_info->bytes_per_row; 229a90ebd77SClemens Zeidler 230a90ebd77SClemens Zeidler return B_OK; 231a90ebd77SClemens Zeidler } 232a90ebd77SClemens Zeidler 233a90ebd77SClemens Zeidler 234a90ebd77SClemens Zeidler status_t 235a90ebd77SClemens Zeidler radeon_get_pixel_clock_limits(display_mode *mode, uint32 *_low, uint32 *_high) 236a90ebd77SClemens Zeidler { 237d5c3acacSAlexander von Gluck IV TRACE("%s\n", __func__); 238e7e76b29SAlexander von Gluck IV 239a90ebd77SClemens Zeidler if (_low != NULL) { 240a90ebd77SClemens Zeidler // lower limit of about 48Hz vertical refresh 2415f6744a8SAlexander von Gluck IV uint32 totalClocks = (uint32)mode->timing.h_total 2425f6744a8SAlexander von Gluck IV *(uint32)mode->timing.v_total; 243a90ebd77SClemens Zeidler uint32 low = (totalClocks * 48L) / 1000L; 244e7e76b29SAlexander von Gluck IV 245d3e8b642SAlexander von Gluck IV if (low < PLL_MIN_DEFAULT) 246d3e8b642SAlexander von Gluck IV low = PLL_MIN_DEFAULT; 247d3e8b642SAlexander von Gluck IV else if (low > PLL_MAX_DEFAULT) 248a90ebd77SClemens Zeidler return B_ERROR; 249a90ebd77SClemens Zeidler 250a90ebd77SClemens Zeidler *_low = low; 251a90ebd77SClemens Zeidler } 252a90ebd77SClemens Zeidler 253a90ebd77SClemens Zeidler if (_high != NULL) 254d3e8b642SAlexander von Gluck IV *_high = PLL_MAX_DEFAULT; 255e7e76b29SAlexander von Gluck IV 256e7e76b29SAlexander von Gluck IV //*_low = 48L; 257e7e76b29SAlexander von Gluck IV //*_high = 100 * 1000000L; 258a90ebd77SClemens Zeidler return B_OK; 259a90ebd77SClemens Zeidler } 260a90ebd77SClemens Zeidler 261a90ebd77SClemens Zeidler 262192781ddSAlexander von Gluck IV bool 263192781ddSAlexander von Gluck IV is_mode_supported(display_mode *mode) 264192781ddSAlexander von Gluck IV { 265d1d65a79SAlexander von Gluck IV TRACE("MODE: %d ; %d %d %d %d ; %d %d %d %d\n", 266d1d65a79SAlexander von Gluck IV mode->timing.pixel_clock, mode->timing.h_display, 267d1d65a79SAlexander von Gluck IV mode->timing.h_sync_start, mode->timing.h_sync_end, 268d1d65a79SAlexander von Gluck IV mode->timing.h_total, mode->timing.v_display, 269d1d65a79SAlexander von Gluck IV mode->timing.v_sync_start, mode->timing.v_sync_end, 270d1d65a79SAlexander von Gluck IV mode->timing.v_total); 271d1d65a79SAlexander von Gluck IV 2721dac4469SAlexander von Gluck IV // Validate modeline is within a sane range 273192781ddSAlexander von Gluck IV if (is_mode_sane(mode) != B_OK) 274192781ddSAlexander von Gluck IV return false; 275192781ddSAlexander von Gluck IV 27695e1d7e8SAlexander von Gluck IV // TODO : is_mode_supported on *which* display? 277d1d65a79SAlexander von Gluck IV uint32 crtid = 0; 2781dac4469SAlexander von Gluck IV 279d1d65a79SAlexander von Gluck IV // if we have edid info, check frequency adginst crt reported valid ranges 280e1b9d6e6SAlexander von Gluck IV if (gInfo->shared_info->has_edid 281e1b9d6e6SAlexander von Gluck IV && gDisplay[crtid]->found_ranges) { 2821dac4469SAlexander von Gluck IV 283d1d65a79SAlexander von Gluck IV uint32 hfreq = mode->timing.pixel_clock / mode->timing.h_total; 28495e1d7e8SAlexander von Gluck IV if (hfreq > gDisplay[crtid]->hfreq_max + 1 28595e1d7e8SAlexander von Gluck IV || hfreq < gDisplay[crtid]->hfreq_min - 1) { 286d1d65a79SAlexander von Gluck IV TRACE("!!! hfreq : %d , hfreq_min : %d, hfreq_max : %d\n", 28795e1d7e8SAlexander von Gluck IV hfreq, gDisplay[crtid]->hfreq_min, gDisplay[crtid]->hfreq_max); 288d1d65a79SAlexander von Gluck IV TRACE("!!! %dx%d falls outside of CRT %d's valid " 289d1d65a79SAlexander von Gluck IV "horizontal range.\n", mode->timing.h_display, 290d1d65a79SAlexander von Gluck IV mode->timing.v_display, crtid); 291d1d65a79SAlexander von Gluck IV return false; 292d1d65a79SAlexander von Gluck IV } 293d1d65a79SAlexander von Gluck IV 294d1d65a79SAlexander von Gluck IV uint32 vfreq = mode->timing.pixel_clock / ((mode->timing.v_total 295d1d65a79SAlexander von Gluck IV * mode->timing.h_total) / 1000); 296d1d65a79SAlexander von Gluck IV 29795e1d7e8SAlexander von Gluck IV if (vfreq > gDisplay[crtid]->vfreq_max + 1 29895e1d7e8SAlexander von Gluck IV || vfreq < gDisplay[crtid]->vfreq_min - 1) { 299d1d65a79SAlexander von Gluck IV TRACE("!!! vfreq : %d , vfreq_min : %d, vfreq_max : %d\n", 30095e1d7e8SAlexander von Gluck IV vfreq, gDisplay[crtid]->vfreq_min, gDisplay[crtid]->vfreq_max); 301d1d65a79SAlexander von Gluck IV TRACE("!!! %dx%d falls outside of CRT %d's valid vertical range\n", 302d1d65a79SAlexander von Gluck IV mode->timing.h_display, mode->timing.v_display, crtid); 303d1d65a79SAlexander von Gluck IV return false; 304d1d65a79SAlexander von Gluck IV } 305e1b9d6e6SAlexander von Gluck IV } 306e1b9d6e6SAlexander von Gluck IV 307d1d65a79SAlexander von Gluck IV TRACE("%dx%d is within CRT %d's valid frequency range\n", 308d1d65a79SAlexander von Gluck IV mode->timing.h_display, mode->timing.v_display, crtid); 309192781ddSAlexander von Gluck IV 310192781ddSAlexander von Gluck IV return true; 311192781ddSAlexander von Gluck IV } 312192781ddSAlexander von Gluck IV 313192781ddSAlexander von Gluck IV 314d5c3acacSAlexander von Gluck IV /* 315d5c3acacSAlexander von Gluck IV * A quick sanity check of the provided display_mode 316d5c3acacSAlexander von Gluck IV */ 317d5c3acacSAlexander von Gluck IV status_t 318192781ddSAlexander von Gluck IV is_mode_sane(display_mode *mode) 319d5c3acacSAlexander von Gluck IV { 320333bd770SAlexander von Gluck IV // horizontal timing 321333bd770SAlexander von Gluck IV // validate h_sync_start is less then h_sync_end 322333bd770SAlexander von Gluck IV if (mode->timing.h_sync_start > mode->timing.h_sync_end) { 32391235829SAlexander von Gluck IV TRACE("%s: ERROR: (%dx%d) " 32491235829SAlexander von Gluck IV "received h_sync_start greater then h_sync_end!\n", 325333bd770SAlexander von Gluck IV __func__, mode->timing.h_display, mode->timing.v_display); 326333bd770SAlexander von Gluck IV return B_ERROR; 327333bd770SAlexander von Gluck IV } 328333bd770SAlexander von Gluck IV // validate h_total is greater then h_display 329333bd770SAlexander von Gluck IV if (mode->timing.h_total < mode->timing.h_display) { 33091235829SAlexander von Gluck IV TRACE("%s: ERROR: (%dx%d) " 33191235829SAlexander von Gluck IV "received h_total greater then h_display!\n", 332333bd770SAlexander von Gluck IV __func__, mode->timing.h_display, mode->timing.v_display); 333d5c3acacSAlexander von Gluck IV return B_ERROR; 334d5c3acacSAlexander von Gluck IV } 335d5c3acacSAlexander von Gluck IV 336333bd770SAlexander von Gluck IV // vertical timing 337333bd770SAlexander von Gluck IV // validate v_start is less then v_end 338333bd770SAlexander von Gluck IV if (mode->timing.v_sync_start > mode->timing.v_sync_end) { 33991235829SAlexander von Gluck IV TRACE("%s: ERROR: (%dx%d) " 34091235829SAlexander von Gluck IV "received v_sync_start greater then v_sync_end!\n", 341333bd770SAlexander von Gluck IV __func__, mode->timing.h_display, mode->timing.v_display); 342d5c3acacSAlexander von Gluck IV return B_ERROR; 343d5c3acacSAlexander von Gluck IV } 344333bd770SAlexander von Gluck IV // validate v_total is greater then v_display 345333bd770SAlexander von Gluck IV if (mode->timing.v_total < mode->timing.v_display) { 34691235829SAlexander von Gluck IV TRACE("%s: ERROR: (%dx%d) " 34791235829SAlexander von Gluck IV "received v_total greater then v_display!\n", 348333bd770SAlexander von Gluck IV __func__, mode->timing.h_display, mode->timing.v_display); 349d5c3acacSAlexander von Gluck IV return B_ERROR; 350d5c3acacSAlexander von Gluck IV } 351d5c3acacSAlexander von Gluck IV 35291235829SAlexander von Gluck IV // calculate refresh rate for given timings to whole int (in Hz) 35391235829SAlexander von Gluck IV int refresh = mode->timing.pixel_clock * 1000 35491235829SAlexander von Gluck IV / (mode->timing.h_total * mode->timing.v_total); 35591235829SAlexander von Gluck IV 35691235829SAlexander von Gluck IV if (refresh < 30 || refresh > 250) { 35791235829SAlexander von Gluck IV TRACE("%s: ERROR: (%dx%d) " 35891235829SAlexander von Gluck IV "refresh rate of %dHz is unlikely for any kind of monitor!\n", 35991235829SAlexander von Gluck IV __func__, mode->timing.h_display, mode->timing.v_display, refresh); 36091235829SAlexander von Gluck IV return B_ERROR; 36191235829SAlexander von Gluck IV } 36291235829SAlexander von Gluck IV 363d5c3acacSAlexander von Gluck IV return B_OK; 364d5c3acacSAlexander von Gluck IV } 365d5c3acacSAlexander von Gluck IV 366d1d65a79SAlexander von Gluck IV 367