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
21 extern "C" void _sPrintf(const char* format, ...);
22 # define TRACE(x) _sPrintf x
23 #else
24 # define TRACE(x) ;
25 #endif
26
27
28 bool
operator ==(const display_mode & lhs,const display_mode & rhs)29 operator==(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. */
40 static bool
is_mode_supported(display_mode * mode)41 is_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 */
50 status_t
create_mode_list(void)51 create_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
77 uint32
framebuffer_accelerant_mode_count(void)78 framebuffer_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
86 status_t
framebuffer_get_mode_list(display_mode * modeList)87 framebuffer_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
96 status_t
framebuffer_set_display_mode(display_mode * _mode)97 framebuffer_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
107 status_t
framebuffer_get_display_mode(display_mode * _currentMode)108 framebuffer_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
116 status_t
framebuffer_get_edid_info(void * info,size_t size,uint32 * _version)117 framebuffer_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
132 status_t
framebuffer_get_frame_buffer_config(frame_buffer_config * config)133 framebuffer_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
145 status_t
framebuffer_get_pixel_clock_limits(display_mode * mode,uint32 * _low,uint32 * _high)146 framebuffer_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