162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * description of display timings
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef __LINUX_DISPLAY_TIMING_H
962306a36Sopenharmony_ci#define __LINUX_DISPLAY_TIMING_H
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/bitops.h>
1262306a36Sopenharmony_ci#include <linux/types.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cienum display_flags {
1562306a36Sopenharmony_ci	DISPLAY_FLAGS_HSYNC_LOW		= BIT(0),
1662306a36Sopenharmony_ci	DISPLAY_FLAGS_HSYNC_HIGH	= BIT(1),
1762306a36Sopenharmony_ci	DISPLAY_FLAGS_VSYNC_LOW		= BIT(2),
1862306a36Sopenharmony_ci	DISPLAY_FLAGS_VSYNC_HIGH	= BIT(3),
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci	/* data enable flag */
2162306a36Sopenharmony_ci	DISPLAY_FLAGS_DE_LOW		= BIT(4),
2262306a36Sopenharmony_ci	DISPLAY_FLAGS_DE_HIGH		= BIT(5),
2362306a36Sopenharmony_ci	/* drive data on pos. edge */
2462306a36Sopenharmony_ci	DISPLAY_FLAGS_PIXDATA_POSEDGE	= BIT(6),
2562306a36Sopenharmony_ci	/* drive data on neg. edge */
2662306a36Sopenharmony_ci	DISPLAY_FLAGS_PIXDATA_NEGEDGE	= BIT(7),
2762306a36Sopenharmony_ci	DISPLAY_FLAGS_INTERLACED	= BIT(8),
2862306a36Sopenharmony_ci	DISPLAY_FLAGS_DOUBLESCAN	= BIT(9),
2962306a36Sopenharmony_ci	DISPLAY_FLAGS_DOUBLECLK		= BIT(10),
3062306a36Sopenharmony_ci	/* drive sync on pos. edge */
3162306a36Sopenharmony_ci	DISPLAY_FLAGS_SYNC_POSEDGE	= BIT(11),
3262306a36Sopenharmony_ci	/* drive sync on neg. edge */
3362306a36Sopenharmony_ci	DISPLAY_FLAGS_SYNC_NEGEDGE	= BIT(12),
3462306a36Sopenharmony_ci};
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/*
3762306a36Sopenharmony_ci * A single signal can be specified via a range of minimal and maximal values
3862306a36Sopenharmony_ci * with a typical value, that lies somewhere inbetween.
3962306a36Sopenharmony_ci */
4062306a36Sopenharmony_cistruct timing_entry {
4162306a36Sopenharmony_ci	u32 min;
4262306a36Sopenharmony_ci	u32 typ;
4362306a36Sopenharmony_ci	u32 max;
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/*
4762306a36Sopenharmony_ci * Single "mode" entry. This describes one set of signal timings a display can
4862306a36Sopenharmony_ci * have in one setting. This struct can later be converted to struct videomode
4962306a36Sopenharmony_ci * (see include/video/videomode.h). As each timing_entry can be defined as a
5062306a36Sopenharmony_ci * range, one struct display_timing may become multiple struct videomodes.
5162306a36Sopenharmony_ci *
5262306a36Sopenharmony_ci * Example: hsync active high, vsync active low
5362306a36Sopenharmony_ci *
5462306a36Sopenharmony_ci *				    Active Video
5562306a36Sopenharmony_ci * Video  ______________________XXXXXXXXXXXXXXXXXXXXXX_____________________
5662306a36Sopenharmony_ci *	  |<- sync ->|<- back ->|<----- active ----->|<- front ->|<- sync..
5762306a36Sopenharmony_ci *	  |	     |	 porch  |		     |	 porch	 |
5862306a36Sopenharmony_ci *
5962306a36Sopenharmony_ci * HSync _|¯¯¯¯¯¯¯¯¯¯|___________________________________________|¯¯¯¯¯¯¯¯¯
6062306a36Sopenharmony_ci *
6162306a36Sopenharmony_ci * VSync ¯|__________|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_________
6262306a36Sopenharmony_ci */
6362306a36Sopenharmony_cistruct display_timing {
6462306a36Sopenharmony_ci	struct timing_entry pixelclock;
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	struct timing_entry hactive;		/* hor. active video */
6762306a36Sopenharmony_ci	struct timing_entry hfront_porch;	/* hor. front porch */
6862306a36Sopenharmony_ci	struct timing_entry hback_porch;	/* hor. back porch */
6962306a36Sopenharmony_ci	struct timing_entry hsync_len;		/* hor. sync len */
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	struct timing_entry vactive;		/* ver. active video */
7262306a36Sopenharmony_ci	struct timing_entry vfront_porch;	/* ver. front porch */
7362306a36Sopenharmony_ci	struct timing_entry vback_porch;	/* ver. back porch */
7462306a36Sopenharmony_ci	struct timing_entry vsync_len;		/* ver. sync len */
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	enum display_flags flags;		/* display flags */
7762306a36Sopenharmony_ci};
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci/*
8062306a36Sopenharmony_ci * This describes all timing settings a display provides.
8162306a36Sopenharmony_ci * The native_mode is the default setting for this display.
8262306a36Sopenharmony_ci * Drivers that can handle multiple videomodes should work with this struct and
8362306a36Sopenharmony_ci * convert each entry to the desired end result.
8462306a36Sopenharmony_ci */
8562306a36Sopenharmony_cistruct display_timings {
8662306a36Sopenharmony_ci	unsigned int num_timings;
8762306a36Sopenharmony_ci	unsigned int native_mode;
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	struct display_timing **timings;
9062306a36Sopenharmony_ci};
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci/* get one entry from struct display_timings */
9362306a36Sopenharmony_cistatic inline struct display_timing *display_timings_get(const struct
9462306a36Sopenharmony_ci							 display_timings *disp,
9562306a36Sopenharmony_ci							 unsigned int index)
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	if (disp->num_timings > index)
9862306a36Sopenharmony_ci		return disp->timings[index];
9962306a36Sopenharmony_ci	else
10062306a36Sopenharmony_ci		return NULL;
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_civoid display_timings_release(struct display_timings *disp);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci#endif
106