^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * description of display timings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifndef __LINUX_DISPLAY_TIMING_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define __LINUX_DISPLAY_TIMING_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) enum display_flags {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) DISPLAY_FLAGS_HSYNC_LOW = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) DISPLAY_FLAGS_HSYNC_HIGH = BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) DISPLAY_FLAGS_VSYNC_LOW = BIT(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) DISPLAY_FLAGS_VSYNC_HIGH = BIT(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* data enable flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) DISPLAY_FLAGS_DE_LOW = BIT(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) DISPLAY_FLAGS_DE_HIGH = BIT(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* drive data on pos. edge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) DISPLAY_FLAGS_PIXDATA_POSEDGE = BIT(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* drive data on neg. edge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) DISPLAY_FLAGS_PIXDATA_NEGEDGE = BIT(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) DISPLAY_FLAGS_INTERLACED = BIT(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) DISPLAY_FLAGS_DOUBLESCAN = BIT(9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) DISPLAY_FLAGS_DOUBLECLK = BIT(10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* drive sync on pos. edge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) DISPLAY_FLAGS_SYNC_POSEDGE = BIT(11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* drive sync on neg. edge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) DISPLAY_FLAGS_SYNC_NEGEDGE = BIT(12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * A single signal can be specified via a range of minimal and maximal values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * with a typical value, that lies somewhere inbetween.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct timing_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) u32 min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u32 typ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u32 max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Single "mode" entry. This describes one set of signal timings a display can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * have in one setting. This struct can later be converted to struct videomode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * (see include/video/videomode.h). As each timing_entry can be defined as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * range, one struct display_timing may become multiple struct videomodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Example: hsync active high, vsync active low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Active Video
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Video ______________________XXXXXXXXXXXXXXXXXXXXXX_____________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * |<- sync ->|<- back ->|<----- active ----->|<- front ->|<- sync..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * | | porch | | porch |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * HSync _|¯¯¯¯¯¯¯¯¯¯|___________________________________________|¯¯¯¯¯¯¯¯¯
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * VSync ¯|__________|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct display_timing {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct timing_entry pixelclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct timing_entry hactive; /* hor. active video */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct timing_entry hfront_porch; /* hor. front porch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct timing_entry hback_porch; /* hor. back porch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct timing_entry hsync_len; /* hor. sync len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct timing_entry vactive; /* ver. active video */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct timing_entry vfront_porch; /* ver. front porch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct timing_entry vback_porch; /* ver. back porch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct timing_entry vsync_len; /* ver. sync len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) enum display_flags flags; /* display flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * This describes all timing settings a display provides.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * The native_mode is the default setting for this display.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * Drivers that can handle multiple videomodes should work with this struct and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * convert each entry to the desired end result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct display_timings {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned int num_timings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned int native_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct display_timing **timings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* get one entry from struct display_timings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static inline struct display_timing *display_timings_get(const struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) display_timings *disp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (disp->num_timings > index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return disp->timings[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void display_timings_release(struct display_timings *disp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #endif