Noralf Trønnes | 40e1a70 | 2021-03-13 12:25:45 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: MIT */ |
| 2 | /* |
| 3 | * Copyright 2020 Noralf Trønnes |
| 4 | */ |
| 5 | |
| 6 | #ifndef __LINUX_GUD_H |
| 7 | #define __LINUX_GUD_H |
| 8 | |
| 9 | #include <linux/types.h> |
| 10 | |
| 11 | /* |
| 12 | * struct gud_display_descriptor_req - Display descriptor |
| 13 | * @magic: Magic value GUD_DISPLAY_MAGIC |
| 14 | * @version: Protocol version |
| 15 | * @flags: Flags |
| 16 | * - STATUS_ON_SET: Always do a status request after a SET request. |
| 17 | * This is used by the Linux gadget driver since it has |
| 18 | * no way to control the status stage of a control OUT |
| 19 | * request that has a payload. |
| 20 | * - FULL_UPDATE: Always send the entire framebuffer when flushing changes. |
| 21 | * The GUD_REQ_SET_BUFFER request will not be sent |
| 22 | * before each bulk transfer, it will only be sent if the |
| 23 | * previous bulk transfer had failed. This gives the device |
| 24 | * a chance to reset its state machine if needed. |
| 25 | * This flag can not be used in combination with compression. |
| 26 | * @compression: Supported compression types |
| 27 | * - GUD_COMPRESSION_LZ4: LZ4 lossless compression. |
| 28 | * @max_buffer_size: Maximum buffer size the device can handle (optional). |
| 29 | * This is useful for devices that don't have a big enough |
| 30 | * buffer to decompress the entire framebuffer in one go. |
| 31 | * @min_width: Minimum pixel width the controller can handle |
| 32 | * @max_width: Maximum width |
| 33 | * @min_height: Minimum height |
| 34 | * @max_height: Maximum height |
| 35 | * |
| 36 | * Devices that have only one display mode will have min_width == max_width |
| 37 | * and min_height == max_height. |
| 38 | */ |
| 39 | struct gud_display_descriptor_req { |
| 40 | __le32 magic; |
| 41 | #define GUD_DISPLAY_MAGIC 0x1d50614d |
| 42 | __u8 version; |
| 43 | __le32 flags; |
| 44 | #define GUD_DISPLAY_FLAG_STATUS_ON_SET BIT(0) |
| 45 | #define GUD_DISPLAY_FLAG_FULL_UPDATE BIT(1) |
| 46 | __u8 compression; |
| 47 | #define GUD_COMPRESSION_LZ4 BIT(0) |
| 48 | __le32 max_buffer_size; |
| 49 | __le32 min_width; |
| 50 | __le32 max_width; |
| 51 | __le32 min_height; |
| 52 | __le32 max_height; |
| 53 | } __packed; |
| 54 | |
| 55 | /* |
| 56 | * struct gud_property_req - Property |
| 57 | * @prop: Property |
| 58 | * @val: Value |
| 59 | */ |
| 60 | struct gud_property_req { |
| 61 | __le16 prop; |
| 62 | __le64 val; |
| 63 | } __packed; |
| 64 | |
| 65 | /* |
| 66 | * struct gud_display_mode_req - Display mode |
| 67 | * @clock: Pixel clock in kHz |
| 68 | * @hdisplay: Horizontal display size |
| 69 | * @hsync_start: Horizontal sync start |
| 70 | * @hsync_end: Horizontal sync end |
| 71 | * @htotal: Horizontal total size |
| 72 | * @vdisplay: Vertical display size |
| 73 | * @vsync_start: Vertical sync start |
| 74 | * @vsync_end: Vertical sync end |
| 75 | * @vtotal: Vertical total size |
| 76 | * @flags: Bits 0-13 are the same as in the RandR protocol and also what DRM uses. |
| 77 | * The deprecated bits are reused for internal protocol flags leaving us |
| 78 | * free to follow DRM for the other bits in the future. |
| 79 | * - FLAG_PREFERRED: Set on the preferred display mode. |
| 80 | */ |
| 81 | struct gud_display_mode_req { |
| 82 | __le32 clock; |
| 83 | __le16 hdisplay; |
| 84 | __le16 hsync_start; |
| 85 | __le16 hsync_end; |
| 86 | __le16 htotal; |
| 87 | __le16 vdisplay; |
| 88 | __le16 vsync_start; |
| 89 | __le16 vsync_end; |
| 90 | __le16 vtotal; |
| 91 | __le32 flags; |
| 92 | #define GUD_DISPLAY_MODE_FLAG_PHSYNC BIT(0) |
| 93 | #define GUD_DISPLAY_MODE_FLAG_NHSYNC BIT(1) |
| 94 | #define GUD_DISPLAY_MODE_FLAG_PVSYNC BIT(2) |
| 95 | #define GUD_DISPLAY_MODE_FLAG_NVSYNC BIT(3) |
| 96 | #define GUD_DISPLAY_MODE_FLAG_INTERLACE BIT(4) |
| 97 | #define GUD_DISPLAY_MODE_FLAG_DBLSCAN BIT(5) |
| 98 | #define GUD_DISPLAY_MODE_FLAG_CSYNC BIT(6) |
| 99 | #define GUD_DISPLAY_MODE_FLAG_PCSYNC BIT(7) |
| 100 | #define GUD_DISPLAY_MODE_FLAG_NCSYNC BIT(8) |
| 101 | #define GUD_DISPLAY_MODE_FLAG_HSKEW BIT(9) |
| 102 | /* BCast and PixelMultiplex are deprecated */ |
| 103 | #define GUD_DISPLAY_MODE_FLAG_DBLCLK BIT(12) |
| 104 | #define GUD_DISPLAY_MODE_FLAG_CLKDIV2 BIT(13) |
| 105 | #define GUD_DISPLAY_MODE_FLAG_USER_MASK \ |
| 106 | (GUD_DISPLAY_MODE_FLAG_PHSYNC | GUD_DISPLAY_MODE_FLAG_NHSYNC | \ |
| 107 | GUD_DISPLAY_MODE_FLAG_PVSYNC | GUD_DISPLAY_MODE_FLAG_NVSYNC | \ |
| 108 | GUD_DISPLAY_MODE_FLAG_INTERLACE | GUD_DISPLAY_MODE_FLAG_DBLSCAN | \ |
| 109 | GUD_DISPLAY_MODE_FLAG_CSYNC | GUD_DISPLAY_MODE_FLAG_PCSYNC | \ |
| 110 | GUD_DISPLAY_MODE_FLAG_NCSYNC | GUD_DISPLAY_MODE_FLAG_HSKEW | \ |
| 111 | GUD_DISPLAY_MODE_FLAG_DBLCLK | GUD_DISPLAY_MODE_FLAG_CLKDIV2) |
| 112 | /* Internal protocol flags */ |
| 113 | #define GUD_DISPLAY_MODE_FLAG_PREFERRED BIT(10) |
| 114 | } __packed; |
| 115 | |
| 116 | /* |
| 117 | * struct gud_connector_descriptor_req - Connector descriptor |
| 118 | * @connector_type: Connector type (GUD_CONNECTOR_TYPE_*). |
| 119 | * If the host doesn't support the type it should fall back to PANEL. |
| 120 | * @flags: Flags |
| 121 | * - POLL_STATUS: Connector status can change (polled every 10 seconds) |
| 122 | * - INTERLACE: Interlaced modes are supported |
| 123 | * - DOUBLESCAN: Doublescan modes are supported |
| 124 | */ |
| 125 | struct gud_connector_descriptor_req { |
| 126 | __u8 connector_type; |
| 127 | #define GUD_CONNECTOR_TYPE_PANEL 0 |
| 128 | #define GUD_CONNECTOR_TYPE_VGA 1 |
| 129 | #define GUD_CONNECTOR_TYPE_COMPOSITE 2 |
| 130 | #define GUD_CONNECTOR_TYPE_SVIDEO 3 |
| 131 | #define GUD_CONNECTOR_TYPE_COMPONENT 4 |
| 132 | #define GUD_CONNECTOR_TYPE_DVI 5 |
| 133 | #define GUD_CONNECTOR_TYPE_DISPLAYPORT 6 |
| 134 | #define GUD_CONNECTOR_TYPE_HDMI 7 |
| 135 | __le32 flags; |
| 136 | #define GUD_CONNECTOR_FLAGS_POLL_STATUS BIT(0) |
| 137 | #define GUD_CONNECTOR_FLAGS_INTERLACE BIT(1) |
| 138 | #define GUD_CONNECTOR_FLAGS_DOUBLESCAN BIT(2) |
| 139 | } __packed; |
| 140 | |
| 141 | /* |
| 142 | * struct gud_set_buffer_req - Set buffer transfer info |
| 143 | * @x: X position of rectangle |
| 144 | * @y: Y position |
| 145 | * @width: Pixel width of rectangle |
| 146 | * @height: Pixel height |
| 147 | * @length: Buffer length in bytes |
| 148 | * @compression: Transfer compression |
| 149 | * @compressed_length: Compressed buffer length |
| 150 | * |
| 151 | * This request is issued right before the bulk transfer. |
| 152 | * @x, @y, @width and @height specifies the rectangle where the buffer should be |
| 153 | * placed inside the framebuffer. |
| 154 | */ |
| 155 | struct gud_set_buffer_req { |
| 156 | __le32 x; |
| 157 | __le32 y; |
| 158 | __le32 width; |
| 159 | __le32 height; |
| 160 | __le32 length; |
| 161 | __u8 compression; |
| 162 | __le32 compressed_length; |
| 163 | } __packed; |
| 164 | |
| 165 | /* |
| 166 | * struct gud_state_req - Display state |
| 167 | * @mode: Display mode |
| 168 | * @format: Pixel format GUD_PIXEL_FORMAT_* |
| 169 | * @connector: Connector index |
| 170 | * @properties: Array of properties |
| 171 | * |
| 172 | * The entire state is transferred each time there's a change. |
| 173 | */ |
| 174 | struct gud_state_req { |
| 175 | struct gud_display_mode_req mode; |
| 176 | __u8 format; |
| 177 | __u8 connector; |
| 178 | struct gud_property_req properties[]; |
| 179 | } __packed; |
| 180 | |
| 181 | /* List of supported connector properties: */ |
| 182 | |
| 183 | /* Margins in pixels to deal with overscan, range 0-100 */ |
| 184 | #define GUD_PROPERTY_TV_LEFT_MARGIN 1 |
| 185 | #define GUD_PROPERTY_TV_RIGHT_MARGIN 2 |
| 186 | #define GUD_PROPERTY_TV_TOP_MARGIN 3 |
| 187 | #define GUD_PROPERTY_TV_BOTTOM_MARGIN 4 |
| 188 | #define GUD_PROPERTY_TV_MODE 5 |
| 189 | /* Brightness in percent, range 0-100 */ |
| 190 | #define GUD_PROPERTY_TV_BRIGHTNESS 6 |
| 191 | /* Contrast in percent, range 0-100 */ |
| 192 | #define GUD_PROPERTY_TV_CONTRAST 7 |
| 193 | /* Flicker reduction in percent, range 0-100 */ |
| 194 | #define GUD_PROPERTY_TV_FLICKER_REDUCTION 8 |
| 195 | /* Overscan in percent, range 0-100 */ |
| 196 | #define GUD_PROPERTY_TV_OVERSCAN 9 |
| 197 | /* Saturation in percent, range 0-100 */ |
| 198 | #define GUD_PROPERTY_TV_SATURATION 10 |
| 199 | /* Hue in percent, range 0-100 */ |
| 200 | #define GUD_PROPERTY_TV_HUE 11 |
| 201 | |
| 202 | /* |
| 203 | * Backlight brightness is in the range 0-100 inclusive. The value represents the human perceptual |
| 204 | * brightness and not a linear PWM value. 0 is minimum brightness which should not turn the |
| 205 | * backlight completely off. The DPMS connector property should be used to control power which will |
| 206 | * trigger a GUD_REQ_SET_DISPLAY_ENABLE request. |
| 207 | * |
| 208 | * This does not map to a DRM property, it is used with the backlight device. |
| 209 | */ |
| 210 | #define GUD_PROPERTY_BACKLIGHT_BRIGHTNESS 12 |
| 211 | |
| 212 | /* List of supported properties that are not connector propeties: */ |
| 213 | |
| 214 | /* |
| 215 | * Plane rotation. Should return the supported bitmask on |
| 216 | * GUD_REQ_GET_PROPERTIES. GUD_ROTATION_0 is mandatory. |
| 217 | * |
| 218 | * Note: This is not display rotation so 90/270 will need scaling to make it fit (unless squared). |
| 219 | */ |
| 220 | #define GUD_PROPERTY_ROTATION 50 |
| 221 | #define GUD_ROTATION_0 BIT(0) |
| 222 | #define GUD_ROTATION_90 BIT(1) |
| 223 | #define GUD_ROTATION_180 BIT(2) |
| 224 | #define GUD_ROTATION_270 BIT(3) |
| 225 | #define GUD_ROTATION_REFLECT_X BIT(4) |
| 226 | #define GUD_ROTATION_REFLECT_Y BIT(5) |
| 227 | #define GUD_ROTATION_MASK (GUD_ROTATION_0 | GUD_ROTATION_90 | \ |
| 228 | GUD_ROTATION_180 | GUD_ROTATION_270 | \ |
| 229 | GUD_ROTATION_REFLECT_X | GUD_ROTATION_REFLECT_Y) |
| 230 | |
| 231 | /* USB Control requests: */ |
| 232 | |
| 233 | /* Get status from the last GET/SET control request. Value is u8. */ |
| 234 | #define GUD_REQ_GET_STATUS 0x00 |
| 235 | /* Status values: */ |
| 236 | #define GUD_STATUS_OK 0x00 |
| 237 | #define GUD_STATUS_BUSY 0x01 |
| 238 | #define GUD_STATUS_REQUEST_NOT_SUPPORTED 0x02 |
| 239 | #define GUD_STATUS_PROTOCOL_ERROR 0x03 |
| 240 | #define GUD_STATUS_INVALID_PARAMETER 0x04 |
| 241 | #define GUD_STATUS_ERROR 0x05 |
| 242 | |
| 243 | /* Get display descriptor as a &gud_display_descriptor_req */ |
| 244 | #define GUD_REQ_GET_DESCRIPTOR 0x01 |
| 245 | |
| 246 | /* Get supported pixel formats as a byte array of GUD_PIXEL_FORMAT_* */ |
| 247 | #define GUD_REQ_GET_FORMATS 0x40 |
| 248 | #define GUD_FORMATS_MAX_NUM 32 |
Noralf Trønnes | 4cabfed | 2021-09-29 21:11:59 +0200 | [diff] [blame] | 249 | #define GUD_PIXEL_FORMAT_R1 0x01 /* 1-bit monochrome */ |
| 250 | #define GUD_PIXEL_FORMAT_R8 0x08 /* 8-bit greyscale */ |
Noralf Trønnes | 40e1a70 | 2021-03-13 12:25:45 +0100 | [diff] [blame] | 251 | #define GUD_PIXEL_FORMAT_XRGB1111 0x20 |
Noralf Trønnes | 1f25d00 | 2021-09-29 21:12:00 +0200 | [diff] [blame] | 252 | #define GUD_PIXEL_FORMAT_RGB332 0x30 |
Noralf Trønnes | 40e1a70 | 2021-03-13 12:25:45 +0100 | [diff] [blame] | 253 | #define GUD_PIXEL_FORMAT_RGB565 0x40 |
Noralf Trønnes | 83d7b6d | 2021-09-29 21:12:01 +0200 | [diff] [blame] | 254 | #define GUD_PIXEL_FORMAT_RGB888 0x50 |
Noralf Trønnes | 40e1a70 | 2021-03-13 12:25:45 +0100 | [diff] [blame] | 255 | #define GUD_PIXEL_FORMAT_XRGB8888 0x80 |
| 256 | #define GUD_PIXEL_FORMAT_ARGB8888 0x81 |
| 257 | |
| 258 | /* |
| 259 | * Get supported properties that are not connector propeties as a &gud_property_req array. |
| 260 | * gud_property_req.val often contains the initial value for the property. |
| 261 | */ |
| 262 | #define GUD_REQ_GET_PROPERTIES 0x41 |
| 263 | #define GUD_PROPERTIES_MAX_NUM 32 |
| 264 | |
| 265 | /* Connector requests have the connector index passed in the wValue field */ |
| 266 | |
| 267 | /* Get connector descriptors as an array of &gud_connector_descriptor_req */ |
| 268 | #define GUD_REQ_GET_CONNECTORS 0x50 |
| 269 | #define GUD_CONNECTORS_MAX_NUM 32 |
| 270 | |
| 271 | /* |
| 272 | * Get properties supported by the connector as a &gud_property_req array. |
| 273 | * gud_property_req.val often contains the initial value for the property. |
| 274 | */ |
| 275 | #define GUD_REQ_GET_CONNECTOR_PROPERTIES 0x51 |
| 276 | #define GUD_CONNECTOR_PROPERTIES_MAX_NUM 32 |
| 277 | |
| 278 | /* |
| 279 | * Issued when there's a TV_MODE property present. |
| 280 | * Gets an array of the supported TV_MODE names each entry of length |
| 281 | * GUD_CONNECTOR_TV_MODE_NAME_LEN. Names must be NUL-terminated. |
| 282 | */ |
| 283 | #define GUD_REQ_GET_CONNECTOR_TV_MODE_VALUES 0x52 |
| 284 | #define GUD_CONNECTOR_TV_MODE_NAME_LEN 16 |
| 285 | #define GUD_CONNECTOR_TV_MODE_MAX_NUM 16 |
| 286 | |
| 287 | /* When userspace checks connector status, this is issued first, not used for poll requests. */ |
| 288 | #define GUD_REQ_SET_CONNECTOR_FORCE_DETECT 0x53 |
| 289 | |
| 290 | /* |
| 291 | * Get connector status. Value is u8. |
| 292 | * |
| 293 | * Userspace will get a HOTPLUG uevent if one of the following is true: |
| 294 | * - Connection status has changed since last |
| 295 | * - CHANGED is set |
| 296 | */ |
| 297 | #define GUD_REQ_GET_CONNECTOR_STATUS 0x54 |
| 298 | #define GUD_CONNECTOR_STATUS_DISCONNECTED 0x00 |
| 299 | #define GUD_CONNECTOR_STATUS_CONNECTED 0x01 |
| 300 | #define GUD_CONNECTOR_STATUS_UNKNOWN 0x02 |
| 301 | #define GUD_CONNECTOR_STATUS_CONNECTED_MASK 0x03 |
| 302 | #define GUD_CONNECTOR_STATUS_CHANGED BIT(7) |
| 303 | |
| 304 | /* |
| 305 | * Display modes can be fetched as either EDID data or an array of &gud_display_mode_req. |
| 306 | * |
| 307 | * If GUD_REQ_GET_CONNECTOR_MODES returns zero, EDID is used to create display modes. |
| 308 | * If both display modes and EDID are returned, EDID is just passed on to userspace |
| 309 | * in the EDID connector property. |
| 310 | */ |
| 311 | |
| 312 | /* Get &gud_display_mode_req array of supported display modes */ |
| 313 | #define GUD_REQ_GET_CONNECTOR_MODES 0x55 |
| 314 | #define GUD_CONNECTOR_MAX_NUM_MODES 128 |
| 315 | |
| 316 | /* Get Extended Display Identification Data */ |
| 317 | #define GUD_REQ_GET_CONNECTOR_EDID 0x56 |
| 318 | #define GUD_CONNECTOR_MAX_EDID_LEN 2048 |
| 319 | |
| 320 | /* Set buffer properties before bulk transfer as &gud_set_buffer_req */ |
| 321 | #define GUD_REQ_SET_BUFFER 0x60 |
| 322 | |
| 323 | /* Check display configuration as &gud_state_req */ |
| 324 | #define GUD_REQ_SET_STATE_CHECK 0x61 |
| 325 | |
| 326 | /* Apply the previous STATE_CHECK configuration */ |
| 327 | #define GUD_REQ_SET_STATE_COMMIT 0x62 |
| 328 | |
| 329 | /* Enable/disable the display controller, value is u8: 0/1 */ |
| 330 | #define GUD_REQ_SET_CONTROLLER_ENABLE 0x63 |
| 331 | |
| 332 | /* Enable/disable display/output (DPMS), value is u8: 0/1 */ |
| 333 | #define GUD_REQ_SET_DISPLAY_ENABLE 0x64 |
| 334 | |
| 335 | #endif |