1/* 2 * Copyright 2005-2015, Axel D��rfler, axeld@pinc-software.de. 3 * Copyright 2016, Jessica Hamilton, jessica.l.hamilton@gmail.com. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8#include <stdlib.h> 9#include <string.h> 10 11#include <compute_display_timing.h> 12#include <create_display_modes.h> 13 14#include "accelerant_protos.h" 15#include "accelerant.h" 16#include "utility.h" 17 18 19//#define TRACE_MODE 20#ifdef TRACE_MODE 21extern "C" void _sPrintf(const char* format, ...); 22# define TRACE(x) _sPrintf x 23#else 24# define TRACE(x) ; 25#endif 26 27 28bool 29operator==(const display_mode &lhs, const display_mode &rhs) 30{ 31 return lhs.space == rhs.space 32 && lhs.virtual_width == rhs.virtual_width 33 && lhs.virtual_height == rhs.virtual_height 34 && lhs.h_display_start == rhs.h_display_start 35 && lhs.v_display_start == rhs.v_display_start; 36} 37 38 39/*! Checks if the specified \a mode can be set using VESA. */ 40static bool 41is_mode_supported(display_mode* mode) 42{ 43 return (mode != NULL) && (*mode == gInfo->shared_info->current_mode); 44} 45 46 47/*! Creates the initial mode list of the primary accelerant. 48 It's called from vesa_init_accelerant(). 49*/ 50status_t 51create_mode_list(void) 52{ 53 const color_space colorspace[] = { 54 (color_space)gInfo->shared_info->current_mode.space 55 }; 56 display_mode mode = gInfo->shared_info->current_mode; 57 58 compute_display_timing(mode.virtual_width, mode.virtual_height, 60, false, 59 &mode.timing); 60 fill_display_mode(mode.virtual_width, mode.virtual_height, &mode); 61 62 gInfo->mode_list_area = create_display_modes("framebuffer modes", 63 NULL, &mode, 1, colorspace, 1, is_mode_supported, &gInfo->mode_list, 64 &gInfo->shared_info->mode_count); 65 66 if (gInfo->mode_list_area < 0) 67 return gInfo->mode_list_area; 68 69 gInfo->shared_info->mode_list_area = gInfo->mode_list_area; 70 return B_OK; 71} 72 73 74// #pragma mark - 75 76 77uint32 78framebuffer_accelerant_mode_count(void) 79{ 80 TRACE(("framebuffer_accelerant_mode_count() = %d\n", 81 gInfo->shared_info->mode_count)); 82 return gInfo->shared_info->mode_count; 83} 84 85 86status_t 87framebuffer_get_mode_list(display_mode* modeList) 88{ 89 TRACE(("framebuffer_get_mode_info()\n")); 90 memcpy(modeList, gInfo->mode_list, 91 gInfo->shared_info->mode_count * sizeof(display_mode)); 92 return B_OK; 93} 94 95 96status_t 97framebuffer_set_display_mode(display_mode* _mode) 98{ 99 TRACE(("framebuffer_set_display_mode()\n")); 100 if (_mode != NULL && *_mode == gInfo->shared_info->current_mode) 101 return B_OK; 102 103 return B_UNSUPPORTED; 104} 105 106 107status_t 108framebuffer_get_display_mode(display_mode* _currentMode) 109{ 110 TRACE(("framebuffer_get_display_mode()\n")); 111 *_currentMode = gInfo->shared_info->current_mode; 112 return B_OK; 113} 114 115 116status_t 117framebuffer_get_edid_info(void* info, size_t size, uint32* _version) 118{ 119 TRACE(("framebuffer_get_edid_info()\n")); 120 121 if (!gInfo->shared_info->has_edid) 122 return B_ERROR; 123 if (size < sizeof(struct edid1_info)) 124 return B_BUFFER_OVERFLOW; 125 126 memcpy(info, &gInfo->shared_info->edid_info, sizeof(struct edid1_info)); 127 *_version = EDID_VERSION_1; 128 return B_OK; 129} 130 131 132status_t 133framebuffer_get_frame_buffer_config(frame_buffer_config* config) 134{ 135 TRACE(("framebuffer_get_frame_buffer_config()\n")); 136 137 config->frame_buffer = gInfo->shared_info->frame_buffer; 138 config->frame_buffer_dma = gInfo->shared_info->physical_frame_buffer; 139 config->bytes_per_row = gInfo->shared_info->bytes_per_row; 140 141 return B_OK; 142} 143 144 145status_t 146framebuffer_get_pixel_clock_limits(display_mode* mode, uint32* _low, uint32* _high) 147{ 148 TRACE(("framebuffer_get_pixel_clock_limits()\n")); 149 150 // TODO: do some real stuff here (taken from radeon driver) 151 uint32 totalPixel = (uint32)mode->timing.h_total 152 * (uint32)mode->timing.v_total; 153 uint32 clockLimit = 2000000; 154 155 // lower limit of about 48Hz vertical refresh 156 *_low = totalPixel * 48L / 1000L; 157 if (*_low > clockLimit) 158 return B_ERROR; 159 160 *_high = clockLimit; 161 return B_OK; 162} 163 164