1
1
Форкнуть 0

Драйвер devg-[vesabios/vpoutfb].so для ЗОСРВ "Нейтрино" редакции 2020

Этот коммит содержится в:
Коммит 3d848c272c
57 изменённых файлов: 9486 добавлений и 0 удалений

2
Makefile Обычный файл
Просмотреть файл

@ -0,0 +1,2 @@
LIST=DRIVERS
include recurse.mk

68
README.md Обычный файл
Просмотреть файл

@ -0,0 +1,68 @@
## Общая структура графического драйвера
```
┌───────────────────────────┐
│ │
│ Контроллер дисплеев │
│ │
└─────────────▴─────────────┘
┌─────────────┴─────────────┐
│ │
│ Графический драйвер │
│ (devg-*) │
│ │
└─────────────▴─────────────┘
*
┌─────────────┴─────────────┐ ┌───────────────────────────┐
│ │ │ │
│ Менеджер io-display ◂─── * ───┤ Клиентское приложение │
│ │ │ │
└───────────────────────────┘ ▲ └───────────────────────────┘
Интерфейс libgf ───────┘
```
## Дерево исходных кодов
```
|- devg/devnp/
| |- lib/ - Вспомогательные библиотеки
| |- private/ - Приватные хедеры графической подсистемы
| |- public/ - Публичные хедеры графической подсистемы
| |- vesabios/ - Исходный код универсального драйвера контроллера дисплеев (группа стандартов VESA)
| |- vpoutfb/ - Исходный код драйвера контроллера дисплеев для Элвис 1892ВМ14Я (ARMv7 SoC)
| |- common.mk - Параметры сборки драйверов
| `- Makefile - Правила сборки дерева исходников
|
`- Makefile - Правила сборки дерева исходников
```
## Сборка драйвера
- Установить и настроить [комплект разработчика](https://help.kpda.ru/help/topic/ru.kpda.doc.dev_tools_ru/html/devkit/devkit.html) для [ЗОСРВ "Нейтрино" редакции 2020](https://help.kpda.ru/help/index.jsp).
- Выполнить команду:
```
make
```
## Запуск драйвера
Общая схема запуска драйвера:
```
io-display -dvid=0x0,did=0x0
```
Особенности запуска и настройки графических драйверов представлены в статье [Настройка графической подсистемы](https://help.kpda.ru/help/topic/ru.kpda.doc.graphics_ru/html/user_guide/guide/configuration.html).

3
devg/Makefile Обычный файл
Просмотреть файл

@ -0,0 +1,3 @@
EARLY_DIRS=lib
LIST=DEVG
include recurse.mk

107
devg/common.mk Обычный файл
Просмотреть файл

@ -0,0 +1,107 @@
#
# (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
#
ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)
define PINFO
PINFO DESCRIPTION=
endef
EXTRA_SILENT_VARIANTS = $(subst -, ,$(SECTION))
ifeq ($(NAME),)
NAME=$(PROJECT)-$(SECTION)
endif
CCVFLAG_fixed=-DDISP_FIXED_POINT
DEVGDRVROOT=$(shell $(PWD_HOST) | sed 's!\/devg.*!\/devg!')/$(shell $(PWD_HOST) | sed 's!.*\/devg[^\/]*\/!!' | sed 's!\/.*!!')
include $(MKFILES_ROOT)/qmacros.mk
-include $(PROJECT_ROOT)/roots.mk
#
# Set this as the default, each devg's pinfo.mk can override if needed.
#
SHARED_LIBS=ffb disputilS
include $(PROJECT_ROOT)/$(SECTION)/pinfo.mk
USEFILE := ../../../$(SECTION).use
CONFIG_PATH := $(PROJECT_ROOT)/$(SECTION)/config
#EXTRA_INCVPATH += $(if $(USE_INSTALL_ROOT),$(INSTALL_ROOT_$(OS)),$(USE_ROOT_$(OS)))/usr/include/graphics
EXTRA_INCVPATH += $(PROJECT_ROOT)/public/graphics
EXTRA_INCVPATH += $(PROJECT_ROOT)/public
EXTRA_INCVPATH += $(PROJECT_ROOT)/private
EXTRA_INCVPATH += $(PROJECT_ROOT)/private/drm
EXTRA_INCVPATH += $(PROJECT_ROOT)/private/linux
EXTRA_INCVPATH += $(PROJECT_ROOT)/private/linux/include
EXTRA_INCVPATH += $(PROJECT_ROOT)/private/linux/include/uapi
EXTRA_INCVPATH += $(PROJECT_ROOT)/private/linux/arch/$(CPU)
EXTRA_INCVPATH += $(PROJECT_ROOT)/private/linux/arch/$(CPU)/include
EXTRA_INCVPATH += $(PROJECT_ROOT)/private/linux/arch/$(CPU)/include/uapi
ifneq ($(OS), qnx4)
ifneq ($(COMPOUND_VARIANT),dll)
ifneq ($(COMPOUND_VARIANT),dll.g)
SHARED_LIBDIR = $(OS)/$(CPU)/so.$(patsubst dll.%,%,$(COMPOUND_VARIANT))
STATIC_LIBDIR = $(OS)/$(CPU)/a.shared.$(patsubst dll.%,%,$(COMPOUND_VARIANT))
else
SHARED_LIBDIR = $(OS)/$(CPU)/so.g
STATIC_LIBDIR = $(OS)/$(CPU)/a.shared.g
endif
else
SHARED_LIBDIR = $(OS)/$(CPU)/so
STATIC_LIBDIR = $(OS)/$(CPU)/a.shared
endif
-include $(DEVGDRVROOT)/extrasrc.mk
-include $(DEVGDRVROOT)/driver.mk
include $(MKFILES_ROOT)/qtargets.mk
ifeq ($(origin NDEBUG),undefined)
CCFLAGS += -O0
else
CCFLAGS += -fomit-frame-pointer
endif
CCFLAGS += -Wno-switch
else # qnx4
ifneq ($(COMPOUND_VARIANT), a.g)
SHARED_LIBDIR = $(OS)/$(CPU)/a
STATIC_LIBDIR = $(OS)/$(CPU)/a
SHARED_LIBS += iographics photon3r $(QNX4_LIBS)
else
SHARED_LIBDIR = $(OS)/$(CPU)/a.g
STATIC_LIBDIR = $(OS)/$(CPU)/a.g
SHARED_LIBS += iographics photon3r $(QNX4_LIBS)
endif
SHARED_LIBS += $(QNX4_LIBS)
LDFLAGS += -T1
CCFLAGS += -Otax -D__X86__ -D__LITTLEENDIAN__
endif
ifeq ($(origin NDEBUG),undefined)
ifeq ($(OS), qnx4)
LIBS += $(foreach lib, $(STATIC_LIBS), $(lib)S) $(SHARED_LIBS)
else
LIBS += $(foreach lib, $(STATIC_LIBS), $(lib)S_g) $(foreach lib, $(SHARED_LIBS), $(lib)_g)
endif
else
LIBS += $(foreach lib, $(STATIC_LIBS), $(lib)S) $(SHARED_LIBS)
endif
WIN32_ENVIRON=mingw
ifeq "$(findstring e2k,$(CPU))" "e2k"
CCFLAGS += -D__DEF_BELOW4G_TMEM__=\"/below4G/ram\"
CCFLAGS += -fcontrol-spec
endif

Двоичные данные
devg/lib/drmhelper/nto/arm/a.shared.le.v7/libdrmhelperS.a Обычный файл

Двоичный файл не отображается.

251
devg/private/drm/drm_edid.h Обычный файл
Просмотреть файл

@ -0,0 +1,251 @@
/*
* Copyright © 2007-2008 Intel Corporation
* Jesse Barnes <jesse.barnes@intel.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __DRM_EDID_H__
#define __DRM_EDID_H__
#ifdef __QNX__
#ifdef __QNXNTO__
/* Pack all structures */
#include <_pack1.h>
#else
#pragma pack (1)
#endif
#endif
#define EDID_LENGTH 128
#define DDC_ADDR 0x50
#define DDC_ADDR2 0x52 /* E-DDC 1.2 - where DisplayID can hide */
#define CEA_EXT 0x02
#define VTB_EXT 0x10
#define DI_EXT 0x40
#define LS_EXT 0x50
#define MI_EXT 0x60
#define DISPLAYID_EXT 0x70
struct est_timings {
uint8_t t1;
uint8_t t2;
uint8_t mfg_rsvd;
};
/* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */
#define EDID_TIMING_ASPECT_SHIFT 6
#define EDID_TIMING_ASPECT_MASK (0x3 << EDID_TIMING_ASPECT_SHIFT)
/* need to add 60 */
#define EDID_TIMING_VFREQ_SHIFT 0
#define EDID_TIMING_VFREQ_MASK (0x3f << EDID_TIMING_VFREQ_SHIFT)
struct std_timing {
uint8_t hsize; /* need to multiply by 8 then add 248 */
uint8_t vfreq_aspect;
};
#define DRM_EDID_PT_HSYNC_POSITIVE (1 << 1)
#define DRM_EDID_PT_VSYNC_POSITIVE (1 << 2)
#define DRM_EDID_PT_SEPARATE_SYNC (3 << 3)
#define DRM_EDID_PT_STEREO (1 << 5)
#define DRM_EDID_PT_INTERLACED (1 << 7)
/* If detailed data is pixel timing */
struct detailed_pixel_timing {
uint8_t hactive_lo;
uint8_t hblank_lo;
uint8_t hactive_hblank_hi;
uint8_t vactive_lo;
uint8_t vblank_lo;
uint8_t vactive_vblank_hi;
uint8_t hsync_offset_lo;
uint8_t hsync_pulse_width_lo;
uint8_t vsync_offset_pulse_width_lo;
uint8_t hsync_vsync_offset_pulse_width_hi;
uint8_t width_mm_lo;
uint8_t height_mm_lo;
uint8_t width_height_mm_hi;
uint8_t hborder;
uint8_t vborder;
uint8_t misc;
};
/* If it's not pixel timing, it'll be one of the below */
struct detailed_data_string {
uint8_t str[13];
};
struct detailed_data_monitor_range {
uint8_t min_vfreq;
uint8_t max_vfreq;
uint8_t min_hfreq_khz;
uint8_t max_hfreq_khz;
uint8_t pixel_clock_mhz; /* need to multiply by 10 */
uint8_t flags;
union {
struct {
uint8_t reserved;
uint8_t hfreq_start_khz; /* need to multiply by 2 */
uint8_t c; /* need to divide by 2 */
uint16_t m;
uint8_t k;
uint8_t j; /* need to divide by 2 */
} gtf2;
struct {
uint8_t version;
uint8_t data1; /* high 6 bits: extra clock resolution */
uint8_t data2; /* plus low 2 of above: max hactive */
uint8_t supported_aspects;
uint8_t flags; /* preferred aspect and blanking support */
uint8_t supported_scalings;
uint8_t preferred_refresh;
} cvt;
} formula;
};
struct detailed_data_wpindex {
uint8_t white_yx_lo; /* Lower 2 bits each */
uint8_t white_x_hi;
uint8_t white_y_hi;
uint8_t gamma; /* need to divide by 100 then add 1 */
};
struct detailed_data_color_point {
uint8_t windex1;
uint8_t wpindex1[3];
uint8_t windex2;
uint8_t wpindex2[3];
};
struct cvt_timing {
uint8_t code[3];
};
struct detailed_non_pixel {
uint8_t pad1;
uint8_t type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name
fb=color point data, fa=standard timing data,
f9=undefined, f8=mfg. reserved */
uint8_t pad2;
union {
struct detailed_data_string str;
struct detailed_data_monitor_range range;
struct detailed_data_wpindex color;
struct std_timing timings[6];
struct cvt_timing cvt[4];
} data;
};
#define EDID_DETAIL_EST_TIMINGS 0xf7
#define EDID_DETAIL_CVT_3BYTE 0xf8
#define EDID_DETAIL_COLOR_MGMT_DATA 0xf9
#define EDID_DETAIL_STD_MODES 0xfa
#define EDID_DETAIL_MONITOR_CPDATA 0xfb
#define EDID_DETAIL_MONITOR_NAME 0xfc
#define EDID_DETAIL_MONITOR_RANGE 0xfd
#define EDID_DETAIL_MONITOR_STRING 0xfe
#define EDID_DETAIL_MONITOR_SERIAL 0xff
struct detailed_timing {
uint16_t pixel_clock; /* need to multiply by 10 KHz */
union {
struct detailed_pixel_timing pixel_data;
struct detailed_non_pixel other_data;
} data;
};
#define DRM_EDID_INPUT_SERRATION_VSYNC (1 << 0)
#define DRM_EDID_INPUT_SYNC_ON_GREEN (1 << 1)
#define DRM_EDID_INPUT_COMPOSITE_SYNC (1 << 2)
#define DRM_EDID_INPUT_SEPARATE_SYNCS (1 << 3)
#define DRM_EDID_INPUT_BLANK_TO_BLACK (1 << 4)
#define DRM_EDID_INPUT_VIDEO_LEVEL (3 << 5)
#define DRM_EDID_INPUT_DIGITAL (1 << 7)
struct edid {
uint8_t header[8];
/* Vendor & product info */
uint8_t mfg_id[2];
uint8_t prod_code[2];
uint32_t serial; /* FIXME: byte order */
uint8_t mfg_week;
uint8_t mfg_year;
/* EDID version */
uint8_t version;
uint8_t revision;
/* Display info: */
uint8_t input;
uint8_t width_cm;
uint8_t height_cm;
uint8_t gamma;
uint8_t features;
/* Color characteristics */
uint8_t red_green_lo;
uint8_t black_white_lo;
uint8_t red_x;
uint8_t red_y;
uint8_t green_x;
uint8_t green_y;
uint8_t blue_x;
uint8_t blue_y;
uint8_t white_x;
uint8_t white_y;
/* Est. timings and mfg rsvd timings*/
struct est_timings established_timings;
/* Standard timings 1-8*/
struct std_timing standard_timings[8];
/* Detailing timings 1-4 */
struct detailed_timing detailed_timings[4];
/* Number of 128 byte ext. blocks */
uint8_t extensions;
/* Checksum */
uint8_t checksum;
};
struct drm_encoder;
struct drm_connector;
struct drm_display_mode;
struct hdmi_avi_infoframe;
struct hdmi_vendor_infoframe;
struct i2c_adapter;
struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter);
struct edid *drm_get_edid_size( struct drm_connector *connector, struct i2c_adapter *adapter, int size );
struct edid *drm_edid_duplicate(const struct edid *edid);
uint8_t drm_match_cea_mode(const struct drm_display_mode *to_match);
enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const uint8_t video_code);
bool drm_detect_hdmi_monitor(struct edid *edid);
int drm_hdmi_avi_infoframe_from_display_mode( struct hdmi_avi_infoframe *frame, const struct drm_display_mode *mode);
int drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, const struct drm_display_mode *mode);
bool drm_edid_is_valid(struct edid *edid);
#ifdef __QNX__
#ifdef __QNXNTO__
#include <_packpop.h>
#else
#pragma pack ()
#endif
#endif
#endif /* __DRM_EDID_H__ */

758
devg/public/graphics/3d.h Обычный файл
Просмотреть файл

@ -0,0 +1,758 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/* KPDA has no driver-dependent GLES headers */
#if 0
#ifndef _GRAPHICS_3D_H_INCLUDED
#define _GRAPHICS_3D_H_INCLUDED
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#include <graphics/display.h>
#endif
#ifndef _GLES_GL_H_INCLUDED
#include <GLES/gl.h>
#endif
#ifndef _GLES_GLEXT_H_INCLUDED
#include <GLES/glext.h>
#endif
#ifndef _GRAPHICS_REND_H_INCLUDED
#include <graphics/rend.h>
#endif
/* Sizes of the matrix stacks */
#define DISP_3D_MODEL_MATRIX_ENTRIES 16
#define DISP_3D_PROJ_MATRIX_ENTRIES 2
#define DISP_3D_TEX_MATRIX_ENTRIES 2
/* Max supported lights */
#define DISP_3D_NUM_LIGHTS 8
/* Max supported texture mapping units */
#define DISP_3D_MAX_TMUS 4
/* Max supported texture dimensions */
#define DISP_3D_MAX_TEXTURE_SIZE 2048
#define DISP_3D_LOG2_MAX_TEXTURE_SIZE 11
#define __MKFMT(__bpp, __id) ((__id) | (__bpp)<<24)
#define DISP_TEX_BITS_PER_PIXEL(__fmt) ((__fmt)>>24)
#define DISP_TEXFORMAT_UNDEFINED 0
#define DISP_TEXFORMAT_RGBA8888 __MKFMT(32, 1)
#define DISP_TEXFORMAT_RGB888 __MKFMT(24, 2)
#define DISP_TEXFORMAT_PK_RGBA4444 __MKFMT(16, 3)
#define DISP_TEXFORMAT_PK_ARGB4444 __MKFMT(16, 4)
#define DISP_TEXFORMAT_PK_RGBA5551 __MKFMT(16, 5)
#define DISP_TEXFORMAT_PK_RGB565 __MKFMT(16, 6)
#define DISP_TEXFORMAT_PKOE_RGBA4444 __MKFMT(16, 7)
#define DISP_TEXFORMAT_PKOE_ARGB4444 __MKFMT(16, 8)
#define DISP_TEXFORMAT_PKOE_RGB565 __MKFMT(16, 9)
#define DISP_TEXFORMAT_LA88 __MKFMT(16, 10)
#define DISP_TEXFORMAT_L8 __MKFMT(8, 11)
#define DISP_TEXFORMAT_A8 __MKFMT(8, 12)
#define DISP_TEXFORMAT_PAL8_RGB888 __MKFMT(8, 13)
#define DISP_TEXFORMAT_PAL8_RGBA8888 __MKFMT(8, 14)
#define DISP_TEXFORMAT_PAL4_RGB888 __MKFMT(4, 15)
#define DISP_TEXFORMAT_PAL4_RGBA8888 __MKFMT(4, 16)
#define DISP_TEXFORMAT_ARGB8888 __MKFMT(32, 17)
#define DISP_TEXFORMAT_PK_ARGB1555 __MKFMT(16, 18)
#define DISP_TEXFORMAT_PK_XRGB1555 __MKFMT(16, 19)
#define DISP_TEXFORMAT_PKOE_ARGB1555 __MKFMT(16, 20)
#define DISP_TEXFORMAT_PKOE_XRGB1555 __MKFMT(16, 21)
#define DISP_TEXFORMAT_BGR888 __MKFMT(24, 22)
#define DISP_TEXFORMAT_BGRA8888 __MKFMT(32, 23)
#define DISP_TEXFORMAT_PKOE_RGBA5551 __MKFMT(16, 24)
#define DISP_TEXFORMAT_ABGR8888 __MKFMT(32, 25)
#define DISP_TEXFORMAT_AL88 __MKFMT(16, 26)
/* Fujitsu proprietary compression */
#define DISP_TEXFORMAT_FJCMP_RGBA5551 __MKFMT(16, 27)
#define DISP_TEXFORMAT_FJCMP_RGBA8888 __MKFMT(32, 28)
/* PRVTC compression */
#define DISP_TEXFORMAT_PVRTC_RGB_4BPPV1 __MKFMT(4, 29)
#define DISP_TEXFORMAT_PVRTC_RGB_2BPPV1 __MKFMT(2, 30)
#define DISP_TEXFORMAT_PVRTC_RGBA_4BPPV1 __MKFMT(4, 31)
#define DISP_TEXFORMAT_PVRTC_RGBA_2BPPV1 __MKFMT(2, 32)
/* Only valid when indicating a preferred internal texture format */
#define DISP_TEXFORMAT_RGB_ANY 100
#define DISP_TEXFORMAT_RGBA_ANY 101
#define DISP_3D_STATE_MODELMATRIX 0x00000001
#define DISP_3D_STATE_PROJMATRIX 0x00000002
#define DISP_3D_STATE_TEXMATRIX 0x00000004
#define DISP_3D_STATE_NORMAL 0x00000008
#define DISP_3D_STATE_DEPTH_RANGE 0x00000010
#define DISP_3D_STATE_SHADING 0x00000020
#define DISP_3D_STATE_DEPTH 0x00000040
#define DISP_3D_STATE_ALPHA_TEST 0x00000080
#define DISP_3D_STATE_BLEND 0x00000100
#define DISP_3D_STATE_STENCIL 0x00000200
#define DISP_3D_STATE_LOGIC_OP 0x00000400
#define DISP_3D_STATE_FOG 0x00000800
#define DISP_3D_STATE_TMU 0x00001000
#define DISP_3D_STATE_COLORMASK 0x00002000
#define DISP_3D_STATE_POLYGON_OFFSET 0x00004000
#define DISP_3D_STATE_VIEWPORT 0x00008000
#define DISP_3D_STATE_CULLFACE 0x00010000
#define DISP_3D_STATE_SCISSOR 0x00020000
#define DISP_3D_STATE_LIGHT 0x00040000
#define DISP_3D_STATE_FLAGS 0x00080000
#define DISP_3D_STATE_ANTIALIAS 0x00100000
#define DISP_3D_STATE_POINT 0x00200000
#define DISP_3D_STATE_LINE 0x00400000
#define DISP_3D_STATE_FSOPS 0x00800000
/* Global light state */
#define DISP_3D_LIGHT_STATE_TWO_SIDE 0x00000001
#define DISP_3D_LIGHT_STATE_AMBIENT 0x00000002
#define DISP_3D_LIGHT_STATE_MAT_AMBIENT 0x00000004
#define DISP_3D_LIGHT_STATE_MAT_DIFFUSE 0x00000008
#define DISP_3D_LIGHT_STATE_MAT_SPECULAR 0x00000010
#define DISP_3D_LIGHT_STATE_MAT_EMISSION 0x00000020
#define DISP_3D_LIGHT_STATE_MAT_SHININESS 0x00000040
#define DISP_3D_LIGHT_STATE_COLOR_MATERIAL 0x00000080
/* Per-light state */
#define DISP_3D_PER_LIGHT_STATE_AMBIENT 0x00000001
#define DISP_3D_PER_LIGHT_STATE_DIFFUSE 0x00000002
#define DISP_3D_PER_LIGHT_STATE_SPECULAR 0x00000004
#define DISP_3D_PER_LIGHT_STATE_POSITION 0x00000008
#define DISP_3D_PER_LIGHT_STATE_SPOT_DIRECTION 0x00000010
#define DISP_3D_PER_LIGHT_STATE_SPOT_EXPONENT 0x00000020
#define DISP_3D_PER_LIGHT_STATE_SPOT_CUTOFF 0x00000040
#define DISP_3D_PER_LIGHT_STATE_CONSTANT_ATTENUATION 0x00000080
#define DISP_3D_PER_LIGHT_STATE_LINEAR_ATTENUATION 0x00000100
#define DISP_3D_PER_LIGHT_STATE_QUADRATIC_ATTENUATION 0x00000200
/* Buffer objects */
#define DISP_3D_BUFOBJ_NONE 0x00000000
#define DISP_3D_BUFOBJ_VERTEX 0x00000001
#define DISP_3D_BUFOBJ_COLOR 0x00000002
#define DISP_3D_BUFOBJ_NORMAL 0x00000004
#define DISP_3D_BUFOBJ_TEXCOORD0 0x00000008
#define DISP_3D_BUFOBJ_TEXCOORD1 0x00000010
#define DISP_3D_BUFOBJ_TEXCOORD2 0x00000020
#define DISP_3D_BUFOBJ_TEXCOORD3 0x00000040
#define DISP_3D_BUFOBJ_INDICES 0x00010000
/* Datatypes for data in buffer objects */
#define DISP_3D_DATATYPE_NONE 0x00000000
#define DISP_3D_DATATYPE_CHAR 0x00000001
#define DISP_3D_DATATYPE_UCHAR 0x00000002
#define DISP_3D_DATATYPE_SHORT 0x00000003
#define DISP_3D_DATATYPE_USHORT 0x00000004
#define DISP_3D_DATATYPE_FIXED32 0x00000005
#define DISP_3D_DATATYPE_FLOAT32 0x00000006
/* For specifying how primitive information will be sent to driver */
typedef enum {
DISP_3D_SEND_OBJECT_COORDS = 0x00000001, /* Send vertices in Object/World coordinates */
DISP_3D_SEND_LIT_EYE_COORDS = 0x00000002, /* Send vertices in Eye coordinates, after lighting */
DISP_3D_SEND_CLIPPED_PRIMS = 0x00000004, /* Send clipped primitives */
DISP_3D_SEND_SPANS = 0x00000010, /* Render primitives as a series of spans */
} disp_3d_send_type;
/* Actions to be taken on vertices before sending to driver */
typedef enum {
DISP_3D_PRIMSTATE_XFORM_TEX = 0x00000001, /* Multiply texture coordinates by current texture matrix */
DISP_3D_PRIMSTATE_DIV_BY_W = 0x00000002, /* Perform division by W (clipped primitives only) */
DISP_3D_PRIMSTATE_VP_XLATE = 0x00000004, /* Translate to viewport coordinates (clipped primitives only) */
} disp_3d_primstate_flag;
typedef enum {
DISP_3D_DATA_COORDS, /* X, Y, Z, W */
DISP_3D_DATA_NORMAL, /* X, Y, Z */
DISP_3D_DATA_RGBA, /* R, G, B, A */
DISP_3D_DATA_STRQ0, /* S, T, R, Q */
DISP_3D_DATA_STRQ1, /* S, T, R, Q */
DISP_3D_DATA_STRQ2, /* S, T, R, Q */
DISP_3D_DATA_STRQ3, /* S, T, R, Q */
DISP_3D_DATA_FOG, /* Fog distance */
} disp_3d_data_type;
typedef enum {
DISP_3D_CTX_FLAG_USE_VTXCOLOR = 0x00000001,
DISP_3D_CTX_FLAG_USE_VTXNORM = 0x00000002,
DISP_3D_CTX_FLAG_PRIM_USE_VTXCOLOR = 0x00000004
} disp_3d_ctx_flag;
/* Driver may set these flags when processing Lit Eye Co-ordinates, if it
* determines that it can't process the specified primitives correctly.
* For example, the driver may be able to render triangle strips and
* fans etc., but cannot handle the case where vertices are outside of the
* far or near clipping planes.
*/
typedef enum {
DISP_3D_PCTL_FLAG_LEC_FBACK_MM_CP = 0x00000001, /* Matrix multiplication still needs to be performed on the vertices, and the driver is prepared to accept clipped primitives */
DISP_3D_PCTL_FLAG_LEC_FBACK_CP = 0x00000002, /* The driver is prepared to accept clipped primitives */
DISP_3D_PCTL_FLAG_LEC_FBACK_MM_SPANS = 0x00000004, /* Matrix multiplication still needs to be performed on the vertices, and the driver can only accept spans */
DISP_3D_PCTL_FLAG_LEC_FBACK_SPANS = 0x00000008, /* The driver can only accept spans */
} disp_3d_pctl_flag;
#define DISP_3D_PCTL_FLAG_LEC_FBACK_MASK \
(DISP_3D_PCTL_FLAG_LEC_FBACK_MM_CP | \
DISP_3D_PCTL_FLAG_LEC_FBACK_CP | \
DISP_3D_PCTL_FLAG_LEC_FBACK_MM_SPANS | \
DISP_3D_PCTL_FLAG_LEC_FBACK_SPANS)
typedef enum {
DISP_3D_MATRIX_FLAG_IS_IDENTITY = 0x00000001,
} disp_3d_matrix_flag;
/* Defines for "flags" argument to prim_begin() */
#define DISP_3D_VTX_FLAG_DFLT_Z 0x00000001
#define DISP_3D_VTX_FLAG_DFLT_W 0x00000002
#define DISP_3D_VTX_FLAG_DFLT_R(__tmu) (1<<((__tmu)+4))
#define DISP_3D_VTX_FLAG_DFLT_Q(__tmu) (1<<((__tmu)+12))
typedef struct {
int allocated;
unsigned format[DISP_3D_LOG2_MAX_TEXTURE_SIZE+1]; /* See DISP_3D_TEXFORMAT_* */
int max_lod;
GLfixed switchover;
void *image[DISP_3D_LOG2_MAX_TEXTURE_SIZE+1];
int width[DISP_3D_LOG2_MAX_TEXTURE_SIZE+1];
int height[DISP_3D_LOG2_MAX_TEXTURE_SIZE+1];
int stride[DISP_3D_LOG2_MAX_TEXTURE_SIZE+1];
void *palette;
int compressed_size;
GLenum min_filter;
GLenum mag_filter;
int min_linear;
GLenum wrap_s;
GLenum wrap_t;
void *driver_private;
} disp_texture_t;
typedef struct {
unsigned name;
GLenum usage;
unsigned size; /* In bytes */
void *dataptr;
void *driver_private;
} disp_bufobj_t;
typedef struct light_state {
struct {
disp_real r;
disp_real g;
disp_real b;
disp_real a;
} ambient;
struct {
disp_real r;
disp_real g;
disp_real b;
disp_real a;
} diffuse;
struct {
disp_real r;
disp_real g;
disp_real b;
disp_real a;
} specular;
struct {
disp_real x;
disp_real y;
disp_real z;
disp_real w;
} position;
struct {
disp_real x;
disp_real y;
disp_real z;
GLboolean transformed;
} spot_direction;
disp_real spot_exponent;
disp_real spot_cutoff;
disp_real cos_spot_cutoff;
disp_real constant_attenuation;
disp_real linear_attenuation;
disp_real quadratic_attenuation;
GLboolean enabled;
unsigned new_state;
unsigned imp_flags;
unsigned reserved[3];
} disp_3d_light_state_t;
typedef struct {
int enabled;
int complete;
disp_real s;
disp_real t;
disp_real r;
disp_real q;
GLenum env_mode;
int function;
disp_real env_r;
disp_real env_g;
disp_real env_b;
disp_real env_a;
disp_real tex_matrix[DISP_3D_TEX_MATRIX_ENTRIES][16];
disp_3d_matrix_flag tex_matrix_flags[DISP_3D_TEX_MATRIX_ENTRIES];
int tex_matrix_stackptr;
} disp_tmu_state_t;
typedef struct {
disp_real x;
disp_real y;
disp_real z;
disp_real w;
disp_real r[2];
disp_real g[2];
disp_real b[2];
disp_real a;
disp_real fog;
struct {
disp_real s;
disp_real t;
disp_real r;
disp_real q;
} t[DISP_3D_MAX_TMUS];
union {
struct {
disp_real x;
disp_real y;
disp_real z;
} normal;
struct {
/*
* Stores NDC's or Viewports coords, depending
* on what the device wants.
*/
disp_real x;
disp_real y;
disp_real z;
} ndc;
} u;
unsigned flags; /* Not for driver's use */
} disp_3d_vertex_t;
typedef struct disp_3d_span_params {
struct disp_rendercontext *rctx;
GLfixed r_start;
GLfixed r_step;
GLfixed g_start;
GLfixed g_step;
GLfixed b_start;
GLfixed b_step;
GLfixed a_start;
GLfixed a_step;
GLfixed f_start;
GLfixed f_step;
int z_start;
int z_step;
GLfixed *spanbuf;
GLfixed *cvgbuf;
unsigned reserved[7];
} disp_3d_span_params_t;
typedef struct disp_3d_prim_state {
disp_3d_send_type send_type;
disp_3d_primstate_flag flags;
unsigned reserved[4];
} disp_3d_prim_state_t;
typedef struct disp_3d_data_ptr {
disp_real *xptr;
disp_real *yptr;
disp_real *zptr;
disp_real *wptr;
disp_real *rptr;
disp_real *gptr;
disp_real *bptr;
disp_real *aptr;
disp_real *tsptr[DISP_3D_MAX_TMUS];
disp_real *ttptr[DISP_3D_MAX_TMUS];
disp_real *trptr[DISP_3D_MAX_TMUS];
disp_real *tqptr[DISP_3D_MAX_TMUS];
int xstride;
int ystride;
int zstride;
int wstride;
int rstride;
int gstride;
int bstride;
int astride;
int tsstride[DISP_3D_MAX_TMUS];
int ttstride[DISP_3D_MAX_TMUS];
int trstride[DISP_3D_MAX_TMUS];
int tqstride[DISP_3D_MAX_TMUS];
disp_real *nxptr;
disp_real *nyptr;
disp_real *nzptr;
int nxstride;
int nystride;
int nzstride;
uint32_t reserved[6];
} disp_3d_data_ptrs_t;
__BEGIN_DECLS
typedef struct disp_3d_pipeline_ctl {
disp_3d_prim_state_t tri;
disp_3d_prim_state_t line;
disp_3d_prim_state_t points;
void (*prim_begin)(void *context,
GLenum primitive, int nvertices, unsigned flags);
void (*prim_end)(void *context);
/* For drivers that can do lighting and/or view volume clipping */
void (*send_vertices)(void *context, int nvertices);
/* For drivers that can do view volume clipping, but not lighting */
void (*send_lit_vertices)(void *context,
disp_3d_vertex_t *v, int nvertices);
/* For drivers that take pre-lit, pre-clipped primitives */
void (*draw_triangle)(void *context,
disp_3d_vertex_t *v1, disp_3d_vertex_t *v2, disp_3d_vertex_t *v3);
void (*draw_line)(void *context,
disp_3d_vertex_t *v1, disp_3d_vertex_t *v2);
void (*draw_points)(void *context, disp_3d_vertex_t *v, int npoints);
/* Span function supporting OpenGL ES per-fragment operations */
void (*draw_span)(void *context,
int x, int y, int count, disp_3d_span_params_t *params);
disp_3d_data_ptrs_t *data_ptrs;
int max_vertices;
/* For drivers with direct access to array data via buffer objects */
int (*draw_arrays)(void *context, GLenum prim, int first, int nvertices);
int (*draw_elements)(void *context, GLenum,
unsigned nvertices, disp_bufobj_t *obj, unsigned datatype);
int (*draw_elements_immed)(void *context, GLenum,
unsigned nvertices, const void *data, unsigned datatype);
/* See DISP_3D_PCTL_FLAG_* */
uint32_t flags;
uint32_t reserved[3];
} disp_3d_pipeline_ctl_t;
typedef struct disp_rendercontext {
unsigned new_state; /* See DISP_3D_STATE_* */
unsigned new_global_light_state; /* See DISP_3D_LIGHT_STATE_* */
unsigned new_light_state; /* Per-light bitmask */
unsigned new_tmu_state; /* Per-tmu bitmask */
unsigned flags; /* See DISP_3D_CTX_FLAG_* */
unsigned enabled_features; /* Driver must check! */
struct {
GLboolean alpha_test;
GLboolean blend;
GLboolean color_logic_op;
GLboolean color_material;
GLboolean cull_face;
GLboolean depth_test;
GLboolean fog;
GLboolean lighting;
GLboolean line_smooth;
GLboolean normalize;
GLboolean point_smooth;
GLboolean polygon_offset_fill;
GLboolean rescale_normal;
GLboolean scissor_test;
GLboolean stencil_test;
} enabled;
int lights_on;
struct light_state light[DISP_3D_NUM_LIGHTS];
struct {
struct {
disp_real r;
disp_real g;
disp_real b;
disp_real a;
} ambient;
GLboolean twoside;
} lightmodel;
struct {
struct {
disp_real r;
disp_real g;
disp_real b;
disp_real a;
} ambient;
struct {
disp_real r;
disp_real g;
disp_real b;
disp_real a;
} diffuse;
struct {
disp_real r;
disp_real g;
disp_real b;
disp_real a;
} specular;
struct {
disp_real r;
disp_real g;
disp_real b;
disp_real a;
} emission;
disp_real shininess;
} material;
GLenum frontface;
GLenum cullface;
struct {
/* Buffer clear values */
disp_real r;
disp_real g;
disp_real b;
disp_real a;
disp_real depth;
GLint stencil;
} clear;
struct {
int x1;
int x2;
int y1;
int y2;
} cliprect;
struct {
disp_real near;
disp_real far;
GLenum func;
GLboolean mask;
} depth;
struct {
GLenum func;
GLenum fail;
GLenum zfail;
GLenum zpass;
GLuint testmask;
GLuint planemask;
GLint ref;
} stencil;
struct {
int x;
int y;
int width;
int height;
} viewport;
struct {
disp_real r;
disp_real g;
disp_real b;
disp_real a;
} color;
struct {
GLboolean r;
GLboolean g;
GLboolean b;
GLboolean a;
} colormask;
struct {
GLenum func;
disp_real ref;
} alpha;
struct {
GLenum sfactor;
GLenum dfactor;
} blend;
struct {
GLenum mode;
disp_real density;
disp_real start;
disp_real end;
disp_real r;
disp_real g;
disp_real b;
disp_real a;
} fog;
GLenum rop;
GLenum shademodel;
struct {
disp_real x;
disp_real y;
disp_real z;
} normal;
/* Space for matrix stacks */
disp_real model_matrix[DISP_3D_MODEL_MATRIX_ENTRIES][16];
disp_real proj_matrix[DISP_3D_PROJ_MATRIX_ENTRIES][16];
disp_3d_matrix_flag model_matrix_flags[DISP_3D_MODEL_MATRIX_ENTRIES];
disp_3d_matrix_flag proj_matrix_flags[DISP_3D_PROJ_MATRIX_ENTRIES];
/* Indices into matrix stacks */
int model_matrix_stackptr;
int proj_matrix_stackptr;
disp_real point_size;
disp_real line_width;
struct {
disp_real factor;
disp_real units;
} polygon_offset;
disp_tmu_state_t tmu[DISP_3D_MAX_TMUS];
int enabled_tmus;
int complete_tmus;
disp_texture_t *textures[DISP_3D_MAX_TMUS];
disp_3d_pipeline_ctl_t pipeline_ctl;
uint32_t ddflags; /* Driver debugging flags */
uint32_t line_stipple; /* Only 16 bits used */
struct {
GLboolean dither;
GLboolean fsaa;
GLboolean reserved[2];
} enabled2;
uint32_t vtx_flags;
uint32_t reserved[28];
} disp_rendercontext_t;
typedef enum {
DISP_3D_CAP_ACCEL = 0x00000001, /* Driver has some form of 3D acceleration support */
DISP_3D_CAP_INDEPENDANT_PM = 0x00000020 /* 3D engine can be independently power managed (i.e. not tied to 2D engine) */
} disp_3d_cap_flag;
typedef struct disp_3d_caps {
disp_3d_cap_flag flags; /* See DISP_3D_CAP_* */
int fixed_point;
int max_vertices;
const char *extensions;
unsigned num_tmus;
unsigned max_line_width;
unsigned max_point_size;
unsigned max_line_width_aa;
unsigned max_point_size_aa;
unsigned reserved[1];
} disp_3d_caps_t;
typedef struct disp_draw_3dfuncs {
void * (*init)(disp_adapter_t *adapter, const char *options);
void (*fini)(void *handle);
void (*module_info)(disp_adapter_t *adapter, disp_module_info_t *info);
int (*query_caps)(void *handle, disp_3d_caps_t *caps);
int (*query_buffer_config)(void *handle,
int index, disp_rend_buffer_config_t *config);
void * (*create_context)(void *handle, disp_rendercontext_t *rctx,
disp_rend_context_params_t *params);
void (*destroy_context)(void *context);
void * (*create_target)(void *handle,
int cfg_index, int width, int height);
void (*destroy_target)(void *handle, void *target);
void (*create_texture)(void *context, disp_texture_t *tex);
void (*destroy_texture)(void *context, disp_texture_t *tex);
void (*set_tex_image)(void *context, disp_texture_t *tex,
int width, int height, int lod, unsigned format,
unsigned reqformat, int stride, const void *data, void *palette);
void (*set_tex_image_copy)(void *context, disp_texture_t *tex,
disp_surface_t *src, int sxoff, int syoff, int width, int height,
int lod, unsigned reqformat);
void (*update_tex_image)(void *context, disp_texture_t *tex,
int dxoff, int dyoff, int width, int height, int lod,
unsigned format, int stride, const void *data, void *palette);
void (*update_tex_image_copy)(void *context, disp_texture_t *tex,
disp_surface_t *src, int sxoff, int syoff, int dxoff, int dyoff,
int width, int height, int lod);
void (*read_image)(void *handle, int sxoff, int syoff,
int width, int height, unsigned dformat, int dstride,
disp_surface_t * src, void *dst, int y_order_ascending);
void (*flush)(void *context);
void (*wait_idle)(void *context);
void (*make_current)(void *context, void *target);
void (*set_draw_surface)(void *context, disp_surface_t *surf);
/* Notifies driver that span rendering is about to occur */
int (*span_prepare)(void *context);
GLbitfield (*clear)(void *context, GLbitfield buffer_mask);
int (*update_state)(void *context);
int (*set_power_mode)(disp_adapter_t *adapter, pm_power_mode_t mode);
/* Buffer Objects (optional - may be NULL) */
int (*bufobj_create)(void *context, disp_bufobj_t *obj);
void (*bufobj_destroy)(void *context, disp_bufobj_t *obj);
int (*bufobj_set_data)(void *context, disp_bufobj_t *obj,
uintptr_t offset, uintptr_t nbytes, const void *data, int realloc);
int (*bufobj_set_datasource)(void *context, disp_bufobj_t *obj,
unsigned array, uintptr_t offset,
unsigned datatype, int stride, int n_elements);
void (*bufobj_set_enabled)(void *context, unsigned array, int enabled);
/* Display Lists - UNSUPPORTED */
void * (*dlist_begin)(void *context);
int (*dlist_end)(void *context);
void (*dlist_execute)(void *context, void *dlist);
void (*dlist_destroy)(void *context, void *dlist);
/* Driver-specific extension support */
int (*state_set_enabled)(void *context, GLenum cap, int enabled,
int active_tmu, int active_client_tmu, intptr_t reserved);
void (*(*get_proc_addr)(void *context, const char *procname))();
int (*query_tex_format)(void *context,
GLenum type, int *bpp, unsigned *tex_format);
void (*reserved[5])(void);
} disp_draw_3dfuncs_t;
typedef int (*get_rendfuncs_t)(disp_adapter_t *adapter,
disp_draw_3dfuncs_t *funcs, int tabsize);
/* Main draw driver entry points */
extern SOFT3D_API int devg_get_rendfuncs(disp_adapter_t *adapter,
disp_draw_3dfuncs_t *funcs, int tabsize);
__END_DECLS
#endif /* _GRAPHICS_3D_H_INCLUDED */
#endif /* disabled in KPDA */

362
devg/public/graphics/dinline.h Обычный файл
Просмотреть файл

@ -0,0 +1,362 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/* Optimized inline routines for low-level graphics operations */
#ifndef _GRAPHICS_DINLINE_H_INCLUDED
#define _GRAPHICS_DINLINE_H_INCLUDED
/*
* The following macros are designed to allow, for example,
* DISP_MR_SWAP32(ptr++); to work without undesirable side effects.
*/
#ifdef __PPC__
static __inline__ uint32_t __attribute__((__unused__))
disp_mr_swap32(volatile uintptr_t __addr)
{
unsigned ret;
__asm__ __volatile__("lwbrx %0,0,%1" :
"=r" (ret) : "r" (__addr), "m" (__addr));
return ret;
}
static __inline__ uint16_t __attribute__((__unused__))
disp_mr_swap16(volatile uintptr_t __addr)
{
int ret;
__asm__ __volatile__("lhbrx %0,0,%1" :
"=r" (ret) : "r" (__addr), "m" (__addr));
return ret;
}
static __inline__ void __attribute__((__unused__))
disp_mw_swap32(volatile uintptr_t __addr, _Uint32t __data)
{
__asm__ __volatile__("stwbrx %1,0,%2" :
"=m" (__addr) : "r" (__data), "r" (__addr));
}
static __inline__ void __attribute__((__unused__))
disp_mw_swap16(volatile uintptr_t __addr, _Uint16t __data)
{
__asm__ __volatile__("sthbrx %1,0,%2" :
"=m" (__addr) : "r" (__data), "r" (__addr));
}
/*
* Bury these functions inside of macros, to work around a gcc 2.95.3 bug,
* which doesn't occur if the arg to disp_m* is a uintptr_t, instead of
* an actual pointer.
*/
#define DISP_MR_SWAP32(__addr) disp_mr_swap32((uintptr_t)(__addr))
#define DISP_MR_SWAP16(__addr) disp_mr_swap16((uintptr_t)(__addr))
#define DISP_MW_SWAP32(__addr, __val) disp_mw_swap32((uintptr_t)(__addr), __val)
#define DISP_MW_SWAP16(__addr, __val) disp_mw_swap16((uintptr_t)(__addr), __val)
#else
static __inline__ uint32_t __attribute__((__unused__))
DISP_MR_SWAP32(void *__ptr)
{
uint32_t __val = *(volatile uint32_t *)(__ptr);
return (((__val) >> 24) | (((__val) >> 8) & 0xff00) |
(((__val) & 0xff00) << 8) | ((__val) << 24));
}
static __inline__ uint16_t __attribute__((__unused__))
DISP_MR_SWAP16(void *__ptr)
{
uint16_t __val = *(volatile uint16_t *)(__ptr);
return (((__val) >> 8) | ((__val) << 8));
}
static __inline__ void __attribute__((__unused__))
DISP_MW_SWAP32(void *__ptr, uint32_t __v)
{
uint32_t __val = (__v);
__val = (__val >> 24 | (__val & 0xff0000) >> 8 |
(__val & 0xff00) << 8 | __val << 24);
*(volatile uint32_t *)(__ptr) = __val;
}
static __inline__ void __attribute__((__unused__))
DISP_MW_SWAP16(void *__ptr, uint16_t __v)
{
uint16_t __val = (__v);
__val = (__val >> 8 | __val << 8);
*(volatile uint16_t *)(__ptr) = __val;
}
#endif
#ifdef __LITTLEENDIAN__
#define DISP_MR_LE32(__ptr) (*(volatile uint32_t *)(__ptr))
#define DISP_MR_BE32(__ptr) DISP_MR_SWAP32(__ptr)
#define DISP_MW_LE32(__ptr, __val) (*(volatile uint32_t *)(__ptr) = (__val))
#define DISP_MW_BE32(__ptr, __val) DISP_MW_SWAP32(__ptr, __val)
#define DISP_MR_LE16(__ptr) (*(volatile uint16_t *)(__ptr))
#define DISP_MR_BE16(__ptr) DISP_MR_SWAP16(__ptr)
#define DISP_MW_LE16(__ptr, __val) (*(volatile uint16_t *)(__ptr) = (__val))
#define DISP_MW_BE16(__ptr, __val) DISP_MW_SWAP16(__ptr, __val)
#else
#define DISP_MR_LE32(__ptr) DISP_MR_SWAP32(__ptr)
#define DISP_MR_BE32(__ptr) (*(volatile uint32_t *)(__ptr))
#define DISP_MW_LE32(__ptr, __val) DISP_MW_SWAP32(__ptr, __val)
#define DISP_MW_BE32(__ptr, __val) (*(volatile uint32_t *)(__ptr) = (__val))
#define DISP_MR_LE16(__ptr) DISP_MR_SWAP16(__ptr)
#define DISP_MR_BE16(__ptr) (*(volatile uint16_t *)(__ptr))
#define DISP_MW_LE16(__ptr, __val) DISP_MW_SWAP16(__ptr, __val)
#define DISP_MW_BE16(__ptr, __val) (*(volatile uint16_t *)(__ptr) = (__val))
#endif
__BEGIN_DECLS
#define __USE_C_FALLBACKS
#if defined (__GNUC__) || defined(__INTEL_COMPILER)
#if defined (__X86__)
#undef __USE_C_FALLBACKS
static inline void disp_memcpy(void *dst, void *src, int len)
{
__asm__ __volatile__ (
".align 4 \n\t"
"cld \n\t"
"cmpl $8, %%edx \n\t"
"jl 0f \n\t"
"3: \n\t"
".align 4 \n\t"
"testl $3, %%edi \n\t"
"jz 1f \n\t"
"movsb \n\t"
"decl %%edx \n\t"
"jz 2f \n\t"
"jnz 3b \n\t"
"0: \n\t"
".align 4 \n\t"
"movl %%edx, %%ecx \n\t"
"rep \n\t"
"movsb \n\t"
"jmp 2f \n\t"
"1: \n\t"
".align 4 \n\t"
"movl %%edx, %%ecx \n\t"
"shrl $2, %%ecx \n\t"
"rep \n\t"
"movsl \n\t"
"4: \n\t"
".align 4 \n\t"
"andl $3, %%edx \n\t"
"jz 2f \n\t"
"movsb \n\t"
"decb %%dl \n\t"
"jmp 4b \n\t"
"2: \n\t"
".align 4 \n\t"
: "=D"(dst), "=S"(src), "=d"(len) : "D"(dst), "S"(src), "d"(len) :
"ecx", "memory");
}
static inline void disp_memcpy_r(void *dst, void *src, int len)
{
__asm__ __volatile__ (
"std \n\t"
"cmpl $8, %%edx \n\t"
"jge 0f \n\t"
"movl %%edx, %%ecx \n\t"
"rep \n\t"
"movsb \n\t"
"jmp 1f \n\t"
/* Move (edi+1) & 3 bytes with movsb. */
"0: \n\t"
".align 4 \n\t"
"movl $3, %%eax \n\t"
"movl %%edi, %%ecx \n\t"
"incl %%ecx \n\t"
"andl %%eax, %%ecx \n\t"
"subl %%ecx, %%edx \n\t"
"rep \n\t"
"movsb \n\t"
/* Adjust edi & esi to point to *start* of nearest long. */
/* Move (edx / 4) longs with movsd. */
/* Adjust edi & esi to point back to end of long. */
"subl %%eax, %%edi \n\t"
"subl %%eax, %%esi \n\t"
"movl %%edx, %%ecx \n\t"
"shrl $2, %%ecx \n\t"
"rep \n\t"
"movsl \n\t"
"addl %%eax, %%edi \n\t"
"addl %%eax, %%esi \n\t"
/* Move remaining bytes. */
"movl %%edx, %%ecx \n\t"
"andl %%eax, %%ecx \n\t"
"jz 1f \n\t"
"rep \n\t"
"movsb \n\t"
"1: \n\t"
".align 4 \n\t"
"cld \n\t"
: "=D"(dst), "=S"(src), "=d"(len) : "D"(dst), "S"(src), "d"(len) :
"eax", "ecx", "memory");
}
static inline void disp_memset16(void *dst, uint16_t val, int len)
{
__asm__ __volatile__ (
"cmpl $8, %%edx \n\t"
"jle 0f \n\t"
"movl %%eax, %%ecx \n\t"
"rorl $16, %%eax \n\t"
"movw %%cx, %%ax \n\t"
"2: \n\t"
".align 4 \n\t"
"testl $3, %%edi \n\t"
"jz 1f \n\t"
"stosw \n\t"
"decl %%edx \n\t"
"jmp 2b \n\t"
"1: \n\t"
".align 4 \n\t"
"movl %%edx, %%ecx \n\t"
"shrl $1, %%ecx \n\t"
"andl $1, %%edx \n\t"
"rep \n\t"
"stosl \n\t"
"0: \n\t"
".align 4 \n\t"
"testl %%edx, %%edx \n\t"
"jz 3f \n\t"
"movl %%edx, %%ecx \n\t"
"rep \n\t"
"stosw \n\t"
"3: \n\t"
".align 4 \n\t"
: "=D"(dst), "=a"(val), "=d"(len) : "D"(dst), "a"(val), "d"(len) :
"ecx", "memory");
};
#endif /* __X86__ */
#elif defined (__WATCOMC__)
#undef __USE_C_FALLBACKS
void disp_memcpy(void *dst, void *src, int len);
#pragma aux disp_memcpy = \
" cmp edx, 8 ",\
" jl QByteCopy ",\
"StartTest: ",\
" test edi, 3 ",\
" jz EvenStart ",\
" movsb ",\
" dec edx ",\
" jz Done ",\
" jmp StartTest ",\
"QByteCopy: ",\
" mov ecx, edx ",\
"QByteCopy2: ",\
" rep movsb ",\
" jmp Done ",\
"EvenStart: ",\
" mov ecx, edx ",\
" shr ecx, 2 ",\
"DoubleCopy: ",\
" rep movsd ",\
"ByteCopy: ",\
" and edx, 3 ",\
" jz Done ",\
" movsb ",\
" dec dl ",\
" jmp ByteCopy ",\
"Done: "\
parm nomemory [edi] [esi] [edx] \
modify [edi esi ecx edx];
void disp_memcpy_r(void *dst, void *src, int len);
#pragma aux disp_memcpy_r = \
" std ",\
" cmp edx, 8 ",\
" jge StartTest ",\
\
" mov ecx, edx ",\
" rep movsb ",\
" jmp Done ",\
/* move (edi+1) & 3 bytes with movsb */ \
"StartTest: ",\
" mov eax, 3 ",\
" mov ecx,edi ",\
" inc ecx ",\
" and ecx,eax ",\
" sub edx,ecx ",\
" rep movsb ",\
/* adjust edi & esi to point to */ \
/* *start* of nearest long */ \
/* move (edx / 4) longs with movsd */ \
/* adjust edi & esi to point back to end of long */ \
" sub edi, eax ",\
" sub esi, eax ",\
" mov ecx, edx ",\
" shr ecx, 2 ",\
" rep movsd ",\
" add edi, eax ",\
" add esi, eax ",\
/* move remaining bytes */ \
" mov ecx, edx ",\
" and ecx, eax ",\
" jz Done ",\
" rep movsb ",\
"Done: ",\
" cld ",\
parm nomemory [edi] [esi] [edx] \
modify [edi esi eax ecx edx];
void disp_memset16(void *dst, unsigned short val, int len);
#pragma aux disp_memset16 = \
" cmp edx, 8 ",\
" jle ByteCopy ",\
" mov ecx, eax ",\
" ror eax, 16 ",\
" mov ax, cx ",\
"StartTest: ",\
" test edi, 3 ",\
" jz EvenStart ",\
" stosw ",\
" dec edx ",\
" jmp StartTest ",\
"EvenStart: ",\
" mov ecx, edx ",\
" shr ecx, 1 ",\
" and edx, 1 ",\
" rep stosd ",\
"ByteCopy: ",\
" test edx, edx ",\
" jz Done ",\
" mov ecx, edx ",\
" rep stosw ",\
"Done: "\
parm nomemory [edi] [ax] [edx] \
modify [edi eax ecx edx];
#endif /* __WATCOMC__ */
#ifdef __USE_C_FALLBACKS
#define disp_memcpy(dst, src, len) memcpy(dst, src, len)
extern void disp_memcpy_r(void *dst, void *src, int len);
extern void disp_memset16(void *dst, disp_color_t color, int len);
#endif /* __USE_C_FALLBACKS */
__END_DECLS
#endif /* _GRAPHICS_DINLINE_H_INCLUDED */

494
devg/public/graphics/display.h Обычный файл
Просмотреть файл

@ -0,0 +1,494 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#define _GRAPHICS_DISPLAY_H_INCLUDED
#ifndef __TYPES_H_INCLUDED
#include <sys/types.h>
#endif
#ifdef __QNXNTO__
#ifndef __INTTYPES_H_INCLUDED
#include <inttypes.h>
#endif
#endif
#ifndef __GULLIVER_H_INCLUDED
#include <gulliver.h>
#endif
#ifndef __PCI_H_INCLUDED
#include <hw/pci.h>
#endif
#ifndef __MMAN_H_INCLUDED
#include <sys/mman.h>
#endif
#ifndef _STDIO_H_INCLUDED
#include <stdio.h>
#endif
#ifndef _PM_H_INCLUDED
#include <sys/pm.h>
#endif
#ifndef _GRAPHICS_ROP_H_INCLUDED
#include <graphics/rop.h>
#endif
#include <semaphore.h>
#define WINSIM_API
#define SOFT3D_API
#ifndef __QNXNTO__
#include <sys/cdefs.h>
#ifndef _INTTYPES_H_INCLUDED
typedef char int8_t;
typedef short int16_t;
typedef short int16_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t; /* This line may have to be omitted, depending on which version of the QNX4 header files you build against */
typedef int8_t _int8;
typedef int16_t _int16;
typedef uint8_t _uint8;
typedef uint16_t _uint16;
typedef uint32_t _uint32;
#endif
typedef uint32_t disp_paddr_t;
typedef uint32_t uintptr_t;
#else
typedef uint64_t disp_paddr_t;
#endif
#ifndef _HW_INOUT_INCLUDED
#include <hw/inout.h>
#endif
#define DISP_MAX_MODES 72
/*
* Supported layer formats; note that a layer format is comprised of
* of one or more surface formats. Please don't use the most significant bit.
*/
#define DISP_LAYER_FORMAT_PAL8 0x00000000
#define DISP_LAYER_FORMAT_ARGB1555 0x00000001
#define DISP_LAYER_FORMAT_RGB565 0x00000002
#define DISP_LAYER_FORMAT_RGB888 0x00000003
#define DISP_LAYER_FORMAT_ARGB8888 0x00000004
#define DISP_LAYER_FORMAT_RGB556 0x00000005
#define DISP_LAYER_FORMAT_BYTES 0x00000006
#define DISP_LAYER_FORMAT_YUY2 0x00010000 /* Packed YUV, 16bpp: Y8U8Y8V8 */
#define DISP_LAYER_FORMAT_UYVY 0x00010001 /* Packed YUV, 16bpp: U8Y8V8Y8 */
#define DISP_LAYER_FORMAT_YVYU 0x00010002 /* Packed YUV, 16bpp: Y8V8Y8U8 */
#define DISP_LAYER_FORMAT_V422 0x00010003 /* Packed YUV, 16bpp: V8Y8U8Y8 */
#define DISP_LAYER_FORMAT_NV12 0x00010004 /* Y plane immediately followed by packed UV plane, one U sample and one V sample per 2x2 block of Y */
#define DISP_LAYER_FORMAT_AYUV 0x00010005 /* Packed YUV, 32bpp: V8U8Y8A8 */
#define DISP_LAYER_FORMAT_YUY2_INTERLACED 0x00018000 /* Packed YUV, 16bpp: Y8U8Y8V8, interlaced */
#define DISP_LAYER_FORMAT_UYVY_INTERLACED 0x00018001 /* Packed YUV, 16bpp: U8Y8V8Y8, interlaced */
#define DISP_LAYER_FORMAT_YVYU_INTERLACED 0x00018002 /* Packed YUV, 16bpp: Y8V8Y8U8, interlaced */
#define DISP_LAYER_FORMAT_V422_INTERLACED 0x00018003 /* Packed YUV, 16bpp: V8Y8U8Y8, interlaced */
#define DISP_LAYER_FORMAT_NV12_INTERLACED 0x00018004 /* Y plane immediately followed by packed UV plane, one U sample and one V sample per 2x2 block of Y, interlaced */
#define DISP_LAYER_FORMAT_AYUV_INTERLACED 0x00018005 /* Packed YUV, 32bpp: V8U8Y8A8, interlaced */
#define DISP_LAYER_FORMAT_YVU9 0x00020000 /* Planar YUV, one U sample and one V sample per 4x4 block of Y */
#define DISP_LAYER_FORMAT_YV12 0x00020001 /* Planar YUV, one U sample and one V sample per 2x2 block of Y */
#define DISP_LAYER_FORMAT_YUV420 0x00020002 /* Planar YUV, one U sample and one V sample per 2x1 block of Y */
#define DISP_LAYER_FORMAT_YVU9_INTERLACED 0x00028000 /* Planar YUV, one U sample and one V sample per 4x4 block of Y, interlaced */
#define DISP_LAYER_FORMAT_YV12_INTERLACED 0x00028001 /* Planar YUV, one U sample and one V sample per 2x2 block of Y, interlaced */
#define DISP_LAYER_FORMAT_YUV420_INTERLACED 0x00028002 /* Planar YUV, one U sample and one V sample per 2x1 block of Y, interlaced */
/* surface formats - upper byte specifies bits per pixel */
#define DISP_SURFACE_FORMAT_BYTES 0x08000000
#define DISP_SURFACE_FORMAT_PAL8 0x08000001
#define DISP_SURFACE_FORMAT_ARGB1555 0x10000002
#define DISP_SURFACE_FORMAT_RGB565 0x10000003
#define DISP_SURFACE_FORMAT_RGB888 0x18000004
#define DISP_SURFACE_FORMAT_ARGB8888 0x20000005
#define DISP_SURFACE_FORMAT_RGBA8888 0x20000006
#define DISP_SURFACE_FORMAT_PAL4 0x04000006
#define DISP_SURFACE_FORMAT_RGB556 0x10000007
/* Packed YUV formats */
#define DISP_SURFACE_FORMAT_PACKEDYUV_IYU1 0x0c40000a
#define DISP_SURFACE_FORMAT_PACKEDYUV_IYU2 0x1840000b
#define DISP_SURFACE_FORMAT_PACKEDYUV_UYVY 0x1040000c
#define DISP_SURFACE_FORMAT_PACKEDYUV_YUY2 0x1040000d
#define DISP_SURFACE_FORMAT_PACKEDYUV_YVYU 0x1040000e
#define DISP_SURFACE_FORMAT_PACKEDYUV_V422 0x1040000f
#define DISP_SURFACE_FORMAT_PACKEDYUV_CLJR 0x08400010
#define DISP_SURFACE_FORMAT_PACKEDYUV_AYUV 0x20400011
#define DISP_SURFACE_FORMAT_PACKEDYUV_IYU1_INTERLACED 0x0c600012
#define DISP_SURFACE_FORMAT_PACKEDYUV_IYU2_INTERLACED 0x18600013
#define DISP_SURFACE_FORMAT_PACKEDYUV_UYVY_INTERLACED 0x10600014
#define DISP_SURFACE_FORMAT_PACKEDYUV_YUY2_INTERLACED 0x10600015
#define DISP_SURFACE_FORMAT_PACKEDYUV_YVYU_INTERLACED 0x10600016
#define DISP_SURFACE_FORMAT_PACKEDYUV_V422_INTERLACED 0x10600017
#define DISP_SURFACE_FORMAT_PACKEDYUV_CLJR_INTERLACED 0x08600018
#define DISP_SURFACE_FORMAT_PACKEDYUV_AYUV_INTERLACED 0x20600019
/* YUV planar surface types */
#define DISP_SURFACE_FORMAT_YPLANE 0x00400011
#define DISP_SURFACE_FORMAT_UPLANE 0x00400012
#define DISP_SURFACE_FORMAT_VPLANE 0x00400013
/* Useful macros to operate on surface types */
#define DISP_BITS_PER_PIXEL(__fmt) ((__fmt) >> 24)
#define DISP_BYTES_PER_PIXEL(__fmt) (((__fmt) + 0x7000000) >> 27)
#define DISP_SURFACE_ISPAL(__fmt) (((__fmt) & 0x00800000) || ((__fmt) == DISP_SURFACE_FORMAT_PAL4) || ((__fmt) == DISP_SURFACE_FORMAT_PAL8))
#define DISP_SURFACE_ISYUV(__fmt) ((__fmt) & 0x00400000)
#define DISP_SURFACE_IS_INTERLACED(__fmt) ((__fmt) & 0x00200000)
/* RGB true color macros */
#define DISP_TRUE_BLUE(color) ((color) & 0xff)
#define DISP_TRUE_GREEN(color) (((color) & 0xff00) >> 8)
#define DISP_TRUE_RED(color) (((color) & 0xff0000) >> 16)
#define DISP_TRUE_ALPHA(color) (((color) & 0xff000000) >> 24)
#define DISP_MK_TRUECOLOR(a, r, g, b) \
((a) << 24 | (r) << 16 | (g) << 8 | b)
/* Alpha Blending multiplier origins */
#define DISP_ALPHA_M1_SRC_PIXEL_ALPHA 0x00010000 /* "M1" comes from the source pixels alpha component */
#define DISP_ALPHA_M1_DST_PIXEL_ALPHA 0x00020000 /* "M1" comes from the destination pixels alpha component */
#define DISP_ALPHA_M1_GLOBAL 0x00040000 /* "M1" comes from the global multiplier 1 */
#define DISP_ALPHA_M1_MAP 0x00080000 /* "M1" comes from the Alpha map */
#define DISP_ALPHA_M2_SRC_PIXEL_ALPHA 0x01000000 /* "M2" comes from the source pixels alpha component */
#define DISP_ALPHA_M2_DST_PIXEL_ALPHA 0x02000000 /* "M2" comes from the destination pixels alpha component */
#define DISP_ALPHA_M2_GLOBAL 0x04000000 /* "M2" comes from the global multiplier 2 */
#define DISP_ALPHA_M2_MAP 0x08000000 /* "M2" comes from the Alpha map */
#define DISP_ALPHA_M1_ORIGIN(__mode) ((__mode) & 0x00ff0000)
#define DISP_ALPHA_M2_ORIGIN(__mode) ((__mode) & 0x0f000000)
#define DISP_ALPHA_TEST 0x10000000 /* Alpha test instead of blend */
#define DISP_ALPHA_MERGE 0x20000000 /* Merge two semi-transparent images with per-pixel alpha (experimental) */
/* Alpha Blending Source Factor */
#define DISP_BLEND_SRC_0 0x0000 /* (0,0,0,0) */
#define DISP_BLEND_SRC_M1 0x0100 /* (M1,M1,M1,M1) */
#define DISP_BLEND_SRC_1mM1 0x0200 /* (1-M1,1-M1,1-M1,1-M1) */
#define DISP_BLEND_SRC_1mD 0x0300 /* (1-M2,1-Rd,1-Gd,1-Bd) */
#define DISP_BLEND_SRC_M2 0x0400 /* (M2,M2,M2,M2) */
#define DISP_BLEND_SRC_D 0x0500 /* (M2,Rd,Gd,Bd) */
#define DISP_BLEND_SRC_1 0x0600 /* (1,1,1,1) */
#define DISP_BLEND_SRC_A1M1 0x0700 /* (1,M1,M1,M1) */
#define DISP_BLEND_SRC_1mM2 0x0800 /* (1-M2,1-M2,1-M2,1-M2) */
#define DISP_BLEND_SRC_1mA1M1 0x0900 /* (1-1,1-M1,1-M1,1-M1) */
#define DISP_BLEND_SRC_A1M2 0x0A00 /* (1,M2,M2,M2) */
#define DISP_BLEND_SRC_1mA1M2 0x0B00 /* (1-1,1-M2,1-M2,1-M2) */
#define DISP_BLEND_SRC_A0M1 0x0C00 /* (0,M1,M1,M1) */
#define DISP_BLEND_SRC_1mA0M1 0x0D00 /* (1-0,1-M1,1-M1,1-M1) */
#define DISP_BLEND_SRC_A0M2 0x0E00 /* (0,M2,M2,M2) */
#define DISP_BLEND_SRC_1mA0M2 0x0F00 /* (1-0,1-M2,1-M2,1-M2) */
#define DISP_BLEND_SRC_M1_ALPHA DISP_BLEND_SRC_M1
#define DISP_BLEND_SRC_ONE_MINUS_M1_ALPHA DISP_BLEND_SRC_1mM1
#define DISP_BLEND_SRC_M2_ALPHA DISP_BLEND_SRC_M2
#define DISP_BLEND_SRC_ONE_MINUS_M2_ALPHA DISP_BLEND_SRC_1mM2
#define DISP_BLEND_SRC_GET(__mode) ((__mode) & 0xff00)
/* Alpha Blending Destination Factor */
#define DISP_BLEND_DST_0 0x00 /* (0,0,0,0) */
#define DISP_BLEND_DST_M1 0x01 /* (M1,M1,M1,M1) */
#define DISP_BLEND_DST_1mM1 0x02 /* (1-M1,1-M1,1-M1,1-M1) */
#define DISP_BLEND_DST_1mS 0x03 /* (1-M1,1-Rs,1-Gs,1-Bs) */
#define DISP_BLEND_DST_M2 0x04 /* (M2,M2,M2,M2) */
#define DISP_BLEND_DST_S 0x05 /* (M1,Rs,Gs,Bs) */
#define DISP_BLEND_DST_1 0x06 /* (1,1,1,1) */
#define DISP_BLEND_DST_A1M1 0x07 /* (1,M1,M1,M1) */
#define DISP_BLEND_DST_1mM2 0x08 /* (1-M2,1-M2,1-M2,1-M2) */
#define DISP_BLEND_DST_1mA1M1 0x09 /* (1-1,1-M1,1-M1,1-M1) */
#define DISP_BLEND_DST_A1M2 0x0A /* (1,M2,M2,M2) */
#define DISP_BLEND_DST_1mA1M2 0x0B /* (1-1,1-M2,1-M2,1-M2) */
#define DISP_BLEND_DST_A0M1 0x0C /* (0,M1,M1,M1) */
#define DISP_BLEND_DST_1mA0M1 0x0D /* (1-0,1-M1,1-M1,1-M1) */
#define DISP_BLEND_DST_A0M2 0x0E /* (0,M2,M2,M2) */
#define DISP_BLEND_DST_1mA0M2 0x0F /* (1-0,1-M2,1-M2,1-M2) */
#define DISP_BLEND_DST_M1_ALPHA DISP_BLEND_DST_M1
#define DISP_BLEND_DST_ONE_MINUS_M1_ALPHA DISP_BLEND_DST_1mM1
#define DISP_BLEND_DST_M2_ALPHA DISP_BLEND_DST_M2
#define DISP_BLEND_DST_ONE_MINUS_M2_ALPHA DISP_BLEND_DST_1mM2
#define DISP_BLEND_DST_GET(__mode) ((__mode) & 0x00ff)
/* Alpha Tests Pixels are written in destination */
#define DISP_TEST_NEVER 0x00 /* Never */
#define DISP_TEST_ALWAYS 0x01 /* Always */
#define DISP_TEST_LESS_THAN 0x02 /* if M1 < M2 */
#define DISP_TEST_LESS_THAN_OR_EQUAL 0x03 /* if M1 <= M2 */
#define DISP_TEST_EQUAL 0x04 /* if M1 == M2 */
#define DISP_TEST_GREATER_THAN_OR_EQUAL 0x05 /* if M1 >= M2 */
#define DISP_TEST_GREATER_THAN 0x06 /* if M1 > M2*/
#define DISP_TEST_NOT_EQUAL 0x07 /* if M1 != M2 */
#define DISP_TEST_GET(__mode) ((__mode) & 0x00ff)
/* Valid alpha combinations */
#define DISP_ALPHA_CAP_SPP_WITH_GLOBAL 0x00000001 /* Source Per-pixel with Dest global supported */
#define DISP_ALPHA_CAP_GLOBAL_WITH_DPP 0x00000002 /* Source global with Dest Per-pixel supported */
#define DISP_ALPHA_CAP_SPP_WITH_DPP 0x00000004 /* Source per-pixel with Dest per-pixel supported */
#define DISP_ALPHA_CAP_GLOBAL_WITH_GLOBAL 0x00000008 /* Source global with Dest global supported */
#define DISP_ALPHA_BLEND_CAP_SPP_WITH_GLOBAL DISP_ALPHA_CAP_SPP_WITH_GLOBAL
#define DISP_ALPHA_BLEND_CAP_GLOBAL_WITH_DPP DISP_ALPHA_CAP_GLOBAL_WITH_DPP
#define DISP_ALPHA_BLEND_CAP_SPP_WITH_DPP DISP_ALPHA_CAP_SPP_WITH_DPP
#define DISP_ALPHA_BLEND_CAP_GLOBAL_WITH_GLOBAL DISP_ALPHA_CAP_GLOBAL_WITH_GLOBAL
/* Chroma Key operations */
#define DISP_CHROMA_OP_SRC_MATCH 0x00000001 /* Match Color is Source Color */
#define DISP_CHROMA_OP_DST_MATCH 0x00000002 /* Match Color is Destination Color */
#define DISP_CHROMA_OP_DRAW 0x00000004 /* if Match Color == Color, Draw */
#define DISP_CHROMA_OP_NO_DRAW 0x00000008 /* if Match Color == Color, Don't Draw */
#define DISP_CHROMA_OP_UNDEFINED ~(DISP_CHROMA_OP_SRC_MATCH | \
DISP_CHROMA_OP_DST_MATCH | \
DISP_CHROMA_OP_DRAW | \
DISP_CHROMA_OP_NO_DRAW)
typedef uint32_t disp_color_t;
typedef struct {
int32_t x;
int32_t y;
} disp_point_t;
typedef int disp_fx_t; /* Fixed point: S1:I15:F16 */
#define DISP_ADD_FUNC(tabletype, table, entry, func, limit) \
if (((size_t)&(((tabletype *)0)->entry)) + sizeof (void (*)()) <= (size_t)(limit)) \
(table)->entry = (func);
/* disp_adapter.caps */
#define DISP_CAP_MULTI_MONITOR_SAFE 0x00000001
#define DISP_CAP_2D_ACCEL 0x00000002
#define DISP_CAP_3D_ACCEL 0x00000004
#define DISP_CAP_NO_IO_PRIVITY 0x00000008 /* 2D/3D entry points can be called without I/O privity */
#define DISP_CAP_DYNAMIC_MODESWITCH 0x00000010 /* Display modeswitches can occur without damaging any surfaces, or disturbing the layer state */
/* disp_adapter.bus_type */
#define DISP_BUS_TYPE_UNKNOWN 0x00000000
#define DISP_BUS_TYPE_PCI 0x00000001
#define DISP_BUS_TYPE_AGP 0x00000002
#define DISP_BUS_TYPE_ISA 0x00000004
#define DISP_BUS_TYPE_VL 0x00000010
#define DISP_BUS_TYPE_IS_PCI_OR_AGP(__type) ((__type) & (DISP_BUS_TYPE_PCI|DISP_BUS_TYPE_AGP))
#define DISP_PADDR_INVALID (~(disp_paddr_t)0)
/* Commands for disp_adapter_t.callback */
#define DISP_CALLBACK_LOCK 1
#define DISP_CALLBACK_UNLOCK 2
#define DISP_CALLBACK_WAIT_IDLE 3
#define DISP_CALLBACK_ALLOC_SURFACE 4
#define DISP_CALLBACK_FREE_SURFACE 5
#define DISP_CALLBACK_WAIT_VSYNC 6
#define DISP_CALLBACK_DEVCTL 7
#define DISP_CALLBACK_SURFACE_SID 8
typedef struct disp_adapter {
int size; /* size of structure */
void *gd_ctx; /* graphics drivers private context */
void *ms_ctx; /* Mode-switchers private context */
void *mm_ctx; /* Memory-managers private context */
void *vid_ctx; /* Video Overlay drivers private context */
void *vcap_ctx; /* Video Capture drivers private context */
void * (*callback)(void *handle, unsigned cmd, void *data);
void *callback_handle;
volatile unsigned *vsync_counter;
void *display_update_mutex;
uintptr_t reserved;
void **hook_context;
int hook_index;
int irq; /* Devices irq, set by disp_pci_init; -1 if unable to generate interrupts */
uintptr_t reserved1[2];
int bus_type;
union {
struct {
#ifdef __QNXNTO__
int pci_handle; /* Used internally by disputil */
void *pci_dev_handle; /* Used internally by disputil */
#else
unsigned pci_bus; /* Used internally by disputil */
uintptr_t pci_devfunc; /* Used internally by disputil */
#endif
unsigned short pci_vendor_id; /* Devices PCI vendor ID (0 if not applicable) */
unsigned short pci_device_id; /* Devices PCI device ID */
short pci_index; /* Together, {pci_vendor_id, pci_deviceid, pci_index} uniquely identify a PCI device in the system */
#ifdef __QNXNTO__
struct pci_dev_info *dev_info;
#else
uintptr_t reserved; /* Current flags to pass to pci_attach */
#endif
disp_paddr_t base[6]; /* devices PCI aperture base addresses; set by disp_pci_init */
disp_paddr_t apsize[6]; /* size of PCI apertures; set by disp_pci_init */
} pci;
struct {
unsigned reserved1;
uintptr_t reserved2;
unsigned short vendor_id; /* Devices vendor ID (0 if not applicable) */
unsigned short device_id; /* Devices device ID */
short index; /* Together, {vendor_id, deviceid, index} uniquely identify a device in the system */
} generic;
} bus;
unsigned caps; /* Adapter capabilities */
FILE *dbgfile; /* Debug sent here if non-NULL */
uintptr_t reserved2; /* interrupts the card can generate */
uintptr_t reserved3;
void *shmem;
void *hydra_shmem; /* For multi-monitor support */
struct disp_modefuncs *modefuncs;
struct disp_memfuncs *memfuncs;
int adapter_ram; /* Total memory installed on the adapter */
#if !defined(__QNXNTO__) || defined (__X86__)
struct vbios_context *vbios;
#else
uintptr_t reservedv;
#endif
void *ffb_extension;
int pulseprio;
uintptr_t reserved4[2];
unsigned cbsize; /* permanetly allocated video capture buffer size */
unsigned dflags; /* debug flags */
} disp_adapter_t;
/* Constants for filling in the disp_module_info structure */
#define DDK_VERSION_MAJOR 1
#define DDK_VERSION_MINOR 2
#define DDK_REVISION 0
typedef struct disp_module_info {
uint8_t ddk_version_major; /* Major version of DDK used to build driver */
uint8_t ddk_version_minor; /* Minor version of DDK used to build driver */
uint8_t ddk_rev; /* Rev. of DDK used to build driver */
uint8_t driver_rev; /* Driver revision number */
char *description;
unsigned reserved[16];
} disp_module_info_t;
/* Flags for memory management */
#define DISP_PROT_READ (PROT_READ)
#define DISP_PROT_WRITE (PROT_WRITE)
#define DISP_PROT_NOCACHE (PROT_NOCACHE)
#ifdef __QNXNTO__
#define DISP_MAP_PHYS (MAP_PHYS)
#define DISP_MAP_BELOW16M (MAP_BELOW16M)
#define DISP_MAP_LAZYWRITE (MAP_LAZY) /* superceeded by DISP_MAP_WRITECOMBINE */
#define DISP_MAP_LAZY (DISP_MAP_LAZYWRITE) /* superceeded by DISP_MAP_WRITECOMBINE */
#define DISP_MAP_WRITECOMBINE 0x00000100 /* write combine */
#define DISP_MAP_WRITETHROUGH 0x00000200 /* write through cache hit policy */
#define DISP_MAP_WRITEBACK 0x00000400 /* write back cache hit policy */
#define DISP_MAP_WRITEALLOC 0x00000800 /* write alloc cache miss policy */
#define DISP_MAP_WRITENOALLOC 0x00100000 /* write no alloc cache miss policy */
#else
#define DISP_MAP_PHYS 0x00010000 /* Get physically contiguous RAM */
#define DISP_MAP_BELOW16M 0x00040000 /* Get RAM that is physically below 16 Meg */
#define DISP_MAP_LAZY 0x00000080 /* Map with write combining (or equivalent caching policy; processor dependant) */
#endif
/* disp_surface.flags */
/* Surface capabilities flags */
#define DISP_SURFACE_DISPLAYABLE 0x00000001 /* Surface can be displayed via CRT controller */
#define DISP_SURFACE_CPU_LINEAR_READABLE 0x00000002 /* CPU can read this surface directly */
#define DISP_SURFACE_CPU_LINEAR_WRITEABLE 0x00000004 /* CPU can write to this surface directly */
#define DISP_SURFACE_2D_READABLE 0x00000008 /* surface is read-accessible by 2D engine */
#define DISP_SURFACE_3D_READABLE 0x00000010 /* surface is read-accessible by 3D engine */
#define DISP_SURFACE_2D_TARGETABLE 0x00000020 /* 2D engine can render into surface */
#define DISP_SURFACE_3D_TARGETABLE 0x00000040 /* 3D engine can render into surface */
#define DISP_SURFACE_SCALER_DISPLAYABLE 0x00000080 /* Surface can be displayed via video overlay scaler */
#define DISP_SURFACE_VMI_TARGETABLE 0x00000100 /* Video in hardware can write frames into surface */
#define DISP_SURFACE_DMA_SAFE 0x00000200 /* DMA engine can treat the surface memory as one contiguous block */
#define DISP_SURFACE_PAGE_ALIGNED 0x00000400 /* Surface memory starts on a page boundary, and its linear size is a multiple of the page size */
#define DISP_SURFACE_MULTISAMPLED 0x00000800 /* Surface can be used in a multisampled Khronos configuration */
#define DISP_SURFACE_BYTES_REVERSED 0x00001000 /* Byte order is reversed. Only valid for 16 and 32bpp surfaces */
#define DISP_SURFACE_OTHER_ENDIAN 0x00001000 /* Obsolete - use DISP_SURFACE_BIG_ENDIAN */
#define DISP_SURFACE_NON_CACHEABLE 0x00002000 /* Memory should be mapped non-cachable */
#define DISP_SURFACE_WT_CACHEABLE 0x00004000 /* Memory can be mapped write-through cacheable (but not write-back cacheable) */
#define DISP_SURFACE_PHYS_CONTIG 0x00008000 /* Memory is physically contiguous */
#define DISP_SURFACE_DRIVER_NOT_OWNER 0x00010000 /* Driver did not create/allocate this surface (e.g. images coming from higher-level software) */
#define DISP_SURFACE_ALPHA_MAP 0x00020000 /* Surface can be used as an alpha map for rendering */
#define DISP_SURFACE_RECT 0x00040000
#define DISP_SURFACE_STRIDE_ALIGNED 0x00080000
#define DISP_SURFACE_DRIVER_PRIVATE 0x00100000 /* Has surface been specially mapped for the given process */
#define DISP_SURFACE_UMA_MEM 0x00800000 /* surface is allocated by UMA GPU through an aperature */
/* Hint flags - mutually exclusive */
#define DISP_SURFACE_SLOW_CPU_ACCESS 0x80000000 /* Surface memory access by CPU is expensive */
#define DISP_SURFACE_SLOW_2D_ENGINE_ACCESS 0x40000000 /* Surface memory access by 2D engine is expensive */
#define DISP_SURFACE_SLOW_3D_ENGINE_ACCESS 0x40000000 /* Surface memory access by 3D engine is expensive */
#define DISP_SURFACE_RESPECT_BYTE_ORDER 0x10000000 /* respect DISP_SURFACE_BYTES_REVERSED flag when allocating surface */
#define DISP_SURFACE_ZONE_MASK 0x0f000000
#define DISP_SURFACE_ZONE_SHIFT 24
#define DISP_SURFACE_CAPS_MASK 0x00ffffff
typedef uint8_t* ch_address;
typedef struct disp_surface {
int size; /* Size of this struct */
unsigned pixel_format;
unsigned offset; /* device-dependent address */
unsigned char *vidptr; /* GPU virtual address */
disp_paddr_t paddr; /* physical address */
unsigned stride; /* In bytes */
unsigned flags; /* Surface flags */
int width; /* In pixels */
int height;
disp_color_t *palette; /* palette associated with this surface, if any */
int palette_valid_entries; /* size of palette */
disp_adapter_t *adapter; /* the adapter which created this surface (if any) */
ch_address **buffer; /* double index for surface buffer */
uintptr_t driver_private;
unsigned char *ffb_vidptr; /* S/W Optimized vidptr, may be the same as vidptr, or NULL. */
unsigned ffb_size; /* Size of memory area referenced by ffb_vidptr. */
uintptr_t reserved[5];
} disp_surface_t;
/* Device specific capabilities/requirements that
* are returned in disp_iomsg_reply_t.u.reg.dev_flags.
*/
#define DISP_DEV_REQUIRES_LAYER_FLUSHRECT 0x0001
#ifdef DISP_DEBUG
/*
* This assert deliberately causes a fault upon failure, so that you can
* obtain a core dump of the process at the time of the assertion failure
*/
#define DISP_ASSERT(x) if (!(x)) { \
fprintf(stderr, \
"%s, line %d: assert failed: %s\n", \
__FILE__, __LINE__, #x); \
(*(char * volatile)0)++; \
}
#else
#define DISP_ASSERT(x)
#endif
#ifndef _GRAPHICS_VMEM_H_INCLUDED
#include <graphics/vmem.h>
#endif
#ifndef _GRAPHICS_DRAW_H_INCLUDED
#include <graphics/draw.h>
#endif
#ifndef _GRAPHICS_MODE_H_INCLUDED
#include <graphics/mode.h>
#endif
#ifndef _GRAPHICS_VID_H_INCLUDED
#include <graphics/vid.h>
#endif
#ifndef _GRAPHICS_VCAP_H_INCLUDED
#include <graphics/vcap.h>
#endif
#ifndef _GRAPHICS_DINLINE_H_INCLUDED
#include <graphics/dinline.h>
#endif
#ifndef _GRAPHICS_FIXED_H_INCLUDED
#include <graphics/fixed.h>
#endif
__BEGIN_DECLS
extern int devg_hook_fini(disp_adapter_t *adapter);
__END_DECLS
#endif /* _GRAPHICS_DISPLAY_H_INCLUDED */

164
devg/public/graphics/disputil.h Обычный файл
Просмотреть файл

@ -0,0 +1,164 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifndef _GRAPHICS_DISPUTIL_H_INCLUDED
#define _GRAPHICS_DISPUTIL_H_INCLUDED
#ifndef __TYPES_H_INCLUDED
#include <sys/types.h>
#endif
#ifndef __INTTYPES_H_INCLUDED
#ifdef __QNXNTO__
#include <inttypes.h>
#endif
#endif
#ifndef __GULLIVER_H_INCLUDED
#include <gulliver.h>
#endif
#ifndef __PCI_H_INCLUDED
#include <hw/pci.h>
#endif
#ifndef __MMAN_H_INCLUDED
#include <sys/mman.h>
#endif
/* Flags for disp_pci_init() */
#ifdef __QNXNTO__
#define DISP_PCI_INIT_IRQ (PCI_INIT_IRQ)
#define DISP_PCI_INIT_ROM (PCI_INIT_ROM)
#define DISP_PCI_INIT_BASE0 (PCI_INIT_BASE0)
#define DISP_PCI_INIT_BASE1 (PCI_INIT_BASE1)
#define DISP_PCI_INIT_BASE2 (PCI_INIT_BASE2)
#define DISP_PCI_INIT_BASE3 (PCI_INIT_BASE3)
#define DISP_PCI_INIT_BASE4 (PCI_INIT_BASE4)
#define DISP_PCI_INIT_BASE5 (PCI_INIT_BASE5)
#define DISP_PCI_INIT_MASTER (PCI_MASTER_ENABLE)
#else
#define DISP_PCI_INIT_IRQ 0x00010000
#define DISP_PCI_INIT_ROM 0x00020000
#define DISP_PCI_INIT_BASE0 0x00040000
#define DISP_PCI_INIT_BASE1 0x00080000
#define DISP_PCI_INIT_BASE2 0x00100000
#define DISP_PCI_INIT_BASE3 0x00200008
#define DISP_PCI_INIT_BASE4 0x00400000
#define DISP_PCI_INIT_BASE5 0x00800000
#define DISP_PCI_INIT_MASTER 0x01000000
#endif
#define DISP_PCI_INIT_BASES (DISP_PCI_INIT_BASE0 | \
DISP_PCI_INIT_BASE1 | \
DISP_PCI_INIT_BASE2 | \
DISP_PCI_INIT_BASE3 | \
DISP_PCI_INIT_BASE4 | \
DISP_PCI_INIT_BASE5)
#define DISP_PCI_INIT_ALL (DISP_PCI_INIT_BASES | \
DISP_PCI_INIT_ROM | \
DISP_PCI_INIT_IRQ)
#define DISP_VM_MAX_ZONES 16
typedef struct {
uint8_t misc_out;
uint8_t seq[5];
uint8_t crtc[25];
uint8_t gc[9];
uint8_t attr[21];
uint8_t pal[64*3];
uint8_t pad[3]; /* Make struct a multiple of 4 bytes in size */
} disp_vga_state_t;
typedef struct disp_vm_pool * pool_handle_t;
__BEGIN_DECLS
/* Prototypes for functions in display driver utility lib */
int disp_register_adapter(disp_adapter_t *adp);
int disp_unregister_adapter(disp_adapter_t *adp);
int disp_crtc_calc(disp_crtc_settings_t *display);
int disp_mode_get_entry(disp_adapter_t *adapter, disp_crtc_settings_t *settings,
const char *fname, int xres, int yres, int refresh);
int disp_check_generic_mode(disp_adapter_t *adapter, disp_mode_info_t *mi,
int xres, int yres, int refresh);
int disp_acquire_vga_resources(disp_adapter_t *adapter);
int disp_release_vga_resources(disp_adapter_t *adapter);
void disp_perror(disp_adapter_t *adp, char *what);
void disp_printf(disp_adapter_t *adp, const char *fmt, ...);
void disp_wait_condition(disp_adapter_t *adapter,
int (*check)(disp_adapter_t *, void *arg), void *arg);
/* PCI access */
int disp_pci_init(disp_adapter_t *adapter, unsigned flags);
int disp_pci_shutdown(disp_adapter_t *adapter);
int disp_pci_info(unsigned *lastbus, unsigned *version, unsigned *hardware);
int disp_pci_read_config(disp_adapter_t *adapter, unsigned offset,
unsigned cnt, size_t size, void *bufptr);
int disp_pci_write_config(disp_adapter_t *adapter, unsigned offset,
unsigned cnt, size_t size, void *bufptr);
int disp_pci_dev_find(unsigned devid, unsigned venid, unsigned index,
unsigned *bus, unsigned *devfunc);
int disp_pci_dev_read_config(unsigned bus, unsigned devfunc, unsigned offset,
unsigned cnt, size_t size, void *bufptr);
int disp_pci_dev_write_config(unsigned bus, unsigned devfunc, unsigned offset,
unsigned cnt, size_t size, void *bufptr);
/* Memory management */
void *disp_mmap_device_memory(disp_paddr_t base, size_t len, int prot, int flags);
#ifndef __64__
unsigned long disp_mmap_device_io(size_t len, disp_paddr_t base);
#else
unsigned int disp_mmap_device_io(size_t len, disp_paddr_t base);
#endif
void disp_munmap_device_memory(void volatile * addr, size_t len);
int disp_munmap_device_io(uintptr_t io, size_t len);
disp_paddr_t disp_phys_addr(void *addr);
void *disp_getmem(int size, unsigned prot, unsigned flags);
void disp_freemem(void *addr, int size);
/* Video memory management */
disp_surface_t *disp_vm_alloc_surface(pool_handle_t pool, int width, int height,
int stride, unsigned format, unsigned flags);
int disp_vm_free_surface(disp_adapter_t *adapter, disp_surface_t *surf);
disp_surface_t * disp_vm_alloc_surface_external(disp_adapter_t *adapter,
int width, int height, unsigned flags);
void disp_vm_free_surface_external(disp_adapter_t *adapter,
disp_surface_t *surf);
unsigned int disp_vm_mem_avail(pool_handle_t pool);
pool_handle_t disp_vm_create_pool(disp_adapter_t *adapter,
disp_surface_t *surf, int bytealign);
int disp_vm_destroy_pool(disp_adapter_t *adapter,
pool_handle_t pool);
pool_handle_t disp_vm_create_pool_with_zones(disp_adapter_t *adapter,
disp_surface_t *surf, int bytealign, int num_zones, int * zone_sizes);
/* Color space conversion utilities */
disp_color_t disp_color_translate(disp_color_t *palette,
unsigned srcformat, unsigned dstformat, disp_color_t color);
/* Miscellaneous utilities */
void disp_usecspin(unsigned usecs);
void disp_delay(unsigned milliseconds);
char *disp_get_rom_image(disp_adapter_t *adapter, int code_type,
int *size, int map_pci_base_index, int map_offset);
/* X86/BIOS Multi-head support */
int disp_warm_boot(disp_adapter_t *adapter, uint8_t *rom);
int disp_get_primary_vga(disp_adapter_t *adapter, int *bus, int *devfunc);
int disp_primary_active(disp_adapter_t *adapter, int io_active, int mem_active);
int disp_device_active(disp_adapter_t *adapter, int io_active, int mem_active);
int disp_acquire_vga_resources(disp_adapter_t *adapter);
int disp_release_vga_resources(disp_adapter_t *adapter);
void disp_vga_restore_state(disp_adapter_t *ctx, disp_vga_state_t *state);
void disp_vga_save_state(disp_adapter_t *ctx, disp_vga_state_t *state);
/* VGA font support */
int disp_vgafont_load(char *fp, int char_count, int char_start);
int disp_vgafont_save(char *fp, int char_count, int char_start);
int disp_vgafont_push(void);
int disp_vgafont_pop(void);
__END_DECLS
#endif /* _GRAPHICS_DISPUTIL_H_INCLUDED */

418
devg/public/graphics/draw.h Обычный файл
Просмотреть файл

@ -0,0 +1,418 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifndef _GRAPHICS_DRAW_H_INCLUDED
#define _GRAPHICS_DRAW_H_INCLUDED
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#include <graphics/display.h>
#endif
typedef struct disp_2d_caps {
int size; /* Size of this struct */
unsigned accel_flags; /* Accelerated features */
unsigned flags; /* Other driver properties */
int min_stride; /* Minimum surface stride for 2d drawing */
int max_stride; /* Maximum surface stride for 2d drawing */
int stride_gran; /* stride (in bytes) must be a multiple of this */
unsigned poly_flags; /* polygon classes than can be handled (DISP_POLY_CLASS_*) */
unsigned poly_max_points; /* Max no. of points in a single polygon that h/w can handle */
} disp_2d_caps_t;
/* disp_2d_caps_t.accel_flags - flags defining which 2D operations are hardware accelerated */
#define DISP_2D_ACCEL_OPAQUE_BLIT 0x00000001 /* Simple, opaque blit operations */
#define DISP_2D_ACCEL_OPAQUE_FILL 0x00000001 /* Simple, opaque fill operations */
#define DISP_2D_ACCEL_MONO_PAT 0x00000002 /* Simple, draw operations with two colors and a pattern */
#define DISP_2D_ACCEL_TRANS_PAT 0x00000004 /* Simple, draw operations with a transparency pattern */
#define DISP_2D_ACCEL_SIMPLE_ROPS 0x00000008 /* Copy, XOR, AND and OR with a pattern */
#define DISP_2D_ACCEL_COMPLEX_ROPS 0x00000010 /* All 256 rop3 codes accelerated */
#define DISP_2D_ACCEL_SRCALPHA_BLEND_GLOBAL 0x00000020 /* Alpha blending with a global source factor is supported */
#define DISP_2D_ACCEL_SRCALPHA_BLEND_PIXEL 0x00000040 /* Alpha blending with a per pixel source factor is supported */
#define DISP_2D_ACCEL_SRCALPHA_BLEND_MAP 0x00000400 /* Alpha blending with an alpha map as source is supported */
#define DISP_2D_ACCEL_DSTALPHA_BLEND_GLOBAL 0x00000800 /* Alpha blending with a global destination factor */
#define DISP_2D_ACCEL_DSTALPHA_BLEND_PIXEL 0x00001000 /* Alpha blending with a per pixel destination factor */
#define DISP_2D_ACCEL_DSTALPHA_BLEND_MAP 0x00002000 /* Alpha blending with an alpha map as destination is supported */
#define DISP_2D_ACCEL_SRC_CHROMA 0x00000080 /* Source image chroma keying supported */
#define DISP_2D_ACCEL_DST_CHROMA 0x00000100 /* Destination image chroma keying supported */
#define DISP_2D_ACCEL_SCALED_BLIT 0x00000200 /* Scaled BitBlit supported */
#define DISP_2D_ACCEL_BRESENHAM_LINES 0x00004000 /* At least opaque Bresenham line drawing */
#define DISP_2D_ACCEL_SIMPLE_POLYGONS 0x00008000 /* Can at least render opaque convex polygons */
#define DISP_2D_ACCEL_COMPLEX_POLYGONS 0x00010000 /* Can at least render opaque complex polygons */
#define DISP_2D_ACCEL_ANTIALIAS 0x00020000 /* Can at least render anti-alias lines */
/* disp_2d_caps_t.flags - miscellaneous 2d renderer characteristics */
#define DISP_2D_SRC_DST_STRIDE_EQUAL 0x00000001 /* Separate source and destination strides cannot be specified */
#define DISP_2D_EXCLUSIVE_VM_ACCESS 0x00000002 /* Not safe to access any video memory surface with the CPU while the 2D engine is busy */
/* disp_draw_context_t.flags */
#define DISP_DRAW_FLAG_USE_DST_ALPHA 0x00000004
#define DISP_DRAW_FLAG_USE_ALPHA 0x00000008
#define DISP_DRAW_FLAG_USE_CHROMA 0x00000010
#define DISP_DRAW_FLAG_MONO_PATTERN 0x00000020
#define DISP_DRAW_FLAG_TRANS_PATTERN 0x00000040
#define DISP_DRAW_FLAG_SUBPIXEL 0x00000100
#define DISP_DRAW_FLAG_COMPLEX_ROP 0x00000200
#define DISP_DRAW_FLAG_SIMPLE_ROP 0x00000400
#define DISP_DRAW_FLAG_FILTERED_SCALING 0x00000800
#define DISP_DRAW_FLAG_SOFTWARE_SCALING 0x00001000
#define DISP_DRAW_FLAG_USE_PLANE_MASK 0x00002000
#define DISP_DRAW_FLAG_ANTIALIAS 0x00004000
#define DISP_DRAW_FLAG_TRANSFORM 0x00008000
#define DISP_DRAW_FLAG_USE_SOFT_AA 0x00010000
#define DISP_DRAW_FLAGS_UNDEFINED \
~(DISP_DRAW_FLAG_USE_DST_ALPHA | \
DISP_DRAW_FLAG_USE_ALPHA | DISP_DRAW_FLAG_USE_CHROMA | \
DISP_DRAW_FLAG_MONO_PATTERN | DISP_DRAW_FLAG_TRANS_PATTERN | \
DISP_DRAW_FLAG_SUBPIXEL | DISP_DRAW_FLAG_COMPLEX_ROP | \
DISP_DRAW_FLAG_SIMPLE_ROP | DISP_DRAW_FLAG_FILTERED_SCALING | \
DISP_DRAW_FLAG_SOFTWARE_SCALING | DISP_DRAW_FLAG_USE_PLANE_MASK | \
DISP_DRAW_FLAG_ANTIALIAS | DISP_DRAW_FLAG_TRANSFORM | DISP_DRAW_FLAG_USE_SOFT_AA)
#define DISP_DRAW_FLAG_ROP_NON_OPAQUE (DISP_DRAW_FLAG_COMPLEX_ROP|DISP_DRAW_FLAG_SIMPLE_ROP)
/* disp_draw_context_t.line_flags */
#define DISP_LINE_FLAG_DASH_MONO 0x00000001
#define DISP_LINE_FLAG_DASH_TRANS 0x00000002
/* disp_draw_context_t.pattern_format */
#define DISP_PATTERN_FORMAT_MONO_8x1 0x00000001
#define DISP_PATTERN_FORMAT_MONO_8x8 0x00000002
#define DISP_DRAW_SIMPLE(flags) (!((flags) & (DISP_DRAW_FLAG_SUBPIXEL | \
DISP_DRAW_FLAG_ROP_NON_OPAQUE | \
DISP_DRAW_FLAG_USE_DST_ALPHA | \
DISP_DRAW_FLAG_USE_ALPHA | \
DISP_DRAW_FLAG_USE_CHROMA | \
DISP_DRAW_FLAG_USE_PLANE_MASK | \
DISP_DRAW_FLAG_MONO_PATTERN | \
DISP_DRAW_FLAG_TRANS_PATTERN | \
DISP_DRAW_FLAG_ANTIALIAS | \
DISP_DRAW_FLAG_TRANSFORM | \
DISP_DRAW_FLAGS_UNDEFINED)))
#define DISP_DRAW_SIMPLE_PATTERN(flags) (!((flags) & (DISP_DRAW_FLAG_SUBPIXEL | \
DISP_DRAW_FLAG_ROP_NON_OPAQUE | \
DISP_DRAW_FLAG_USE_DST_ALPHA | \
DISP_DRAW_FLAG_USE_ALPHA | \
DISP_DRAW_FLAG_USE_CHROMA | \
DISP_DRAW_FLAG_USE_PLANE_MASK | \
DISP_DRAW_FLAG_ANTIALIAS | \
DISP_DRAW_FLAG_TRANSFORM | \
DISP_DRAW_FLAGS_UNDEFINED)))
#define DISP_DRAW_ROP_ONLY(flags) (!((flags) & (DISP_DRAW_FLAG_SUBPIXEL | \
DISP_DRAW_FLAG_USE_DST_ALPHA | \
DISP_DRAW_FLAG_USE_ALPHA | \
DISP_DRAW_FLAG_USE_CHROMA | \
DISP_DRAW_FLAG_USE_PLANE_MASK | \
DISP_DRAW_FLAG_MONO_PATTERN | \
DISP_DRAW_FLAG_TRANS_PATTERN | \
DISP_DRAW_FLAG_ANTIALIAS | \
DISP_DRAW_FLAG_TRANSFORM | \
DISP_DRAW_FLAGS_UNDEFINED)))
#define DISP_DRAW_ROP_PATTERN_ONLY(flags) (!((flags) & (DISP_DRAW_FLAG_SUBPIXEL | \
DISP_DRAW_FLAG_USE_DST_ALPHA | \
DISP_DRAW_FLAG_USE_ALPHA | \
DISP_DRAW_FLAG_USE_CHROMA | \
DISP_DRAW_FLAG_USE_PLANE_MASK | \
DISP_DRAW_FLAG_TRANS_PATTERN | \
DISP_DRAW_FLAG_ANTIALIAS | \
DISP_DRAW_FLAG_TRANSFORM | \
DISP_DRAW_FLAGS_UNDEFINED)))
#define DISP_DRAW_SIMPLE_ROP_ONLY(flags) (!((flags) & (DISP_DRAW_FLAG_SUBPIXEL | \
DISP_DRAW_FLAG_COMPLEX_ROP | \
DISP_DRAW_FLAG_USE_DST_ALPHA | \
DISP_DRAW_FLAG_USE_ALPHA | \
DISP_DRAW_FLAG_USE_CHROMA | \
DISP_DRAW_FLAG_USE_PLANE_MASK | \
DISP_DRAW_FLAG_MONO_PATTERN | \
DISP_DRAW_FLAG_TRANS_PATTERN | \
DISP_DRAW_FLAG_ANTIALIAS | \
DISP_DRAW_FLAG_TRANSFORM | \
DISP_DRAW_FLAGS_UNDEFINED)))
#define DISP_DRAW_SIMPLE_ROP_PATTERN_ONLY(flags) (!((flags) & (DISP_DRAW_FLAG_SUBPIXEL | \
DISP_DRAW_FLAG_COMPLEX_ROP | \
DISP_DRAW_FLAG_USE_DST_ALPHA | \
DISP_DRAW_FLAG_USE_ALPHA | \
DISP_DRAW_FLAG_USE_CHROMA | \
DISP_DRAW_FLAG_USE_PLANE_MASK | \
DISP_DRAW_FLAG_ANTIALIAS | \
DISP_DRAW_FLAG_TRANSFORM | \
DISP_DRAW_FLAGS_UNDEFINED)))
/* "flags" parameter for context "draw_poly_line" entrypoint */
#define DISP_DRAW_POLYLINE_CLOSE 0x00000001 /* Connect the first and last point */
/* "flags" parameter for core/context "fill_poly" entrypoint */
#define DISP_DRAW_FILLPOLY_ANTIALIAS 0x00000001 /* Antialiased the filled polygon edges */
/* disp_draw_context_t.line_join */
#define DISP_DRAW_LINEJOIN_BUTT 0x00000000
#define DISP_DRAW_LINEJOIN_BEVEL 0x00000001
#define DISP_DRAW_LINEJOIN_ROUND 0x00000002
#define DISP_DRAW_LINEJOIN_MITER 0x00000003
/* disp_draw_context_t.cap_style */
#define DISP_DRAW_CAPSTYLE_BUTT 0x00000000
#define DISP_DRAW_CAPSTYLE_ROUND 0x00000001
#define DISP_DRAW_CAPSTYLE_SQUARE 0x00000002
/* disp_draw_context_t.poly_fill */
#define DISP_DRAW_POLYFILL_EVENODD 0x00000000
#define DISP_DRAW_POLYFILL_NON_ZERO 0x00000001
#define DISP_DRAW_POLYFILL_CONVEX 0x00000002
#define DISP_DRAW_CAPSTYLE_MONOTONE 0x00000003
typedef enum {
DISP_DRAW_DEVCTL_STATS = 1, /* for used with devg-stats module */
} disp_draw_devctl_t;
/* Contains everything the flat frame buffer lib needs in order to draw */
typedef struct disp_draw_context {
int size;
disp_adapter_t *adapter;
void *gd_ctx; /* Graphics drivers private context */
struct disp_draw_corefuncs *cfuncs; /* Allow software routines to call into hw routines */
unsigned flags; /* Draw flags */
disp_color_t fgcolor;
disp_color_t bgcolor;
struct disp_draw_corefuncs *corefuncs_sw; /* S/W only core functions for currently targetted surface */
struct disp_draw_contextfuncs *ctxfuncs_sw; /* S/W only context functions */
uint8_t *pat;
unsigned short pat_xoff;
unsigned short pat_yoff;
unsigned short pattern_format;
unsigned short rop3;
unsigned short chroma_mode;
disp_color_t chroma_color0;
disp_color_t chroma_color1;
disp_color_t chroma_mask;
unsigned alpha_mode;
unsigned s_alpha; /* Global multiplier 1 */
unsigned d_alpha; /* Global multiplier 2 */
unsigned alpha_map_xoff, alpha_map_yoff;
disp_surface_t *alpha_map;
disp_surface_t *dsurf; /* Default destination surface */
unsigned char *sysram_workspace; /* Scratch workspace in system RAM */
int sysram_workspace_size; /* Size of scratch workspace */
unsigned plane_mask;
int clip_left;
int clip_top;
int clip_right;
int clip_bottom;
int reserved0;
int reserved1;
int reserved2;
int reserved3;
unsigned char *palette_lut; /* 4k palette look up table (444 true color to palette index conversions) */
disp_color_t *dest_palette; /* Palette to be used for 8-bit alpha blending */
int dest_palette_size;
disp_fx_t xform_matrix[4]; /* 2x2 matrix */
int xlate_x;
int xlate_y;
unsigned line_flags;
int line_join;
uint32_t line_pat;
int line_repeat;
int line_initial_offset;
int cap_style;
int poly_fill;
disp_surface_t *dst_alpha_map;
unsigned dst_alpha_map_xoff, dst_alpha_map_yoff;
uintptr_t reserved[5];
} disp_draw_context_t;
__BEGIN_DECLS
typedef struct disp_nl_accessfuncs {
void (*writescan)(disp_draw_context_t *ctx, disp_surface_t *dst,
int x, int y, int npixels, void *data);
void (*readscan)(disp_draw_context_t *ctx, disp_surface_t *src,
int x, int y, int npixels, void *data);
void (*setscan)(disp_draw_context_t *ctx, disp_surface_t *dst,
int x, int y, int npixels, disp_color_t color);
void (*setscan_mono)(disp_draw_context_t *ctx, disp_surface_t *dst,
int x, int y, int npixels,
disp_color_t fgcolor, disp_color_t bgcolor, uint8_t pat, int patidx);
void (*setscan_trans)(disp_draw_context_t *ctx, disp_surface_t *dst,
int x, int y, int npixels, disp_color_t color, uint8_t pat, int patidx);
void (*setscan_bitmap)(disp_draw_context_t *ctx, disp_surface_t *dst,
int x, int y, int width,
disp_color_t fgcolor, disp_color_t bgcolor, int bit0_offset,
int transparent, uint8_t *sptr);
} disp_nl_accessfuncs_t;
typedef struct disp_draw_corefuncs {
void (*wait_idle)(disp_draw_context_t *);
int (*hw_idle)(disp_adapter_t *adapter, void *ignored);
/* Simple drawing functions */
void (*draw_span)(disp_draw_context_t *context,
disp_color_t color, int x1, int x2, int y);
void (*draw_span_list)(disp_draw_context_t *context, int count,
disp_color_t color, int x1[], int x2[], int y[]);
void (*draw_solid_rect)(disp_draw_context_t *context,
disp_color_t color, int x1, int y1, int x2, int y2);
void (*draw_line_pat8x1)(disp_draw_context_t *context,
disp_color_t fgcolor, disp_color_t bgcolor,
int x1, int x2, int y, uint8_t pattern);
void (*draw_line_trans8x1)(disp_draw_context_t *context,
disp_color_t color, int x1, int x2, int y, uint8_t pattern);
void (*draw_rect_pat8x8)(disp_draw_context_t *context,
disp_color_t fgcolor, disp_color_t bgcolor, int x1, int y1,
int x2, int y2);
void (*draw_rect_trans8x8)(disp_draw_context_t *context,
disp_color_t color, int x1, int y1, int x2, int y2);
void (*blit1)(disp_draw_context_t *context,
int sx, int sy, int dx, int dy, int width, int height);
void (*blit2)(disp_draw_context_t *context,
disp_surface_t *src, disp_surface_t *dst,
int sx, int sy, int dx, int dy, int width, int height);
void (*draw_bitmap)(disp_draw_context_t *context,
uint8_t *image, int sstride, int bit0_offset,
disp_color_t fgcolor, disp_color_t bgcolor,
int transparent, int dx, int dy, int width, int height);
void (*update_draw_surface)(disp_draw_context_t *context);
void (*update_pattern)(disp_draw_context_t *context);
void (*scaled_blit)(disp_draw_context_t *context,
disp_surface_t *src, disp_surface_t *dst,
int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2);
void (*draw_line)(disp_draw_context_t *context, disp_color_t color,
int x1, int y1, int x2, int y2, unsigned flags);
int (*fill_poly)(disp_draw_context_t *ctx, disp_color_t color,
disp_point_t *pointlist, int npoints, unsigned flags);
int (*get_bresenham_params)(disp_draw_context_t *ctx,
int x1, int y1, int x2, int y2,
int *initial_error, int *major_inc, int *minor_inc);
void (*update_transform)(disp_draw_context_t *context);
void (*update_clipping)(disp_draw_context_t *context);
void (*blend_pixels)(disp_draw_context_t *ctx, disp_color_t color,
int x[], int y[], uint8_t alpha[], int npixels);
disp_nl_accessfuncs_t * (*get_nlfuncs)(disp_draw_context_t *ctx,
disp_surface_t *surf);
void (*reserved[8])(void);
} disp_draw_corefuncs_t;
typedef struct disp_draw_contextfuncs {
void (*draw_span)(disp_draw_context_t *context,
unsigned x1, unsigned x2, unsigned y);
void (*draw_span_list)(disp_draw_context_t *context, int count,
int x1[], int x2[], int y[]);
void (*draw_rect)(disp_draw_context_t *context,
unsigned x1, unsigned y1, unsigned x2, unsigned y2);
void (*blit)(disp_draw_context_t *context, disp_surface_t *src,
disp_surface_t *dst, unsigned sx, unsigned sy,
unsigned dx, unsigned dy, unsigned width, unsigned height);
/* Notify of changes in draw context */
void (*update_general)(disp_draw_context_t *context);
void (*update_color)(disp_draw_context_t *context);
void (*update_rop3)(disp_draw_context_t *context);
void (*update_chroma)(disp_draw_context_t *context);
void (*update_alpha)(disp_draw_context_t *context);
void (*scaled_blit)(disp_draw_context_t *context,
disp_surface_t *src, disp_surface_t *dst,
int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2);
void (*update_planemask)(disp_draw_context_t *context);
void (*draw_line)(disp_draw_context_t *context,
int x1, int y1, int x2, int y2, unsigned flags);
int (*fill_poly)(disp_draw_context_t *ctx,
disp_point_t *pointlist, int npoints, unsigned flags);
int (*draw_polyline)(disp_draw_context_t *ctx,
disp_point_t *pointlist, int npoints, int width, unsigned flags);
void (*update_line)(disp_draw_context_t *context);
void (*blend_pixels)(disp_draw_context_t *ctx,
int x[], int y[], uint8_t alpha[], int npixels);
void (*reserved[8])(void);
} disp_draw_contextfuncs_t;
typedef struct disp_draw_miscfuncs {
int (*init)(disp_adapter_t *adapter, char *optstring);
void (*fini)(disp_adapter_t *adapter);
void (*module_info)(disp_adapter_t *adapter, disp_module_info_t *info);
int (*set_palette)(disp_adapter_t *ctx,
int index, int count, disp_color_t *pal);
int (*set_hw_cursor)(disp_adapter_t *ctx,
uint8_t *fg_bmp, uint8_t *bg_bmp,
unsigned fg_color, unsigned bg_color,
int hotspot_x, int hotspot_y,
int size_x, int size_y, int bmp_stride);
void (*enable_hw_cursor)(disp_adapter_t *ctx);
void (*disable_hw_cursor)(disp_adapter_t *ctx);
void (*set_hw_cursor_pos)(disp_adapter_t *ctx, int x, int y);
void (*flushrect)(disp_draw_context_t *ctx,
int x1, int y1, int x2, int y2);
int (*service_msg)(disp_draw_context_t *ctx,
void *data_in, int nbytes, void *data_out, int out_buffer_size);
int (*get_2d_caps)(disp_adapter_t *adapter,
disp_surface_t *surf, disp_2d_caps_t *caps);
int (*get_corefuncs_sw)(disp_adapter_t *adapter, unsigned pixel_format,
disp_draw_corefuncs_t *fns, int tabsize);
int (*get_contextfuncs_sw)(disp_adapter_t *adapter,
disp_draw_contextfuncs_t *fns, int tabsize);
int (*set_power_mode)(disp_adapter_t *adapter, pm_power_mode_t mode);
int (*end_of_draw)(disp_adapter_t *adapter);
/* Support for rendering from another process */
int (*attach_external)(disp_adapter_t *adapter, disp_aperture_t aper[]);
int (*detach_external)(disp_adapter_t *adapter);
int (*recover)(disp_adapter_t *adapter);
int (*wait_idle)(disp_adapter_t *adapter);
int (*devctl)(disp_adapter_t *adapter, disp_draw_devctl_t cmd,
void *data_in, int nbytes, void *data_out, int *out_buffer_size);
int (*terminate_notify)(disp_adapter_t *adapter, pid_t pid);
void (*set_memory_zone)(disp_adapter_t *adapter, int zone);
void (*reserved[6])(void);
} disp_draw_miscfuncs_t;
typedef int (*get_miscfuncs_t)(disp_adapter_t *adapter,
disp_draw_miscfuncs_t *fns, int tabsize);
typedef int (*get_corefuncs_t)(disp_adapter_t *adapter, unsigned pixel_format,
disp_draw_corefuncs_t *fns, int tabsize);
typedef int (*get_contextfuncs_t)(disp_adapter_t *adapter,
disp_draw_contextfuncs_t *fns, int tabsize);
/* Main draw driver entry points */
extern WINSIM_API int devg_get_miscfuncs(disp_adapter_t *adapter,
disp_draw_miscfuncs_t *fns, int tabsize);
extern WINSIM_API int devg_get_corefuncs(disp_adapter_t *adapter, unsigned pixel_format,
disp_draw_corefuncs_t *fns, int tabsize);
extern WINSIM_API int devg_get_contextfuncs(disp_adapter_t *adapter,
disp_draw_contextfuncs_t *fns, int tabsize);
__END_DECLS
#endif /* _GRAPHICS_DRAW_H_INCLUDED */

106
devg/public/graphics/extra/devctl.h Обычный файл
Просмотреть файл

@ -0,0 +1,106 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifndef _GRAPHICS_EXTRA_DEVCTL_H_INCLUDED
#define _GRAPHICS_EXTRA_DEVCTL_H_INCLUDED
/* disp_modefuncs_t::devctl() commands */
#define DEVCTL_DDC (0x1000) /* driver side "ddc" utility support */
#define DEVCTL_DISPLAY_INFO (0x2000) /* driver side "display-info" utility support */
/* disp_modefuncs_t::devctl() data types */
typedef struct devctl_ddc
{
#define DEVCTL_DDC_MODE_DISPLAY (0x0)
#define DEVCTL_DDC_MODE_BUS (0x1)
uint8_t mode; /* DDC request mode */
uint8_t bus; /* DDC bus mode */
} devctl_ddc_t;
typedef devctl_ddc_t devctl_ddc_request_t;
typedef struct devctl_display_mode
{
#define DEVCTL_DISPLAY_INFO_DISPLAYS (0x0)
#define DEVCTL_DISPLAY_INFO_DISPLAY (0x1)
#define DEVCTL_DISPLAY_INFO_LAYER (0x2)
struct devctl_display_mode_request {
uint8_t mode; /* Display config request mode */
uint8_t display; /* Display id */
uint8_t layer; /* Display layer id */
uint8_t unused;
} __attribute__((packed)) request;
#define DEVCTL_DISPLAY_INFO_IFACE_NONE (0x0)
#define DEVCTL_DISPLAY_INFO_IFACE_VGA (0x1)
#define DEVCTL_DISPLAY_INFO_IFACE_DVI (0x2)
#define DEVCTL_DISPLAY_INFO_IFACE_HDMI (0x3)
#define DEVCTL_DISPLAY_INFO_IFACE_DP (0x4)
#define DEVCTL_DISPLAY_INFO_IFACE_LVDS (0x5)
#define DEVCTL_DISPLAY_INFO_IFACE_eDP (0x6)
#define DEVCTL_DISPLAY_INFO_IFACE_DSI (0x7)
#define DEVCTL_DISPLAY_INFO_STATUS_FAIL (0xa)
#define DEVCTL_DISPLAY_INFO_STATUS_OK (0xb)
#define DEVCTL_DISPLAY_INFO_STATE_OFF (0xa)
#define DEVCTL_DISPLAY_INFO_STATE_ON (0xb)
#define DEVCTL_DISPLAY_INFO_CHROMA_NONE (0x0)
#define DEVCTL_DISPLAY_INFO_CHROMA_SRC (0x1)
#define DEVCTL_DISPLAY_INFO_CHROMA_DST (0x2)
struct devctl_display_mode_reply {
uint8_t status; /* Request status (DEVCTL_DISPLAY_INFO_STATUS_*) */
uint8_t displays; /* Display count */
uint8_t unused[2];
struct { /* Display info */
uint8_t id; /* id */
uint8_t state; /* state (DEVCTL_DISPLAY_INFO_STATE_*) */
uint8_t layers; /* layer count */
uint8_t unused;
uint32_t width; /* width */
uint32_t height; /* height */
uint32_t refresh; /* refresh rate */
uint32_t interface; /* display intercafe (DEVCTL_DISPLAY_INFO_IFACE_*) */
} __attribute__((packed)) display;
struct { /* Display layer info */
uint8_t id; /* id */
uint8_t state; /* state (DEVCTL_DISPLAY_INFO_STATE_*) */
uint8_t unused[2];
uint32_t sid; /* GF surface ID */
uint32_t format; /* format (DISP_LAYER_FORMAT_*) */
uint32_t width; /* width */
uint32_t height; /* height */
uint32_t stride; /* stride */
uint32_t x; /* x position */
uint32_t y; /* y position */
uint64_t addr; /* phys address */
struct {
struct {
uint32_t x1; /* x1 source viewport coordinate */
uint32_t y1; /* y1 source viewport coordinate */
uint32_t x2; /* x2 source viewport coordinate */
uint32_t y2; /* y2 source viewport coordinate */
} __attribute__((packed)) source;
struct {
uint32_t x1; /* x1 source viewport coordinate */
uint32_t y1; /* y1 source viewport coordinate */
uint32_t x2; /* x2 source viewport coordinate */
uint32_t y2; /* y2 source viewport coordinate */
} __attribute__((packed)) destination;
} __attribute__((packed)) viewport;
struct {
uint32_t mode; /* chroma key mode (#define DEVCTL_DISPLAY_INFO_CHROMA_*) */
uint32_t color; /* chroma key color */
} __attribute__((packed)) chroma_key;
} __attribute__((packed)) layer;
} __attribute__((packed)) reply;
} devctl_display_mode_t;
typedef struct devctl_display_mode_request devctl_display_mode_request_t;
typedef struct devctl_display_mode_reply devctl_display_mode_reply_t;
#endif /* _GRAPHICS_EXTRA_DEVCTL_H_INCLUDED */

196
devg/public/graphics/ffb.h Обычный файл
Просмотреть файл

@ -0,0 +1,196 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifndef _GRAPHICS_FFB_H_INCLUDED
#define _GRAPHICS_FFB_H_INCLUDED
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#include <graphics/display.h>
#endif
typedef struct {
int rbank_size; /* Size of read aperture */
int wbank_size; /* Size of write aperture */
int rbank_current;
int wbank_current;
void (*set_rbank)(void *arg, int bankno);
void (*set_wbank)(void *arg, int bankno);
uint8_t *rptr; /* Virtual address of read aperture */
uint8_t *wptr; /* Virtual address of write aperture */
void *arg; /* Argument to pass to bank-switch routines */
uint32_t reserved[4];
} ffb_bankinfo_t;
__BEGIN_DECLS
/* Core functions */
void ffb_core_blit1(disp_draw_context_t *ctx,
int sx, int sy, int dx, int dy, int width, int height);
void ffb_core_blit2(disp_draw_context_t *ctx,
disp_surface_t *src, disp_surface_t *dst,
int sx, int sy, int dx, int dy, int width, int height);
void ffb_core_scaled_blit(disp_draw_context_t *ctx,
disp_surface_t *src, disp_surface_t *dst,
int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2);
void ffb_core_draw_line(disp_draw_context_t *ctx, disp_color_t color,
int x1, int y1, int x2, int y2, unsigned flags);
void ffb_core_blend_pixels(disp_draw_context_t *ctx,
disp_color_t color, int x[], int y[], uint8_t alpha[], int npixels);
int ffb_core_fill_poly(disp_draw_context_t *ctx, disp_color_t color,
disp_point_t *pointlist, int npoints, unsigned flags);
int ffb_get_bresenham_params(disp_draw_context_t *ctx,
int x1, int y1, int x2, int y2,
int *initial_error, int *major_inc, int *minor_inc);
void ffb_draw_span_8(disp_draw_context_t *context,
disp_color_t color, int x1, int x2, int y);
void ffb_draw_span_list_8(disp_draw_context_t *context, int count,
disp_color_t color, int x1[], int x2[], int y[]);
void ffb_draw_solid_rect_8(disp_draw_context_t *context,
disp_color_t color, int x1, int y1, int x2, int y2);
void ffb_draw_line_pat8x1_8(disp_draw_context_t *context, disp_color_t fgcolor,
disp_color_t bgcolor, int x1, int x2, int y, uint8_t pattern);
void ffb_draw_line_trans8x1_8(disp_draw_context_t *context, disp_color_t color,
int x1, int x2, int y, uint8_t pattern);
void ffb_draw_rect_pat8x8_8(disp_draw_context_t *context,
disp_color_t fgcolor, disp_color_t bgcolor, int x1, int y1,
int x2, int y2);
void ffb_draw_rect_trans8x8_8(disp_draw_context_t *context,
disp_color_t color, int x1, int y1,
int x2, int y2);
void ffb_draw_bitmap_8(disp_draw_context_t *context,
uint8_t *image, int sstride, int bit0_offset,
disp_color_t fgcolor, disp_color_t bgcolor,
int transparent, int dx, int dy, int width, int height);
void ffb_draw_span_16(disp_draw_context_t *context,
disp_color_t color, int x1, int x2, int y);
void ffb_draw_span_list_16(disp_draw_context_t *context, int count,
disp_color_t color, int x1[], int x2[], int y[]);
void ffb_draw_solid_rect_16(disp_draw_context_t *context,
disp_color_t color, int x1, int y1, int x2, int y2);
void ffb_draw_line_pat8x1_16(disp_draw_context_t *context, disp_color_t fgcolor,
disp_color_t bgcolor, int x1, int x2, int y, uint8_t pattern);
void ffb_draw_line_trans8x1_16(disp_draw_context_t *context, disp_color_t color,
int x1, int x2, int y, uint8_t pattern);
void ffb_draw_rect_pat8x8_16(disp_draw_context_t *context,
disp_color_t fgcolor, disp_color_t bgcolor, int x1, int y1,
int x2, int y2);
void ffb_draw_rect_trans8x8_16(disp_draw_context_t *context,
disp_color_t color, int x1, int y1,
int x2, int y2);
void ffb_draw_bitmap_16(disp_draw_context_t *context,
uint8_t *image, int sstride, int bit0_offset,
disp_color_t fgcolor, disp_color_t bgcolor,
int transparent, int dx, int dy, int width, int height);
void ffb_draw_span_24(disp_draw_context_t *context,
disp_color_t color, int x1, int x2, int y);
void ffb_draw_span_list_24(disp_draw_context_t *context, int count,
disp_color_t color, int x1[], int x2[], int y[]);
void ffb_draw_solid_rect_24(disp_draw_context_t *context,
disp_color_t color, int x1, int y1, int x2, int y2);
void ffb_draw_line_pat8x1_24(disp_draw_context_t *context, disp_color_t fgcolor,
disp_color_t bgcolor, int x1, int x2, int y, uint8_t pattern);
void ffb_draw_line_trans8x1_24(disp_draw_context_t *context, disp_color_t color,
int x1, int x2, int y, uint8_t pattern);
void ffb_draw_rect_pat8x8_24(disp_draw_context_t *context,
disp_color_t fgcolor, disp_color_t bgcolor, int x1, int y1,
int x2, int y2);
void ffb_draw_rect_trans8x8_24(disp_draw_context_t *context,
disp_color_t color, int x1, int y1,
int x2, int y2);
void ffb_draw_bitmap_24(disp_draw_context_t *context,
uint8_t *image, int sstride, int bit0_offset,
disp_color_t fgcolor, disp_color_t bgcolor,
int transparent, int dx, int dy, int width, int height);
void ffb_draw_span_32(disp_draw_context_t *context,
disp_color_t color, int x1, int x2, int y);
void ffb_draw_span_list_32(disp_draw_context_t *context, int count,
disp_color_t color, int x1[], int x2[], int y[]);
void ffb_draw_solid_rect_32(disp_draw_context_t *context,
disp_color_t color, int x1, int y1, int x2, int y2);
void ffb_draw_line_pat8x1_32(disp_draw_context_t *context, disp_color_t fgcolor,
disp_color_t bgcolor, int x1, int x2, int y, uint8_t pattern);
void ffb_draw_line_trans8x1_32(disp_draw_context_t *context, disp_color_t color,
int x1, int x2, int y, uint8_t pattern);
void ffb_draw_rect_pat8x8_32(disp_draw_context_t *context,
disp_color_t fgcolor, disp_color_t bgcolor, int x1, int y1,
int x2, int y2);
void ffb_draw_rect_trans8x8_32(disp_draw_context_t *context,
disp_color_t color, int x1, int y1,
int x2, int y2);
void ffb_draw_bitmap_32(disp_draw_context_t *context,
uint8_t *image, int sstride, int bit0_offset,
disp_color_t fgcolor, disp_color_t bgcolor,
int transparent, int dx, int dy, int width, int height);
/* Draw state update notify functions */
void ffb_update_draw_surface(disp_draw_context_t *context);
void ffb_update_pattern(disp_draw_context_t *context);
void ffb_update_transform(disp_draw_context_t *context);
void ffb_update_clipping(disp_draw_context_t *context);
/* Context functions */
void ffb_ctx_draw_span(disp_draw_context_t *context,
unsigned x1, unsigned x2, unsigned y);
void ffb_ctx_draw_span_list(disp_draw_context_t *context,
int count, int x1[], int x2[], int y[]);
void ffb_ctx_draw_rect(disp_draw_context_t *context,
unsigned x1, unsigned y1, unsigned x2, unsigned y2);
void ffb_ctx_blit(disp_draw_context_t *ctx,
disp_surface_t *src, disp_surface_t *dst,
unsigned sx, unsigned sy, unsigned dx, unsigned dy,
unsigned width, unsigned height);
void ffb_ctx_scaled_blit(disp_draw_context_t *ctx,
disp_surface_t *src, disp_surface_t *dst,
int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2);
void ffb_ctx_draw_line(disp_draw_context_t *ctx,
int x1, int y1, int x2, int y2, unsigned flags);
int ffb_ctx_fill_poly(disp_draw_context_t *ctx,
disp_point_t *point_list, int npoints, unsigned flags);
int ffb_ctx_draw_polyline(disp_draw_context_t *ctx,
disp_point_t *pointlist, int npoints, int width, unsigned flags);
void ffb_ctx_blend_pixels(disp_draw_context_t *ctx,
int x[], int y[], uint8_t alpha[], int npixels);
/* Miscellaneous */
void ffb_wait_idle(disp_draw_context_t *context);
int ffb_hw_idle(disp_adapter_t *context, void *ignored);
void ffb_set_draw_surface(disp_draw_context_t *context, disp_surface_t *surf);
int ffb_get_2d_caps(disp_adapter_t *adapter, disp_surface_t *surf,
disp_2d_caps_t *caps);
/* Draw state update notify functions */
void ffb_ctx_update_general(disp_draw_context_t *context);
void ffb_ctx_update_color(disp_draw_context_t *context);
void ffb_ctx_update_rop3(disp_draw_context_t *context);
void ffb_ctx_update_chroma(disp_draw_context_t *context);
void ffb_ctx_update_alpha(disp_draw_context_t *context);
void ffb_ctx_update_planemask(disp_draw_context_t *context);
void ffb_ctx_update_line(disp_draw_context_t *context);
/* Draw function retrieval routines */
int ffb_get_corefuncs(disp_adapter_t *context,
unsigned pixel_format, disp_draw_corefuncs_t *funcs, int tabsize);
int ffb_get_contextfuncs(disp_adapter_t *context, disp_draw_contextfuncs_t *funcs, int tabsize);
typedef void (*ffb_cvtfunc_t)(void *, void *, int, void *);
ffb_cvtfunc_t ffb_cvtfunc(disp_surface_t *src,
disp_surface_t *dst, void **extra);
ffb_cvtfunc_t ffb_cvtfunc_swap(disp_surface_t *src,
disp_surface_t *dst, void **extra);
/* Scanline scaling-in-place routine */
void ffb_scale_scanline(unsigned pixel_format,
uint8_t *data, int swidth, int dwidth, int startpixel, int npixels);
__END_DECLS
#endif /* _GRAPHICS_FFB_H_INCLUDED */

107
devg/public/graphics/fixed.h Обычный файл
Просмотреть файл

@ -0,0 +1,107 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifndef _GRAPHICS_FIXED_H_INCLUDED
#define _GRAPHICS_FIXED_H_INCLUDED
#include <stdlib.h>
/*
* Fixed point types and macros. Fixed point 3D drivers should define
* DISP_FIXED_POINT before including this file.
*/
#ifdef DISP_FIXED_POINT
typedef int disp_real;
#define DISP_REALFX(__r) (__r)
#else
typedef float disp_real;
#define DISP_REALFX(__r) ((int)((__r)*0x10000))
#endif
#define DISP_FXHALF 0x8000
#ifdef DISP_FIXED_POINT
#define DISP_REALHALF DISP_FXHALF
#else
#define DISP_REALHALF 0.5
#endif
#define DISP_INTFX(__i) ((__i)<<16)
#define DISP_FXMUL(__a, __b) \
((int)(((int64_t)(__a)*(int64_t)(__b)) >> 16))
/* Multiply two real numbers */
#ifdef DISP_FIXED_POINT
#define DISP_REALMUL(__r1, __r2) DISP_FXMUL((__r1), (__r2))
#else
#define DISP_REALMUL(__r1, __r2) ((__r1) * (__r2))
#endif
/* Divide one real number by another */
#ifdef DISP_FIXED_POINT
#define DISP_REALDIV(__r1, __r2) DISP_FXDIV((__r1), (__r2))
#else
#define DISP_REALDIV(__r1, __r2) ((__r1) / (__r2))
#endif
/* Macro to convert from fixed point to internal non-integral format */
#ifdef DISP_FIXED_POINT
#define DISP_FXREAL(__fx) (__fx)
#else
#define DISP_FXREAL(__fx) ((float)(__fx)/0x10000)
#endif
/* Convert an integral value to a real value */
#ifdef DISP_FIXED_POINT
#define DISP_INTREAL(__i) ((disp_real)((__i) << 16))
#else
#define DISP_INTREAL(__i) ((disp_real)(__i))
#endif
/* Convert a real value to an integral value */
#ifdef DISP_FIXED_POINT
#define DISP_REALINT(__r) ((int)(__r) >> 16)
#else
#define DISP_REALINT(__r) ((int)(__r))
#endif
#ifdef __X86__
static __inline__ int
DISP_FXDIV(int a, int b)
{
int result;
if (abs(a >> 14) > abs(b)) {
/* Could cause overflow exception */
if (((unsigned)a ^ (unsigned)b) & (1<<31))
return 1<<31; /* Negative result */
else
return 0x7fffffff;
}
asm (
"xorl %%eax,%%eax \n"
"shrdl $16,%%edx,%%eax \n"
"sarl $16,%%edx \n"
"idivl %%ecx \n"
: "=a" (result)
: "d" (a), "c" (b)
);
return result;
}
#else
#ifdef DISP_FIXED_POINT
#define DISP_FXDIV(__a, __b) \
((int)(((int64_t)(__a) << 16)/(__b)))
#else
#define DISP_FXDIV(__a, __b) \
((int)(((float)(__a)*0x10000)/(__b)))
#endif
#endif
#endif /* _GRAPHICS_FIXED_H_INCLUDED */

150
devg/public/graphics/legacy_vcap.h Обычный файл
Просмотреть файл

@ -0,0 +1,150 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/* Types and defines for TV tuner / video capture support */
#ifndef _GRAPHICS_LEGACY_VCAP_H_INCLUDED
#define _GRAPHICS_LEGACY_VCAP_H_INCLUDED
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#include <graphics/display.h>
#endif
/* Capture / tuner device capability flags (disp_vcap_channel_caps_t.flags) */
#define DISP_VCAP_CAP_SOURCE_TUNER 0x00000001
#define DISP_VCAP_CAP_SOURCE_SVIDEO 0x00000002
#define DISP_VCAP_CAP_SOURCE_COMPOSITE 0x00000004
#define DISP_VCAP_CAP_BRIGHTNESS_ADJUST 0x00000008
#define DISP_VCAP_CAP_CONTRAST_ADJUST 0x00000010
#define DISP_VCAP_CAP_SATURATION_ADJUST 0x00000020
#define DISP_VCAP_CAP_HUE_ADJUST 0x00000040
#define DISP_VCAP_CAP_VOLUME_ADJUST 0x00000080
#define DISP_VCAP_CAP_AUDIO_SOURCE_MUTE 0x00000100 /* Audio source can be muted */
#define DISP_VCAP_CAP_AUDIO_SOURCE_TUNER 0x00000200
#define DISP_VCAP_CAP_AUDIO_SOURCE_EXTERNAL 0x00000400 /* Line in */
#define DISP_VCAP_CAP_TEMPORAL_DECIMATION 0x00000800
#define DISP_VCAP_CAP_DOWNSCALING 0x00001000
#define DISP_VCAP_CAP_UPSCALING 0x00002000
#define DISP_VCAP_CAP_CROPPING 0x00004000
#define DISP_VCAP_CAP_DOUBLE_BUFFER 0x00008000
/* Capture / tuner device property flags (disp_vcap_channel_props_t.flags) */
#define DISP_VCAP_FLAG_AFT_ON 0x00000001
#define DISP_VCAP_FLAG_RUNNING 0x00000002
#define DISP_VCAP_FLAG_DOUBLE_BUFFER 0x00000004
#define DISP_VCAP_FLAG_SYNC_WITH_SCALER 0x00000008
/* Capture / tuner device status flags (disp_vcap_channel_status_t.flags) */
#define DISP_VCAP_STATUS_TUNED 0x00000001 /* Tuner PLL has locked */
#define DISP_VCAP_STATUS_CHANNEL_PRESENT 0x00000002 /* Good signal detected on current Radio or TV channel */
#define DISP_VCAP_STATUS_VIDEO_PRESENT 0x00000004 /* Video signal detected */
#define DISP_VCAP_STATUS_STEREO 0x00000008 /* Stereo audio signal */
/* Capture / tuner device status flags (disp_vcap_channel_props_t.source) */
#define DISP_VCAP_SOURCE_TUNER 0x00000001
#define DISP_VCAP_SOURCE_SVIDEO 0x00000002
#define DISP_VCAP_SOURCE_COMPOSITE 0x00000004
#define DISP_VCAP_AUDIO_SOURCE_MUTE 0x00000100
#define DISP_VCAP_AUDIO_SOURCE_TUNER 0x00000200
#define DISP_VCAP_AUDIO_SOURCE_EXTERNAL 0x00000400
#define DISP_VCAP_UPDATE_VIDEO_SOURCE 0x00000001 /* "video_source" has changed */
#define DISP_VCAP_UPDATE_AUDIO_SOURCE 0x00000002 /* "audio_source" has changed */
#define DISP_VCAP_UPDATE_INPUT_FORMAT 0x00000004 /* "input_format" has changed */
#define DISP_VCAP_UPDATE_OUTPUT_FORMAT 0x00000008 /* "output_format" has changed */
#define DISP_VCAP_UPDATE_TUNER 0x00000010 /* "tuner_channel" and/or "Fif" and/or "radio_modulation" has changed */
#define DISP_VCAP_UPDATE_OUTPUT_SIZE 0x00000020 /* one or more of "crop_top", "crop bottom", "crop_left", "crop_right", "dst_width" and "dst_height" has changed */
#define DISP_VCAP_UPDATE_BRIGHTNESS 0x00000040 /* "brightness" has changed */
#define DISP_VCAP_UPDATE_CONTRAST 0x00000080 /* "contrast" has changed */
#define DISP_VCAP_UPDATE_SATURATION 0x00000100 /* "u_saturation" and/or "v_saturation" has changed */
#define DISP_VCAP_UPDATE_HUE 0x00000200 /* "hue" has changed */
#define DISP_VCAP_UPDATE_VOLUME 0x00000400 /* "volume" has changed */
#define DISP_VCAP_UPDATE_OUTPUT_TARGET 0x00000800 /* one or more of ?plane? members have changed */
/* Capabilities of a Video Frame Capture device */
typedef struct {
unsigned flags;
unsigned input_format; /* PAL, NTSC, etc. */
int frame_width;
int frame_height;
int frame_rate;
unsigned output_format; /* YUV, RGB, etc. */
int stride_granularity; /* Stride of capture buffer must be a multiple of this */
unsigned reserved[10];
} disp_vcap_channel_caps_t;
/* Status of a Video Frame Capture device */
typedef struct {
unsigned size;
unsigned flags;
unsigned signal;
int current_channel;
unsigned reserved[8];
} disp_vcap_channel_status_t;
typedef struct {
unsigned size;
unsigned flags;
unsigned video_source; /* Device to capture from */
unsigned audio_source; /* Audio source device */
unsigned input_format; /* PAL, NTSC etc. */
unsigned output_format; /* YUV, RGB etc. */
int tuner_channel;
int Fif;
short dst_width; /* Output width of scaled image */
short dst_height; /* Output height of scaled image */
short crop_top; /* Lines to skip at top of pre-scaled source image */
short crop_bottom; /* Lines to skip at bottom of pre-scaled source image */
short crop_left; /* Samples to skip at left of pre-scaled source image */
short crop_right; /* Samples to skip at right of pre-scaled source image */
short brightness;
short contrast;
short u_saturation;
short v_saturation;
short hue;
short reserved;
unsigned update_flags;
int scaler_index;
unsigned reserved2[6];
} disp_vcap_channel_props_t;
__BEGIN_DECLS
typedef struct disp_legacy_vcapfuncs {
int (*init)(disp_adapter_t *adapter, char *optstring);
void (*fini)(disp_adapter_t *adapter);
void (*module_info)(disp_adapter_t *adapter, disp_module_info_t *info);
int (*get_channel_caps)(disp_adapter_t *adapter, int channel,
int input_fmt_index, int output_fmt_index,
disp_vcap_channel_caps_t *caps);
int (*get_channel_status)(disp_adapter_t *adapter, int channel,
disp_vcap_channel_status_t *caps);
int (*set_channel_props)(disp_adapter_t *adapter, int channel,
disp_vcap_channel_props_t *props,
disp_surface_t *yplane1, disp_surface_t *yplane2,
disp_surface_t *uplane1, disp_surface_t *uplane2,
disp_surface_t *vplane1, disp_surface_t *vplane2);
int (*next_frame)(disp_adapter_t *adapter, int channel);
int (*close_channel)(disp_adapter_t *adapter, int channel);
int (*set_power_mode)(disp_adapter_t *adapter, pm_power_mode_t mode);
} disp_legacy_vcapfuncs_t;
/* Main video capture module entry point */
typedef int (*get_legacy_vcapfuncs_t)(disp_adapter_t *adapter,
disp_legacy_vcapfuncs_t *funcs, int tabsize);
extern int devg_get_legacy_vcapfuncs(disp_adapter_t *adapter,
disp_legacy_vcapfuncs_t *funcs, int tabsize);
__END_DECLS
#ifndef _GRAPHICS_TV_H_INCLUDED
#include <graphics/tv.h>
#endif
#endif /* _GRAPHICS_VCAP_H_INCLUDED */

317
devg/public/graphics/mode.h Обычный файл
Просмотреть файл

@ -0,0 +1,317 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifndef _GRAPHICS_MODE_H_INCLUDED
#define _GRAPHICS_MODE_H_INCLUDED
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#include <graphics/display.h>
#endif
typedef unsigned short disp_mode_t;
#define DISP_MAX_MODES 72
#define DISP_MODE_LISTEND (disp_mode_t)~0
/* disp_mode_info.flags */
#define DISP_MODE_PANEL_DETECTED 0x00000004 /* There is a flat panel currently attached */
#define DISP_MODE_FLAG_TVOUT_OVERSCAN 0x00000008 /* TV driven in "overscan" mode (else underscan) */
#define DISP_MODE_GENERIC 0x00020000 /* xres, yres, and refresh rate of this mode are not fixed */
#define DISP_MODE_XY_SWAPPED 0x00100000 /* For handling display timings on rotated displays */
/* "flags" argument to "set_mode()" */
#define DISP_MODE_FLAG_TV_STANDARD(__flags) ((__flags) & 0xff)
#define DISP_MODE_FLAG_DONT_SWITCH 0x00000100 /* Adapter is already in graphics mode; don't adjust video mode (e.g. if there's a splash screen being displayed) */
#define DISP_MODE_FLAG_TVOUT_NTSC 0x00000000
#define DISP_MODE_FLAG_TVOUT_PAL 0x00000001
#define DISP_MODE_FLAG_TVOUT_SECAM 0x00000002
#define DISP_MODE_FLAG_TVOUT_NTSC_JAPAN 0x00000003
#define DISP_MODE_FLAG_TVOUT_PAL_M 0x00000004
#define DISP_MODE_FLAG_TVOUT_PAL_N 0x00000005
#define DISP_MODE_FLAG_TVOUT_PAL_N_COMBO 0x00000006
#define DISP_MODE_FLAG_DISABLE_MONITOR 0x00000100 /* Turn off the monitor output */
#define DISP_MODE_FLAG_DISABLE_TVOUT 0x00000200 /* Turn off the TV output */
#define DISP_MODE_FLAG_DISABLE_PANEL 0x00000400 /* Turn off the panel output */
#define DISP_MODE_FLAG_DYNAMIC_SWITCH 0x00001000 /* Change display timings, but otherwise do not disturb display controller state */
/* disp_mode_info.caps */
#define DISP_MCAP_SET_DISPLAY_OFFSET 0x00000001
#define DISP_MCAP_VIRTUAL_PANNING 0x00000002
#define DISP_MCAP_DPMS_SUPPORTED 0x00000004
#define DISP_MCAP_TVOUT_ONLY 0x00000010 /* Can drive a TV with monitor switched off */
#define DISP_MCAP_TVOUT_WITH_MONITOR 0x00000020 /* Can drive a TV and monitor simultaneously */
#define DISP_MCAP_PANEL_ONLY 0x00000040 /* Can drive a panel with monitor switched off */
#define DISP_MCAP_PANEL_WITH_MONITOR 0x00000080 /* Can drive a panel and monitor simultaneously */
#define DISP_MCAP_TVOUT_NTSC 0x00010000
#define DISP_MCAP_TVOUT_PAL 0x00020000
#define DISP_MCAP_TVOUT_SECAM 0x00040000
#define DISP_MCAP_TVOUT_NTSC_JAPAN 0x00080000
#define DISP_MCAP_TVOUT_PAL_M 0x00100000
#define DISP_MCAP_TVOUT_PAL_N 0x00200000
#define DISP_MCAP_TVOUT_PAL_N_COMBO 0x00400000
#define DISP_MCAP_BACKLIGHT_CONTROL 0x00800000 /* Backlight brightness can be adjusted */
#define DISP_MODE_NUM_REFRESH 6
typedef struct disp_mode_info {
short size; /* Size of this struct */
disp_mode_t mode; /* Mode number */
int xres, yres; /* Physical display dimensions */
unsigned pixel_format; /* frame buffer pixel format */
unsigned flags;
uintptr_t fb_addr; /* Obsolete - DO NOT USE */
int fb_stride; /* Obsolete - DO NOT USE */
unsigned fb_size; /* Obsolete - DO NOT USE */
unsigned crtc_start_gran; /* In pixels */
unsigned caps; /* available features */
union {
struct {
short refresh[DISP_MODE_NUM_REFRESH]; /* Possible refresh rates for this mode */
} fixed;
struct {
int min_vfreq, max_vfreq; /* Monitor limitations - in Hz */
int min_hfreq, max_hfreq; /* Monitor limitations - in Hz */
int min_pixel_clock; /* in KHz */
int max_pixel_clock; /* in KHz */
uint8_t h_granularity; /* X resolution must be a multiple of this */
uint8_t v_granularity; /* Y resolution must be a multiple of this */
uint8_t sync_polarity;
uint8_t reserved;
} generic;
} u;
int num_colors; /* Palette modes only */
unsigned crtc_pitch_gran;
unsigned max_virtual_width; /* Max width of virtual display (in pixels) */
unsigned max_virtual_height; /* Max height of virtual display */
unsigned reserved[2];
} disp_mode_info_t;
/* values defined for sync_polarity in disp_crtc_settings struct */
#define DISP_SYNC_POLARITY_H_POS 1
#define DISP_SYNC_POLARITY_V_POS 2
#define DISP_SYNC_POLARITY_NN 0
#define DISP_SYNC_POLARITY_PN DISP_SYNC_POLARITY_H_POS
#define DISP_SYNC_POLARITY_NP DISP_SYNC_POLARITY_V_POS
#define DISP_SYNC_POLARITY_PP (DISP_SYNC_POLARITY_H_POS|DISP_SYNC_POLARITY_V_POS)
#define DISP_SYNC_INTERLACED 4
/* DPMS power saving modes modes */
#define DISP_DPMS_MODE_ON 0
#define DISP_DPMS_MODE_STANDBY 1
#define DISP_DPMS_MODE_SUSPEND 2
#define DISP_DPMS_MODE_OFF 4
typedef struct disp_crtc_settings {
int xres, yres, refresh;
unsigned pixel_clock;
uint8_t sync_polarity;
uint8_t h_granularity; /* X resolution must be a multiple of this */
uint8_t v_granularity; /* Y resolution must be a multiple of this */
uint8_t reserved0;
int h_total; /* In pixels */
int h_blank_start, h_blank_len; /* In pixels */
int reserved1;
int reserved2;
int h_sync_start, h_sync_len; /* In pixels */
int v_total; /* In lines */
int v_blank_start, v_blank_len; /* In lines */
int reserved3;
int reserved4;
int v_sync_start, v_sync_len; /* In lines */
unsigned flags;
int h_freq; /* In pixels */
unsigned reserved[5];
} disp_crtc_settings_t;
/* disp_layer_query_t.caps */
#define DISP_LAYER_CAP_FILTER 0x00000001
#define DISP_LAYER_CAP_SCALE_REPLICATE 0x00000002
#define DISP_LAYER_CAP_PAN_SOURCE 0x00000004
#define DISP_LAYER_CAP_SIZE_DEST 0x00000008
#define DISP_LAYER_CAP_PAN_DEST 0x00000010
#define DISP_LAYER_CAP_EDGE_CLAMP 0x00000020
#define DISP_LAYER_CAP_EDGE_WRAP 0x00000040
#define DISP_LAYER_CAP_DISABLE 0x00000080
#define DISP_LAYER_CAP_SET_BRIGHTNESS 0x00000100
#define DISP_LAYER_CAP_SET_CONTRAST 0x00000200
#define DISP_LAYER_CAP_SET_SATURATION 0x00000400
#define DISP_LAYER_CAP_ALPHA_WITH_CHROMA 0x00000800
#define DISP_LAYER_CAP_BLEND_WITH_FRONT 0x00001000
#define DISP_LAYER_CAP_PAN_DEST_NEGATIVE 0x00002000
#define DISP_LAYER_CAP_SET_HUE 0x00004000
#define DISP_LAYER_CAP_MAIN_DISPLAY 0x80000000
/* disp_layer_query_t.chromakey_caps */
#define DISP_LAYER_CHROMAKEY_CAP_SRC_SINGLE 0x00000001
#define DISP_LAYER_CHROMAKEY_CAP_SRC_RANGE 0x00000002
#define DISP_LAYER_CHROMAKEY_CAP_SRC_MASK 0x00000004
#define DISP_LAYER_CHROMAKEY_CAP_DST_SINGLE 0x00000100
#define DISP_LAYER_CHROMAKEY_CAP_DST_RANGE 0x00000200
#define DISP_LAYER_CHROMAKEY_CAP_DST_MASK 0x00000400
#define DISP_LAYER_CHROMAKEY_CAP_SHOWTHROUGH 0x00000800
#define DISP_LAYER_CHROMAKEY_CAP_BLOCK 0x00001000
/* "flags" arg. to layer_set_flags() */
#define DISP_LAYER_FLAG_DISABLE_FILTERING 0x00000001
#define DISP_LAYER_FLAG_EDGE_CLAMP 0x00000002
#define DISP_LAYER_FLAG_EDGE_WRAP 0x00000004
typedef enum {
DISP_MODE_DEVCTL_SET_SYNC_SOURCE = 1,
DISP_MODE_DEVCTL_UPDATE_DISPLAY_SETTINGS
} disp_mode_devctl_t;
typedef struct {
int size; /* Allocator of this struct sets "size" to sizeof (disp_surface_info_t) */
unsigned pixel_format;
unsigned caps;
unsigned alpha_valid_flags; /* Valid flags to layer_set_blending() */
unsigned alpha_combinations;
unsigned chromakey_caps;
int src_max_height; /* Memory surface to be displayed by layer must be no taller than this */
int src_max_width; /* Memory surface to be displayed by layer must be no wider than this */
int src_max_viewport_height; /* Maximum height of the source data image that can be fetched from the memory surface to update the display */
int src_max_viewport_width; /* Maximum width of the source data image that can be fetched from the memory surface to update the display */
int dst_max_height;
int dst_max_width;
int dst_min_height;
int dst_min_width;
int max_scaleup_x;
int max_scaleup_y;
int max_scaledown_x;
int max_scaledown_y;
uint64_t order_mask; /* 1 bit per layer */
uint32_t output_mask; /* 1 bit per output */
uint32_t vcap_mask; /* 1 bit per capture unit */
uintptr_t reserved[7];
} disp_layer_query_t;
__BEGIN_DECLS
typedef struct disp_modefuncs {
int (*init)(disp_adapter_t *adapter, char *optstring);
void (*fini)(disp_adapter_t *adapter);
void (*module_info)(disp_adapter_t *adapter, disp_module_info_t *info);
int (*get_modeinfo)(disp_adapter_t *adapter, int dispno,
disp_mode_t mode, disp_mode_info_t *info);
int (*get_modelist)(disp_adapter_t *adapter,
int dispno, disp_mode_t *modelist, int index, int size);
int (*set_mode)(disp_adapter_t *adapter, int dispno,
disp_mode_t mode, disp_crtc_settings_t *settings,
disp_surface_t *surf, unsigned flags);
void (*reserved)();
int (*wait_vsync)(disp_adapter_t *adapter, int dispno);
void (*set_backlight_intensity)(disp_adapter_t *adapter,
int dispno, int brightness);
void (*restore_vga)(disp_adapter_t *adapter);
int (*set_dpms_mode)(disp_adapter_t *adapter, int dispno, int mode);
int (*set_display_offset)(disp_adapter_t *adapter, int dispno,
unsigned offset, int wait_vsync);
int (*set_palette)(disp_adapter_t *adapter, int dispno,
int index, int count, disp_color_t *pal);
void (*set_scroll_position)(disp_adapter_t *adapter,
int dispno, unsigned xoff, unsigned yoff);
int (*layer_query)(disp_adapter_t *adapter, int dispno,
int layer_idx, int fmt_idx, disp_layer_query_t *info);
int (*layer_enable)(disp_adapter_t *adapter, int dispno, int layer_idx);
int (*layer_disable)(disp_adapter_t *adapter, int dispno, int layer_idx);
int (*layer_set_surface)(disp_adapter_t *adapter, int dispno,
int layer_idx, unsigned layer_format, disp_surface_t *surf[]);
int (*layer_set_source_viewport)(disp_adapter_t *adapter, int dispno,
int layer_idx, int x1, int y1, int x2, int y2);
int (*layer_set_dest_viewport)(disp_adapter_t *adapter,
int dispno, int layer_idx, int x1, int y1, int x2, int y2);
int (*layer_set_blending)(disp_adapter_t *adapter, int dispno,
int layer_idx, unsigned alpha_mode, int m1, int m2);
int (*layer_set_chromakey)(disp_adapter_t *adapter, int dispno,
int layer_idx, unsigned chroma_mode,
disp_color_t color0, disp_color_t color1, disp_color_t mask);
int (*layer_set_brightness)(disp_adapter_t *adapter, int dispno,
int layer_idx, int brightness);
int (*layer_set_saturation)(disp_adapter_t *adapter, int dispno,
int layer_idx, int saturation);
int (*layer_set_contrast)(disp_adapter_t *adapter, int dispno,
int layer_idx, int contrast);
int (*layer_set_flags)(disp_adapter_t *adapter, int dispno,
int layer_idx, unsigned flag_mask, unsigned flag_values);
void (*layer_update_begin)(disp_adapter_t *adapter,
int dispno, uint64_t layer_mask);
void (*layer_update_end)(disp_adapter_t *adapter,
int dispno, uint64_t layer_mask, int wait_vsync);
void (*layer_reset)(disp_adapter_t *adapter, int dispno, int layer_idx);
int (*set_power_mode)(disp_adapter_t *adapter, pm_power_mode_t mode);
int (*layer_set_order)(disp_adapter_t *adapter, int dispno, unsigned order[]);
int (*set_hw_cursor)(disp_adapter_t *ctx, int dispno,
uint8_t *fg_bmp, uint8_t *bg_bmp,
unsigned fg_color, unsigned bg_color,
int hotspot_x, int hotspot_y,
int size_x, int size_y, int bmp_stride);
void (*enable_hw_cursor)(disp_adapter_t *ctx, int dispno);
void (*disable_hw_cursor)(disp_adapter_t *ctx, int dispno);
void (*set_hw_cursor_pos)(disp_adapter_t *ctx, int dispno, int x, int y);
int (*i2c_read)(disp_adapter_t *ctx, int busno, int slaveaddr,
uint8_t *ibuf, int ibytes);
int (*i2c_write)(disp_adapter_t *ctx, int busno, int slaveaddr,
uint8_t *obuf, int obytes);
int (*i2c_writeread)(disp_adapter_t *ctx, int busno, int slaveaddr,
uint8_t *obuf, int obytes, uint8_t *ibuf, int ibytes);
int (*layer_enable_outputs)(disp_adapter_t *adapter,
int dispno, int layer, uint32_t output_mask);
int (*set_cursor_index)(disp_adapter_t *adapter,
int dispno, int cursor_idx);
int (*layer_set_alpha_map)(disp_adapter_t *adapter,
int dispno, int layer, disp_surface_t *map);
int (*layer_set_hue)(disp_adapter_t *adapter, int dispno,
int layer_idx, int hue);
int (*snapshot)(disp_adapter_t *adapter, int dispno, int output,
int x1, int y1, int x2, int y2, disp_surface_t *surf);
int (*set_external_chroma)(disp_adapter_t *adapter, int dispno,
unsigned chroma_mode,
disp_color_t color0, disp_color_t color1, disp_color_t mask);
int (*devctl)(disp_adapter_t *adapter, int dispno,
disp_mode_devctl_t cmd, void *data_in, int nbytes,
void *data_out, int *out_buffer_size);
int (*set_color_lut16)(disp_adapter_t *adapter,
int dispno, const uint16_t *redLUT, const uint16_t *greenLUT, const uint16_t *blueLUT);
int (*layer_flushrect)(disp_adapter_t *adapter, int dispno,
int layer_idx, int x1, int y1, int x2, int y2);
int (*layer_set_palette)(disp_adapter_t *adapter, int dispno,
int layer_idx, int index, int count, disp_color_t *pal);
void (*reserved1[1])();
} disp_modefuncs_t;
/* Main mode-switcher entry point */
typedef int (*get_modefuncs_t)(disp_adapter_t *adapter,
disp_modefuncs_t *funcs, int tabsize);
extern WINSIM_API int devg_get_modefuncs(disp_adapter_t *adapter,
disp_modefuncs_t *funcs, int tabsize);
__END_DECLS
#endif /* _GRAPHICS_MODE_H_INCLUDED */

30
devg/public/graphics/rend.h Обычный файл
Просмотреть файл

@ -0,0 +1,30 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifndef _GRAPHICS_REND_H_INCLUDED
#define _GRAPHICS_REND_H_INCLUDED
typedef struct disp_rend_buffer_config {
unsigned color_format; /* See DISP_LAYER_FORMAT_* */
unsigned read_format; /* See DISP_TEXFORMAT_* */
unsigned red_bpp; /* Red bits per pixel of color buffer */
unsigned green_bpp; /* Green bits per pixel of color buffer */
unsigned blue_bpp; /* Blue bits per pixel of color buffer */
unsigned alpha_bpp; /* Alpha bits per pixel of color buffer */
unsigned depth_bpp; /* Bits per pixel of depth buffer */
unsigned stencil_bpp; /* Bits per pixel of stencil buffer */
int max_surf_width; /* Maximum width of a buffer, in pixels, that can be rendered to */
int max_surf_height; /* Maximum height of a buffer, in pixels, that can be rendered to */
int slow_config;
unsigned sample_buffers;
unsigned samples;
unsigned reserved[6]; /* Must be zero */
} disp_rend_buffer_config_t;
typedef struct disp_rend_context_params {
void * (*get_current_context)();
} disp_rend_context_params_t;
#endif /* _GRAPHICS_REND_H_INCLUDED */

353
devg/public/graphics/rop.h Обычный файл
Просмотреть файл

@ -0,0 +1,353 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifndef _GRAPHICS_ROP_H_INCLUDED
#define _GRAPHICS_ROP_H_INCLUDED
/*
* Raster Op Defines
*
* Reverse Polish Notation Defines of ROPS
* This follows Microsofts 256 raster operation
* definitions
*
* D = Dest Bit
* S = Source Bit
* P = Pattern Bit
* o = bitwise or operation
* a = bitwise and operation
* x = bitwise exclusive or operation
* n = bitwise not operation
*
* Truth Table
* P S D ropbit
* 0 0 0 0
* 0 0 1 1
* 0 1 0 2
* 0 1 1 3
* 1 0 0 4
* 1 0 1 5
* 1 1 0 6
* 1 1 1 7
*
* if the condition in the table is true for
* each test turned on then dst bit=1, else 0
*
* So: DrawMode CC = Source Copy
* if ((conditions 2 | 3 | 6 | 7) == 1) on current bits, dst bit=1, else 0
* DrawMode 66 = S ^ D
* if ((conditions 1 | 2 | 5 | 6) == 1) on current bits, dst bit=1, else 0
* DrawMode 03 = ~ (P | S)
* if ((conditions 0 | 1) == 1) on current bits, dst bit=1, else 0
*
* It's a little confusing at first, but it does make sense once you wrap
* your brain around it.
*
* Name Rop # Operation
*--------------------------------------------------------------------------
*/
#define DrawModeZERO 0x00 /* 0 */
#define DrawModeDPSoon 0x01 /* ~ ( (D | (P | S) ) ) */
#define DrawModeDPSona 0x02 /* D & ( ~ (P | S) ) */
#define DrawModePSon 0x03 /* ~ (P | S) */
#define DrawModeSDPona 0x04 /* S & ( ~ (D | P) ) */
#define DrawModeDPon 0x05 /* ~ (D | P) */
#define DrawModePDSxnon 0x06 /* ~ (P | (~ (D ^ S))) */
#define DrawModePDSaon 0x07 /* ~ (P | (D & S)) */
#define DrawModeSDPnaa 0x08 /* S & (D & (~ P)) */
#define DrawModePDSxon 0x09 /* ~ (P | (D ^ S)) */
#define DrawModeDPna 0x0A /* D & (~ P) */
#define DrawModePSDnaon 0x0B /* ~ (P | (S & (~ D))) */
#define DrawModeSPna 0x0C /* S & (~ P) */
#define DrawModePDSnaon 0x0D /* ~ (P | (D & (~ S))) */
#define DrawModePDSonon 0x0E /* ~ (P | (~(D | S))) */
#define DrawModePn 0x0F /* ~ P */
#define DrawModePDSona 0x10 /* P & (~ (D | S)) */
#define DrawModeDSon 0x11 /* ~ (D | S) */
#define DrawModeSDPxnon 0x12 /* ~ (S | (~ (D ^ P))) */
#define DrawModeSDPaon 0x13 /* ~ (S | (D & P)) */
#define DrawModeDPSxnon 0x14 /* ~ (D | (~ (P ^ S))) */
#define DrawModeDPSaon 0x15 /* ~ (D | (P & S)) */
#define DrawModePSDPSanaxx 0x16 /* P ^ (S ^ (D & (~ (P & S)))) */
#define DrawModeSSPxDSxaxn 0x17 /* ~ (S ^ ((S ^ P) & (D ^ S))) */
#define DrawModeSPxPDxa 0x18 /* (S ^ P) & (P ^ D) */
#define DrawModeSDPSanaxn 0x19 /* ~ (S ^ (D & (~ (P & S)))) */
#define DrawModePDSPaox 0x1A /* P ^ (D | (S & P)) */
#define DrawModeSDPSxaxn 0x1B /* ~ (S ^ (D & (P ^ S)))) */
#define DrawModePSDPaox 0x1C /* P ^ (S | (D & P))) */
#define DrawModeDSPDxaxn 0x1D /* ~ (D ^ (S & (P ^ D))) */
#define DrawModePDSox 0x1E /* P ^ (D | S) */
#define DrawModePDSoan 0x1F /* ~ (P & (D | S)) */
#define DrawModeDPSnaa 0x20 /* D & (P & (~S)) */
#define DrawModeSDPxon 0x21 /* ~ (S | (D ^ P)) */
#define DrawModeDSna 0x22 /* D & (~S) */
#define DrawModeSPDnaon 0x23 /* ~ (S | (P & (~D))) */
#define DrawModeSPxDSxa 0x24 /* (S ^ P) & (D ^ S) */
#define DrawModePDSPanaxn 0x25 /* ~ (P ^ (D & (~ (S & P)))) */
#define DrawModeSDPSaox 0x26 /* S ^ (D | (P & S)) */
#define DrawModeSDPSxnox 0x27 /* S ^ (D | (~ (P ^ S))) */
#define DrawModeDPSxa 0x28 /* D & (P ^ S) */
#define DrawModePSDPSaoxxn 0x29 /* ~ (P ^ (S ^ (D | (P & S)))) */
#define DrawModeDPSana 0x2A /* D & (~ (P & S)) */
#define DrawModeSSPxPDxaxn 0x2B /* ~ (S ^ ((S ^ P) & (P ^ D)) */
#define DrawModeSPDSoax 0x2C /* S ^ (P & (D | S)) */
#define DrawModePSDnox 0x2D /* P ^ (S | (~D)) */
#define DrawModePSDPxox 0x2E /* P ^ (S | (D ^ P)) */
#define DrawModePSDnoan 0x2F /* ~ (P & (S | (~D))) */
#define DrawModePSna 0x30 /* P & (~ S) */
#define DrawModeSDPnaon 0x31 /* ~ (S | (D & (~P))) */
#define DrawModeSDPSoox 0x32 /* S ^ (D | (P | S)) */
#define DrawModeSn 0x33 /* ~S */
#define DrawModeSPDSaox 0x34 /* S ^ (P | (D & S)) */
#define DrawModeSPDSxnox 0x35 /* S ^ (P | (~ (D ^ S))) */
#define DrawModeSDPox 0x36 /* S ^ (D | P) */
#define DrawModeSDPoan 0x37 /* ~ (S & (D | P)) */
#define DrawModePSDPoax 0x38 /* P ^ (S & (D | P))) */
#define DrawModeSPDnox 0x39 /* S ^ (P | (~ D))) */
#define DrawModeSPDSxox 0x3A /* S ^ (P | (D ^ S)) */
#define DrawModeSPDnoan 0x3B /* ~ (S & (P | (~ D))) */
#define DrawModePSx 0x3C /* P ^ S */
#define DrawModeSPDSonox 0x3D /* S ^ (P | (~ (D | S))) */
#define DrawModeSPDSnaox 0x3E /* S ^ (P | (D & (~ S))) */
#define DrawModePSan 0x3F /* ~ (P & S) */
#define DrawModePSDnaa 0x40 /* P & (S & (~ D)) */
#define DrawModeDPSxon 0x41 /* ~ (D | (P ^ S) */
#define DrawModeSDxPDxa 0x42 /* (S ^ D) & (P ^ D) */
#define DrawModeSPDSanaxn 0x43 /* ~ (S ^ (P & (~ (D & S)))) */
#define DrawModeSDna 0x44 /* S & (~ D) */
#define DrawModeDPSnaon 0x45 /* ~ (D | (P & (~ S))) */
#define DrawModeDSPDaox 0x46 /* D ^ (S | (P & D))) */
#define DrawModePSDPxaxn 0x47 /* ~ (P ^ (S & (D ^ P))) */
#define DrawModeSDPxa 0x48 /* S & (D ^ P)) */
#define DrawModePDSPDoaxxn 0x49 /* ~ (P ^ (D ^ (S & (P | D)))) */
#define DrawModeDPSDoax 0x4A /* D ^ (P & (S | D)) */
#define DrawModePDSnox 0x4B /* P ^ (D | (~ S)) */
#define DrawModeSDPana 0x4C /* S & (~ (D & P)) */
#define DrawModeSSPxDSxoxn 0x4D /* ~ (S ^ ((S ^ P) | (D ^ S))) */
#define DrawModePDSPxox 0x4E /* P ^ (D | (S ^ P)) */
#define DrawModePDSnoan 0x4F /* ~ (P & (D | (~S))) */
#define DrawModePDna 0x50 /* (~ D) & P */
#define DrawModeDSPnaon 0x51 /* ~ (D | (S & (~P))) */
#define DrawModeDPSDaox 0x52 /* D ^ (P | (S & D)) */
#define DrawModeSPDSxaxn 0x53 /* ~ (S ^ (P & (D ^ S))) */
#define DrawModeDPSonon 0x54 /* ~ (D | (~ (P | S))) */
#define DrawModeDn 0x55 /* ~ D */
#define DrawModeDPSox 0x56 /* D ^ (P | S) */
#define DrawModeDPSoan 0x57 /* ~ (D & (P | S)) */
#define DrawModePDSPoax 0x58 /* P ^ (D & (S | P)) */
#define DrawModeDPSnox 0x59 /* D ^ (P | (~ S)) */
#define DrawModeDPx 0x5A /* D ^ P */
#define DrawModeDPSDonox 0x5B /* D ^ (P | (~ (S | D))) */
#define DrawModeDPSDxox 0x5C /* D ^ (P | (S ^ D)) */
#define DrawModeDPSnoan 0x5D /* ~ (D & (P | (~ S))) */
#define DrawModeDPSDnaox 0x5E /* D ^ (P | (S & (~ D))) */
#define DrawModeDPan 0x5F /* ~ (D & P) */
#define DrawModePDSxa 0x60 /* P & (D ^ S) */
#define DrawModeDSPDSaoxxn 0x61 /* ~ (D ^ (S ^ (P | (D & S)))) */
#define DrawModeDSPDoax 0x62 /* D ^ (S & (P | D)) */
#define DrawModeSDPnox 0x63 /* S ^ (D | (~ P)) */
#define DrawModeSDPSoax 0x64 /* S ^ (D & (P | S)) */
#define DrawModeDSPnox 0x65 /* D ^ (S | (~ P)) */
#define DrawModeDSx 0x66 /* D ^ S */
#define DrawModeSDPSonox 0x67 /* S ^ (D | (~ (P | S))) */
#define DrawModeDSPDSonoxxn 0x68 /* ~ (D ^ (S ^ (P | (~ (D | S))))) */
#define DrawModePDSxxn 0x69 /* ~ (P ^ (D ^ S)) */
#define DrawModeDPSax 0x6A /* D ^ (P & S) */
#define DrawModePSDPSoaxxn 0x6B /* ~ (P ^ (S ^ (D & (P | S)))) */
#define DrawModeSDPax 0x6C /* S ^ (D & P) */
#define DrawModePDSPDoaxx 0x6D /* P ^ (D ^ (S & (P | D))) */
#define DrawModeSDPSnoax 0x6E /* S ^ (D & (P | (~ S))) */
#define DrawModePDSxnan 0x6F /* ~ (P & (~ (D ^ S))) */
#define DrawModePDSana 0x70 /* P & (~ (D & S)) */
#define DrawModeSSDxPDxaxn 0x71 /* ~ (S ^ ((S ^ D) & (P ^ D))) */
#define DrawModeSDPSxox 0x72 /* S ^ (D | (P ^ S)) */
#define DrawModeSDPnoan 0x73 /* ~ (S & (D | (~P))) */
#define DrawModeDSPDxox 0x74 /* D ^ (S | (P ^ D)) */
#define DrawModeDSPnoan 0x75 /* ~ (D & (S | (~ P))) */
#define DrawModeSDPSnaox 0x76 /* S ^ (D | (P & (~ S))) */
#define DrawModeDSan 0x77 /* ~ (D & S) */
#define DrawModePDSax 0x78 /* P ^ (D & S) */
#define DrawModeDSPDSoaxxn 0x79 /* ~ (D ^ (S ^ (P & (D | S)))) */
#define DrawModeDPSDnoax 0x7A /* D ^ (P & (S | (~ D))) */
#define DrawModeSDPxnan 0x7B /* ~ (S & (~ (D ^ P))) */
#define DrawModeSPDSnoax 0x7C /* S ^ (P & (D | (~ S))) */
#define DrawModeDPSxnan 0x7D /* ~ (D & (~ (P ^ S))) */
#define DrawModeSPxDSxo 0x7E /* (S ^ P) | (D ^ S) */
#define DrawModeDPSaan 0x7F /* ~ (D & (P & S)) */
#define DrawModeDPSaa 0x80 /* D & (P & S) */
#define DrawModeSPxDSxon 0x81 /* ~ ((P ^ S) | (D ^ S)) */
#define DrawModeDPSxna 0x82 /* D & (~ (P ^ S)) */
#define DrawModeSPDSnoaxn 0x83 /* ~ (S ^ (P & (D | (~ S)))) */
#define DrawModeSDPxna 0x84 /* S & (~ (D ^ P)) */
#define DrawModePDSPnoaxn 0x85 /* ~ (P ^ (D & (S | (~ P)))) */
#define DrawModeDSPDSoaxx 0x86 /* D ^ (S ^ (P & (D | S))) */
#define DrawModePDSaxn 0x87 /* ~ (P ^ (D & S)) */
#define DrawModeDSa 0x88 /* D & S */
#define DrawModeSDPSnaoxn 0x89 /* ~ (S ^ (D | (P & (~ S)))) */
#define DrawModeDSPnoa 0x8A /* D & (S | (~ P)) */
#define DrawModeDSPDxoxn 0x8B /* ~ (D ^ (S | (P ^ D))) */
#define DrawModeSDPnoa 0x8C /* S & (D | (~ P)) */
#define DrawModeSDPSxoxn 0x8D /* ~ (S ^ (D | (P ^ S))) */
#define DrawModeSSDxPDxax 0x8E /* S ^ ((S ^ D) & (P ^ D)) */
#define DrawModePDSanan 0x8F /* ~ (P & (~ (D & S))) */
#define DrawModePDSxna 0x90 /* P & (~ (D ^ S)) */
#define DrawModeSDPSnoaxn 0x91 /* ~ (S ^ (D & (P | (~ S)))) */
#define DrawModeDPSDPoaxx 0x92 /* D ^ (P ^ (S & (D | P))) */
#define DrawModeSPDaxn 0x93 /* ~ (S ^ (P & D)) */
#define DrawModePSDPSoaxx 0x94 /* P ^ (S ^ (D & (P | S))) */
#define DrawModeDPSaxn 0x95 /* ~ (D ^ (P & S)) */
#define DrawModeDPSxx 0x96 /* D ^ (P ^ S) */
#define DrawModePSDPSonoxx 0x97 /* P ^ (S ^ (D | (~ (P | S)))) */
#define DrawModeSDPSonoxn 0x98 /* ~ (S ^ (D | (~ (P | S)))) */
#define DrawModeDSxn 0x99 /* ~ (D ^ S) */
#define DrawModeDPSnax 0x9A /* D ^ (P & (~ S)) */
#define DrawModeSDPSoaxn 0x9B /* ~ (S ^ (D & (P | S))) */
#define DrawModeSPDnax 0x9C /* S ^ (P & (~ D)) */
#define DrawModeDSPDoaxn 0x9D /* ~ (D ^ (S & (P | D))) */
#define DrawModeDSPDSaoxx 0x9E /* D ^ (S ^ (P | (D & S))) */
#define DrawModePDSxan 0x9F /* ~ (P & (D ^ S)) */
#define DrawModeDPa 0xA0 /* (D & P) */
#define DrawModePDSPnaoxn 0xA1 /* ~ (P ^ (D | (S & (~ P)))) */
#define DrawModeDPSnoa 0xA2 /* D & (P | (~ S)) */
#define DrawModeDPSDxoxn 0xA3 /* ~ (D ^ (P | (S ^ D))) */
#define DrawModePDSPonoxn 0xA4 /* ~ (P ^ (D | (~ (S | P)))) */
#define DrawModePDxn 0xA5 /* ~ (P ^ D) */
#define DrawModeDSPnax 0xA6 /* D ^ (S & (~ P)) */
#define DrawModePDSPoaxn 0xA7 /* ~ (P ^ (D & (S | P))) */
#define DrawModeDPSoa 0xA8 /* D & (P | S) */
#define DrawModeDPSoxn 0xA9 /* ~ (D ^ (P | S)) */
#define DrawModeD 0xAA /* D */
#define DrawModeDPSono 0xAB /* D | (~ (P | S)) */
#define DrawModeSPDSxax 0xAC /* S ^ (P & (D ^ S)) */
#define DrawModeDPSDaoxn 0xAD /* ~ (D ^ (P | (S & D))) */
#define DrawModeDSPnao 0xAE /* D | (S & (~ P)) */
#define DrawModeDPno 0xAF /* D | (~ P) */
#define DrawModePDSnoa 0xB0 /* P & (D | (~ S)) */
#define DrawModePDSPxoxn 0xB1 /* ~ (P ^ (D | (S ^ P))) */
#define DrawModeSSPxDSxox 0xB2 /* S ^ ((S ^ P) | (D ^ S)) */
#define DrawModeSDPanan 0xB3 /* ~ (S & (~ (D & P))) */
#define DrawModePSDnax 0xB4 /* P ^ (S & (~ D)) */
#define DrawModeDPSDoaxn 0xB5 /* ~ (D ^ (P & (S | D))) */
#define DrawModeDPSDPaoxx 0xB6 /* D ^ (P ^ (S | (D & P))) */
#define DrawModeSDPxan 0xB7 /* ~ (S & (D ^ P)) */
#define DrawModePSDPxax 0xB8 /* P ^ (S & (D ^ P)) */
#define DrawModeDSPDaoxn 0xB9 /* ~ (D ^ (S | (P & D))) */
#define DrawModeDPSnao 0xBA /* D | (P & (~ S)) */
#define DrawModeDSno 0xBB /* D | (~ S) */
#define DrawModeSPDSanax 0xBC /* S ^ (P & (~ (D & S))) */
#define DrawModeSDxPDxan 0xBD /* ~ ((S ^ D) & (P ^ D)) */
#define DrawModeDPSxo 0xBE /* D | (P ^ S) */
#define DrawModeDPSano 0xBF /* D | (~ (P & S)) */
#define DrawModePSa 0xC0 /* P & S */
#define DrawModeSPDSnaoxn 0xC1 /* ~ (S ^ (P | (D & (~ S)))) */
#define DrawModeSPDSonoxn 0xC2 /* ~ (S ^ (P | (~ (D | S)))) */
#define DrawModePSxn 0xC3 /* ~ (P ^ S) */
#define DrawModeSPDnoa 0xC4 /* S & (P | (~ D)) */
#define DrawModeSPDSxoxn 0xC5 /* ~ (S ^ (P | (D ^ S))) */
#define DrawModeSDPnax 0xC6 /* S ^ (D & (~ P)) */
#define DrawModePSDPoaxn 0xC7 /* ~ (P ^ (S & (D | P))) */
#define DrawModeSDPoa 0xC8 /* S & (D | P) */
#define DrawModeSPDoxn 0xC9 /* ~ (S ^ (P | D)) */
#define DrawModeDPSDxax 0xCA /* D ^ (P & (S ^ D)) */
#define DrawModeSPDSaoxn 0xCB /* ~ (S ^ (P | (D & S))) */
#define DrawModeS 0xCC /* S */
#define DrawModeSDPono 0xCD /* S | (~ (D | P)) */
#define DrawModeSDPnao 0xCE /* S | (D & (~ P)) */
#define DrawModeSPno 0xCF /* S | (~ P) */
#define DrawModePSDnoa 0xD0 /* P & (S | (~ D)) */
#define DrawModePSDPxoxn 0xD1 /* ~ (P ^ (S | (D ^ P))) */
#define DrawModePDSnax 0xD2 /* P ^ (D & (~ S)) */
#define DrawModeSPDSoaxn 0xD3 /* ~ (S ^ (P & (D | S))) */
#define DrawModeSSPxPDxax 0xD4 /* S ^ ((S ^ P) & (P ^ D)) */
#define DrawModeDPSanan 0xD5 /* ~ (D & (~ (P & S))) */
#define DrawModePSDPSaoxx 0xD6 /* P ^ (S ^ (D | (P & S))) */
#define DrawModeDPSxan 0xD7 /* ~ (D & (P ^ S)) */
#define DrawModePDSPxax 0xD8 /* P ^ (D & (S ^ P)) */
#define DrawModeSDPSaoxn 0xD9 /* ~ (S ^ (D | (P & S))) */
#define DrawModeDPSDanax 0xDA /* D ^ (P & (~ (S & D))) */
#define DrawModeSPxDSxan 0xDB /* ~ ((S ^ P) & (D ^ S)) */
#define DrawModeSPDnao 0xDC /* S | (P & (~ D)) */
#define DrawModeSDno 0xDD /* S | (~ D) */
#define DrawModeSDPxo 0xDE /* S | (D ^ P) */
#define DrawModeSDPano 0xDF /* S | (~ (D & P)) */
#define DrawModePDSoa 0xE0 /* P & (D | S) */
#define DrawModePDSoxn 0xE1 /* ~ (P ^ (D | S)) */
#define DrawModeDSPDxax 0xE2 /* D ^ (S & (P ^ D)) */
#define DrawModePSDPaoxn 0xE3 /* ~ (P ^ (S | (D & P))) */
#define DrawModeSDPSxax 0xE4 /* S ^ (S & (P ^ S)) */
#define DrawModePDSPaoxn 0xE5 /* ~ (P ^ (D | (S & P))) */
#define DrawModeSDPSanax 0xE6 /* S ^ (D & (~ (P & S))) */
#define DrawModeSPxDPxan 0xE7 /* ~ ((S ^ P) & (D ^ P)) */
#define DrawModeSSPxDSxax 0xE8 /* S ^ ((S ^ P) & (D ^ S)) */
#define DrawModeDSPDSanaxxn 0xE9 /* ~ (D ^ (S ^ (P & (~ (D & S))))) */
#define DrawModeDPSao 0xEA /* D | (P & S) */
#define DrawModeDPSxno 0xEB /* D | (~ (P ^ S)) */
#define DrawModeSDPao 0xEC /* S | (D & P) */
#define DrawModeSDPxno 0xED /* S | (~ (D ^ P)) */
#define DrawModeDSo 0xEE /* D | S */
#define DrawModeSDPnoo 0xEF /* S | (D | (~ P)) */
#define DrawModeP 0xF0 /* P */
#define DrawModePDSono 0xF1 /* P | (~ (D | S)) */
#define DrawModePDSnao 0xF2 /* P | (D & (~ S)) */
#define DrawModePSno 0xF3 /* P | (~ S) */
#define DrawModePSDnao 0xF4 /* P | (S & (~ D)) */
#define DrawModePDno 0xF5 /* P | (~ D) */
#define DrawModePDSxo 0xF6 /* P | (D ^ S) */
#define DrawModePDSano 0xF7 /* P | (~ (D & S)) */
#define DrawModePDSao 0xF8 /* P | (D & S) */
#define DrawModePDSxno 0xF9 /* P | (~ (D ^ S)) */
#define DrawModeDPo 0xFA /* D | P */
#define DrawModeDPSnoo 0xFB /* D | (P | (~ S)) */
#define DrawModePSo 0xFC /* P | S */
#define DrawModePSDnoo 0xFD /* P | (S | (~ D)) */
#define DrawModeDPSoo 0xFE /* D | (P | S) */
#define DrawModeONE 0xFF /* 1 */
/* Convenience Defines */
#define DrawModeBLACK DrawModeZERO
#define DrawModeWHITE DrawModeONE
#define DrawModeSRCCOPY DrawModeS
#define DrawModeSRCINVERT DrawModeSn
#define DrawModePATCOPY DrawModeP
#define DrawModePATINVERT DrawModePn
#define DrawModeNOP DrawModeD
#define DrawModeDSTINVERT DrawModeDn
#define DrawModeSRCXOR DrawModeDSx
#define DrawModePATXOR DrawModeDPx
#define DrawModeSRCAND DrawModeDSa
#define DrawModePATAND DrawModeDPa
#define DrawModeSRCOR DrawModeDSo
#define DrawModePATOR DrawModeDPo
/* Simple ROP defines */
#define DrawModeOpaque DrawModeSRCCOPY
#define DrawModeXOR DrawModeSRCXOR
#define DrawModeAND DrawModeSRCAND
#define DrawModeOR DrawModeSRCOR
/* Defines for interpreting ternary Raster OPs (ROP3) */
#define DISP_ROP_STUPID(__rop) ((__rop) == 0 | (__rop) == 0xff)
#define DISP_ROP_NO_PATTERN(__rop) (((__rop) & 0xf) == \
(((__rop) >> 4) & 0xf))
#define DISP_ROP_NO_SOURCE(__rop) (((__rop) & 0x33) == \
(((__rop) >> 2) & 0x33))
#define DISP_ROP_NO_DEST(__rop) (((__rop) & 0x55) == \
(((__rop) >> 1) & 0x55))
/* Rastor op conversion macros */
#define DISP_ROP_SRC_TO_PAT(__rop) (((__rop) & 0xc0) | \
((__rop) & 0xc) << 2 | \
((__rop) & 0x30) >> 2 | \
((__rop) & 0x3))
#define DISP_ROP_PAT_TO_SRC(__rop) (((__rop) & 0xc0) | \
((__rop) & 0x30) >> 2 | \
((__rop) & 0xc) << 2 | \
((__rop) & 0x3))
#endif /* _GRAPHICS_ROP_H_INCLUDED */

76
devg/public/graphics/vbios.h Обычный файл
Просмотреть файл

@ -0,0 +1,76 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifdef __X86__
#ifndef _GRAPHICS_VBIOS_H_INCLUDED
#define _GRAPHICS_VBIOS_H_INCLUDED
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#include <graphics/display.h>
#endif
typedef struct vbios_context {
disp_adapter_t *adp;
unsigned xfer_area_seg; /* Real-mode segment */
unsigned xfer_area_off; /* Real-mode offset */
unsigned char *xfer_area_ptr; /* virtual address */
/* Multiple controller support */
uint8_t *zeropage; /* Drivers copy */
uint8_t *rom; /* Drivers copy */
int romsize;
uint8_t *c0000_ptr; /* Pointer to linear c0000 */
#ifndef __QNXNTO__
void *legacy_regs;
#endif
} vbios_context_t;
/* Flags passed to vbios_register */
#define VBIOS_FLAG_FORCE_EMU86 1
#define VBIOS_FLAG_FORCE_V86 2
/* Larget amount of data that can be transferred to/from BIOS code */
#define VBIOS_TRANSBUF_MAX 2048
#ifdef __QNXNTO__
#ifdef __X86__
#ifndef __V86_H_INCLUDED
#include <x86/v86.h>
#endif
typedef struct _v86reg vbios_regs_t;
#endif
#else /* !__QNXNTO__ */
typedef struct {
long edi, esi, ebp, exx, ebx, edx, ecx, eax;
long eip, cs, efl;
long esp, ss, es, ds, fs, gs;
} vbios_regs_t;
#endif
__BEGIN_DECLS
int vbios_register_noemu(disp_adapter_t *adp, unsigned flags);
int vbios_register(disp_adapter_t *adp, unsigned flags);
void vbios_unregister(vbios_context_t *ctx);
int vbios_int(vbios_context_t *ctx, int inum, vbios_regs_t *regs, int xfer_size);
int vbios_call(vbios_context_t *ctx, int seg, int offs, vbios_regs_t *regs, int xfer_size);
int vbios_dowarmboot(vbios_context_t *ctx, unsigned ax_val, unsigned char *biosptr, int bios_size);
void *vbios_get_realptr(vbios_context_t *ctx, unsigned seg, unsigned off);
int vbios_store_bios(disp_adapter_t *adp, vbios_context_t *vbios);
int vbios_retrieve_bios(disp_adapter_t *adp, uint8_t **zeropage, uint8_t **rom, int *romsize);
int vbios_acquire_bios_resources(vbios_context_t *ctx);
void vbios_release_bios_resources(vbios_context_t *ctx);
int vbios_set_text_mode3(vbios_context_t *ctx);
__END_DECLS
#endif /* __X86__ */
#endif /* _GRAPHICS_VBIOS_H_INCLUDED */

74
devg/public/graphics/vcap.h Обычный файл
Просмотреть файл

@ -0,0 +1,74 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/* Types and defines for video capture support */
#ifndef _GRAPHICS_VCAP_H_INCLUDED
#define _GRAPHICS_VCAP_H_INCLUDED
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#include <graphics/display.h>
#endif
/* disp_vcap_props.flags argument to "set_flags" */
#define DISP_VCAP_FLAG_WEAVE 0x00000001
#define DISP_VCAP_FLAG_BOB 0x00000002
#define DISP_VCAP_FLAG_ODD_FRAMES_ONLY 0x00000004
#define DISP_VCAP_FLAG_EVEN_FRAMES_ONLY 0x00000008
typedef struct disp_vcap_props {
unsigned flags;
int input_source;
int src_width; /* Unscaled, uncropped source width */
int src_height; /* Unscaled, uncropped source height */
int src_x1, src_y1; /* Source crop rectangle upper left */
int src_x2, src_y2; /* Source crop rectangle lower right */
int dst_width; /* Post-scaling width */
int dst_height; /* Post-scaling height */
int h_offset; /* Horizontal sync offset */
int v_offset; /* Vertical sync offset */
int h_total; /* Pixels clocks per horizontal period */
int v_total; /* Total scanlines per vertical period */
intptr_t reserved[6];
} disp_vcap_props_t;
typedef struct disp_vcap_adjust {
int brightness; /* Range -128->127, 0 means "normal" */
int contrast; /* Range -128->127, 0 means "normal" */
int saturation; /* Range -128->127, 0 means "normal" */
int hue; /* Range -128->127, 0 means "normal" */
intptr_t reserved[4];
} disp_vcap_adjust_t;
__BEGIN_DECLS
typedef struct disp_vcapfuncs {
int (*init)(disp_adapter_t *adapter, char *optstring);
void (*fini)(disp_adapter_t *adapter);
void (*module_info)(disp_adapter_t *adapter, disp_module_info_t *info);
int (*set_props)(disp_adapter_t *adapter,
int unit, disp_vcap_props_t *props);
int (*set_adjustments)(disp_adapter_t *adapter,
int unit, disp_vcap_adjust_t *adjustments);
int (*bind_layer)(disp_adapter_t *adapter, int unit,
int dispno, int layer_idx);
int (*set_enabled)(disp_adapter_t *adapter, int unit, int enabled);
void (*wait_vsync)(disp_adapter_t *adapter, int unit);
int (*set_power_mode)(disp_adapter_t *adapter,
int unit, pm_power_mode_t mode);
void (*reserved[8])();
} disp_vcapfuncs_t;
/* Main video capture module entry point */
typedef int (*get_vcapfuncs_t)(disp_adapter_t *adapter,
disp_vcapfuncs_t *funcs, int tabsize);
extern int devg_get_vcapfuncs(disp_adapter_t *adapter,
disp_vcapfuncs_t *funcs, int tabsize);
__END_DECLS
#endif /* _GRAPHICS_VCAP_H_INCLUDED */

230
devg/public/graphics/vesa.h Обычный файл
Просмотреть файл

@ -0,0 +1,230 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifdef __X86__
#ifndef _GRAPHICS_VESA_H_INCLUDED
#define _GRAPHICS_VESA_H_INCLUDED
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#include <graphics/display.h>
#endif
#ifndef _GRAPHICS_VBIOS_H_INCLUDED
#include <graphics/vbios.h>
#endif
#include <_pack1.h>
struct VESATimingDetail {
uint16_t PixClock;
uint8_t HALow;
uint8_t HBLow;
uint8_t HABHigh;
uint8_t VALow;
uint8_t VBLow;
uint8_t VABHigh;
uint8_t HSyncOLow;
uint8_t HSyncWLow;
uint8_t VSyncOffWidLow;
uint8_t SyncOffWidHigh;
uint8_t HSizeLow;
uint8_t VSizeLow;
uint8_t SizeHigh;
uint8_t HBorder;
uint8_t VBorder;
uint8_t Flags;
};
struct vesa_edid {
uint8_t b0;
uint8_t b1;
uint8_t b2;
uint8_t b3;
uint8_t b4;
uint8_t b5;
uint8_t b6;
uint8_t b7;
uint16_t Manufacturer;
uint16_t Product;
uint32_t SerialNum;
uint8_t MfgrWeek;
uint8_t MfgrYear;
uint8_t EDIDVersion;
uint8_t EDIDRevision;
uint8_t VidInDef;
uint8_t MaxHSize;
uint8_t MaxVSize;
uint8_t Gamma;
uint8_t DPMSSupport;
uint8_t RGLow;
uint8_t BWLow;
uint8_t RedX;
uint8_t RedY;
uint8_t GreenX;
uint8_t GreenY;
uint8_t BlueX;
uint8_t BlueY;
uint8_t WhiteX;
uint8_t WhiteY;
uint8_t EstTiming1;
uint8_t EstTiming2;
uint8_t MfgrTiming;
uint16_t StdTiming[8];
struct VESATimingDetail Detail[4];
uint8_t ExtensionFlag;
uint8_t Checksum;
uint8_t spare[101];
};
#define CIB_FLAG_DSCAN 0x01
#define CIB_FLAG_NO_DSCAN 0
#define CIB_FLAG_INTERLACED 0x02
#define CIB_FLAG_HSYNC_PLUS 0
#define CIB_FLAG_HSYNC_MINUS 0x04
#define CIB_FLAG_VSYNC_PLUS 0
#define CIB_FLAG_VSYNC_MINUS 0x08
typedef struct {
uint16_t HorizontalTotal;
uint16_t HorizontalSyncStart;
uint16_t HorizontalSyncEnd;
uint16_t VerticalTotal;
uint16_t VerticalSyncStart;
uint16_t VerticalSyncEnd;
uint8_t Flags;
uint32_t PixelClock;
uint16_t RefreshRate;
uint8_t Reserved[40];
} CRTCInfoBlock_t;
typedef struct {
uint32_t Signature;
uint16_t EntryPoint;
uint16_t Initialize;
uint16_t BIOSDataSelector;
uint16_t A0000Selector;
uint16_t B0000Selector;
uint16_t B8000Selector;
uint16_t CodeSegSelector;
uint8_t InProtectMode;
uint8_t Checksum;
} PMInfoBlock_t;
typedef struct {
int32_t Mid;
int16_t XRes;
int16_t YRes;
int16_t BitsPerPixel;
int16_t MemModel;
} ModeInfo_t;
typedef struct {
uint16_t Offset;
uint16_t Seg;
} BIOSFarPointer;
typedef struct {
uint32_t VESASignature;
uint16_t VESAVersion;
BIOSFarPointer OEMStringPtr;
uint32_t Capabilities;
BIOSFarPointer VideoModePtr;
uint16_t TotalMemory;
/* VESA2 */
uint16_t VBESoftwareRev;
BIOSFarPointer OEMVendorNamePtr;
BIOSFarPointer OEMProductNamePtr;
BIOSFarPointer OEMProductRevPtr;
uint8_t Reserved[222];
uint8_t OEMData[256];
} VESAInfoBlockStruct;
typedef struct {
uint16_t ModeAttributes;
uint8_t WinAAttributes;
uint8_t WinBAttributes;
uint16_t WinGranularity;
uint16_t WinSize;
uint16_t WinASegment;
uint16_t WinBSegment;
BIOSFarPointer WinFuncPtr; /* Set to 0 */
uint16_t BytesPerScanLine;
uint16_t XResolution;
uint16_t YResolution;
uint8_t XCharSize;
uint8_t YCharSize;
uint8_t NumberOfPlanes;
uint8_t BitsPerPixel;
uint8_t NumberOfBanks;
uint8_t MemoryModel;
uint8_t BankSize;
uint8_t NumberOfImagePages;
uint8_t Reserved; /* Set to 1 */
uint8_t RedMaskSize, RedFieldPosition;
uint8_t GreenMaskSize, GreenFieldPosition;
uint8_t BlueMaskSize, BlueFieldPosition;
uint8_t RsvdMaskSize, RsvdFieldPosition;
uint8_t DirectColorModeInfo;
/* VESA2 */
uint32_t PhysBasePtr;
uint32_t OffScreenMemOffset;
uint16_t OffScreenMemSize;
/* VBE 3.0 (optional) */
uint16_t LinBytesPerScanLine;
uint8_t BnkNumberOfImagePages;
uint8_t LinNumberOfImagePages;
uint8_t LinRedMaskSize;
uint8_t LinRedFieldPosition;
uint8_t LinGreenMaskSize;
uint8_t LinGreenFieldPosition;
uint8_t LinBlueMaskSize;
uint8_t LinBlueFieldPosition;
uint8_t LinRsvdMaskSize;
uint8_t LinRsvdFieldPosition;
/* VBE 3.0 (mandatory) */
uint32_t MaxPixelClock;
uint8_t cur_reserved[189];
} VESAModeInfoStruct;
#include <_packpop.h>
/* frame buffer memory models */
#define VESA_MM_TextMode 0x0
#define VESA_MM_CGAGraphics 0x1
#define VESA_MM_HGCGraphics 0x2
#define VESA_MM_MonoGraphics 0x2
#define VESA_MM_VGA4Plane 0x3
#define VESA_MM_VGA8Packed 0x4
#define VESA_MM_DirectColor 0x6
#define VESA_MM_DirectYUV 0x7
__BEGIN_DECLS
struct vesa_edid *vesa_get_edid(vbios_context_t *vbios, struct vesa_edid *edid);
int vesa_HaveDPMS(vbios_context_t *vbios);
int vesa_HaveSetDisplayOffset(vbios_context_t *vbios);
VESAInfoBlockStruct *vesa_InfoBlock(vbios_context_t *vbios,
VESAInfoBlockStruct *VIB);
uint8_t *vesa_OEMString(vbios_context_t *vbios,
VESAInfoBlockStruct *VIPtr, uint8_t *str);
uint16_t *vesa_ModeList(vbios_context_t *vbios,
VESAInfoBlockStruct *VIPtr, uint16_t *list);
VESAModeInfoStruct *vesa_ModeInfo(vbios_context_t *vbios,
int mode, VESAModeInfoStruct *buffer);
int vesa_SetDisplayOffset(vbios_context_t *vbios, int x, int y, int wait_vsync);
int vesa_SetDPMSMode(vbios_context_t *vbios, int mode);
int vesa_BIOSSetPalette(vbios_context_t *vbios,
disp_color_t *pal, int idx, int num);
__END_DECLS
#endif /* _GRAPHICS_VESA_H_INCLUDED */
#endif /* __X86__ */

127
devg/public/graphics/vid.h Обычный файл
Просмотреть файл

@ -0,0 +1,127 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/* Types and defines for Video Overlay / Scaler support */
#ifndef _GRAPHICS_VID_H_INCLUDED
#define _GRAPHICS_VID_H_INCLUDED
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#include <graphics/display.h>
#endif
#define DISP_VID_MAX_PLANES 3
#define DISP_VID_MAX_ALPHA 4
/* Describes an alpha-blended area of the video viewport */
typedef struct {
unsigned char src_alpha, dst_alpha; /* Blending factors */
unsigned alpha_mode; /* Blending mode */
unsigned short x1, y1, x2, y2;
} disp_vid_alpha_t;
/* YUV data formats FourCC Layout H sample (YUV) V sample (YUV) BPP */
#define DISP_PACKED_YUV_FORMAT_IYU1 0x31555949 /* U2Y2Y2V2Y2Y2 144 111 12 */
#define DISP_PACKED_YUV_FORMAT_IYU2 0x32555949 /* U4Y4V4U4Y4V4 111 111 24 */
#define DISP_PACKED_YUV_FORMAT_UYVY 0x59565955 /* U8Y8V8Y8 122 111 16 */
#define DISP_PACKED_YUV_FORMAT_YUY2 0x32595559 /* Y8U8Y8V8 122 111 16 */
#define DISP_PACKED_YUV_FORMAT_YVYU 0x55595659 /* Y8V8Y8U8 122 111 16 */
#define DISP_PACKED_YUV_FORMAT_V422 0x56343232 /* V8Y8U8Y8 122 111 16 */
#define DISP_PACKED_YUV_FORMAT_CLJR 0x524a4c43 /* V6U6Y5Y5Y5Y5 133 111 8 */
#define DISP_PLANAR_YUV_FORMAT_YVU9 0x39555659 /* YVU 144 144 9 */
#define DISP_PLANAR_YUV_FORMAT_YV12 0x32315659 /* YUV 122 122 12 */
/* There doesn't seem to be a FourCC for this one */
#define DISP_PLANAR_YUV_FORMAT_YUV420 0x00000100 /* YUV 122 111 16 */
/* These formats are the same as YV12, except the U and V planes do not have to contiguously follow the Y plane */
#define DISP_PLANAR_YUV_FORMAT_CLPL DISP_PLANAR_YUV_FORMAT_YV12 /* Cirrus Logic Planar format */
#define DISP_PLANAR_YUV_FORMAT_VBPL DISP_PLANAR_YUV_FORMAT_YV12 /* VooDoo Banshee planar format */
#define DISP_VID_CAP_SRC_CHROMA_KEY 0x00001000 /* Video viewport supports chroma-keying on frame data */
#define DISP_VID_CAP_DST_CHROMA_KEY 0x00002000 /* Video viewport supports chroma-keying on desktop data */
#define DISP_VID_CAP_BUSMASTER 0x00008000 /* Scaler device can bus-master the data from system ram */
#define DISP_VID_CAP_DOUBLE_BUFFER 0x00010000 /* Scaler channel can be double-buffered */
#define DISP_VID_CAP_BRIGHTNESS_ADJUST 0x00080000 /* Brightness of video viewport can be adjusted */
#define DISP_VID_CAP_CONTRAST_ADJUST 0x00100000 /* Contrast of video viewport can be adjusted */
/* General capabilities of a Video Scaler, for a given format */
typedef struct {
unsigned short size; /* Size of this struct */
unsigned short reserved0;
unsigned flags;
unsigned format;
int src_max_x; /* Maximum width of source frames */
int src_max_y; /* Maximum height of source frames */
int max_mag_factor_x; /* Magnification - 1 means cannot scale upwards */
int max_mag_factor_y; /* Magnification - 1 means cannot scale upwards */
int max_shrink_factor_x; /* 1 means cannot scale downwards */
int max_shrink_factor_y; /* 1 means cannot scale downwards */
unsigned reserved[8];
} disp_vid_channel_caps_t;
/* disp_vid_channel_props.flags */
#define DISP_VID_FLAG_ENABLE 0x00000001 /* Enable the video viewport */
#define DISP_VID_FLAG_CHROMA_ENABLE 0x00000002 /* Perform chroma-keying */
#define DISP_VID_FLAG_DOUBLE_BUFFER 0x00000004 /* Perform double-buffering */
#define DISP_VID_FLAG_DRIVER_DOES_COPY 0x00000010 /* Driver performs the copy of frame data in the nextframe routine */
#define DISP_VID_FLAG_APP_DOES_COPY 0x00000020 /* Driver copies the frame data adter calling the nextframe routine */
#define DISP_VID_FLAG_DISABLE_FILTERING 0x00000040 /* Do scaling by replication, turn of bilear filtering, interpolation etc. */
#define DISP_VID_FLAG_DRAWABLE_SURFACE 0x00000080 /* Want to be able to draw to the video surfaces */
#define DISP_VID_FLAG_TO_FRONT 0x00000100 /* This overlay should be brought in front of any other overlays */
#define DISP_VID_FLAG_TO_BACK 0x00000200 /* This overlay should be put underneath any other overlays */
/* disp_vid_channel_props.chroma_mode */
#define DISP_VID_CHROMA_FLAG_DST 0x00000001 /* Perform chroma test on desktop data */
#define DISP_VID_CHROMA_FLAG_SRC 0x00000002 /* Perform chroma test on video frame data */
/* Configurable properties of a video scaler channel */
typedef struct {
unsigned short size;
unsigned short reserved0;
unsigned flags;
unsigned format; /* Format of the frame data */
disp_color_t chroma_key0; /* Chroma-key color */
unsigned reserved1;
unsigned chroma_flags; /* Chroma-key comparison operation */
disp_color_t chroma_key_mask; /* Colors are masked with this before chroma comparison */
disp_color_t chroma_mode; /* Type of chroma key match to perform */
int x1, y1; /* Top left corner of video viewport in display coords*/
int x2, y2; /* Bottom right corner of video viewport in display coords */
int src_width, src_height; /* Dimensions of the video source data */
unsigned fmt_index; /* Selects the format of the source frame data */
short brightness; /* Brightness adjust. 0x7fff = normal, 0 darkest, 0xffff brightest */
short contrast; /* Contrast adjust. 0x7fff = normal, 0 minimum, 0xffff maximun */
disp_vid_alpha_t alpha[DISP_VID_MAX_ALPHA]; /* Regions of the video viewport to be blended with desktop */
unsigned reserved[8];
} disp_vid_channel_props_t;
__BEGIN_DECLS
typedef struct disp_vidfuncs {
int (*init)(disp_adapter_t *adapter, char *optstring);
void (*fini)(disp_adapter_t *adapter);
void (*module_info)(disp_adapter_t *adapter, disp_module_info_t *info);
int (*get_channel_caps)(disp_adapter_t *adapter, int channel,
int fmt_index, disp_vid_channel_caps_t *caps);
int (*set_channel_props)(disp_adapter_t *adapter, int channel,
disp_vid_channel_props_t *props,
disp_surface_t **yplane1, disp_surface_t **yplane2,
disp_surface_t **uplane1, disp_surface_t **uplane2,
disp_surface_t **vplane1, disp_surface_t **vplane2);
int (*next_frame)(disp_adapter_t *adapter, int channel);
int (*close_channel)(disp_adapter_t *adapter, int channel);
} disp_vidfuncs_t;
/* Main video overlay module entry point */
typedef int (*get_vidfuncs_t)(disp_adapter_t *adapter,
disp_vidfuncs_t *funcs, int tabsize);
extern int devg_get_vidfuncs(disp_adapter_t *adapter,
disp_vidfuncs_t *funcs, int tabsize);
__END_DECLS
#endif /* _GRAPHICS_VID_H_INCLUDED */

101
devg/public/graphics/vmem.h Обычный файл
Просмотреть файл

@ -0,0 +1,101 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#ifndef _GRAPHICS_VMEM_H_INCLUDED
#define _GRAPHICS_VMEM_H_INCLUDED
#ifndef _GRAPHICS_DISPLAY_H_INCLUDED
#include <graphics/display.h>
#endif
/* hint_flags argument to "alloc_surface" */
#define DISP_VMEM_HINT_USAGE(__flags) ((__flags) & 0x0000000f)
#define DISP_VMEM_HINT_USAGE_CPU 0x00000001
#define DISP_VMEM_HINT_USAGE_2D 0x00000002
#define DISP_VMEM_HINT_USAGE_3D 0x00000003
#define DISP_VMEM_HINT_USAGE_3D_BACKBUFFER 0x00000004
/* disp_aperture.flags */
#define DISP_APER_NOCACHE 0x00000001 /* Aperture must be mapped with PROT_NOCACHE */
#define DISP_APER_LAZYWRITE 0x00000002 /* Aperture supports write combining -- superceeded by DISP_APER_WRITECOMBINE */
#define DISP_APER_WRITECOMBINE 0x00000004 /* Aperture write combine */
#define DISP_APER_WRITETHROUGH 0x00000008 /* Aperture write through cache hit policy */
#define DISP_APER_WRITEBACK 0x00000010 /* Aperture write back cache hit policy */
#define DISP_APER_WRITEALLOC 0x00000020 /* Aperture write alloc cache miss policy */
#define DISP_APER_WRITENOALLOC 0x00000040 /* Aperture write no alloc cache miss policy */
#define DISP_MAX_APERTURES 8
typedef struct disp_aperture {
uint64_t base; /* Physical address */
unsigned size;
void *vaddr;
unsigned flags;
unsigned reserved[5];
} disp_aperture_t;
typedef struct disp_surface_info {
int aperture_index;
unsigned offset;
unsigned reserved[6];
} disp_surface_info_t;
#define DISP_ALLOCINFO_NO_EXTERNAL_ALLOC 0x00000001 /* Surface memory allocation on client side not supported */
typedef struct disp_alloc_info {
unsigned start_align;
unsigned end_align;
unsigned min_stride;
unsigned max_stride;
unsigned stride_gran;
unsigned prot_flags;
unsigned map_flags;
unsigned surface_flags;
unsigned alloc_flags;
unsigned row_gran;
unsigned reserved[2];
} disp_alloc_info_t;
__BEGIN_DECLS
typedef struct disp_memfuncs {
int (*init)(disp_adapter_t *adapter, char *optstring);
void (*fini)(disp_adapter_t *adapter);
void (*module_info)(disp_adapter_t *adapter, disp_module_info_t *info);
int (*reset)(disp_adapter_t *adapter, disp_surface_t *surf);
disp_surface_t * (*alloc_surface)(disp_adapter_t *adapter, int width,
int height, unsigned format, unsigned sflags, unsigned hint_flags);
int (*free_surface)(disp_adapter_t *adapter, disp_surface_t *surf);
unsigned long (*mem_avail)(disp_adapter_t *adapter, unsigned sflags);
disp_surface_t * (*alloc_layer_surface)(disp_adapter_t *adp,
int dispno[], int layer_idx[],
int nlayers, unsigned format, int surface_index,
int width, int height, unsigned sflags, unsigned hint_flags);
int (*set_power_mode)(disp_adapter_t *adapter, pm_power_mode_t mode);
int (*query_apertures)(disp_adapter_t *adapter, disp_aperture_t *apertures);
int (*query_surface)(disp_adapter_t *adapter,
disp_surface_t *surf, disp_surface_info_t *info);
int (*get_alloc_info)(disp_adapter_t *adapter, int width,
int height, unsigned format,
unsigned sflags, unsigned hint_flags, disp_alloc_info_t *info);
int (*get_alloc_layer_info)(disp_adapter_t *adp,
int dispno[], int layer_idx[], int nlayers, unsigned format,
int surface_index, int width, int height,
unsigned sflags, unsigned hint_flags, disp_alloc_info_t *info);
int (*submit_alloced_info)(disp_adapter_t *adapter, disp_surface_t *surf, unsigned flags);
int (*submit_freed_shmem)(disp_adapter_t *adapter, disp_surface_t *surf);
void (*reserved[3])(void);
} disp_memfuncs_t;
/* Main memory manager entry point */
typedef int (*get_memfuncs_t)(disp_adapter_t *adapter,
disp_memfuncs_t *funcs, int tabsize);
extern WINSIM_API int devg_get_memfuncs(disp_adapter_t *adapter,
disp_memfuncs_t *funcs, int tabsize);
__END_DECLS
#endif /* _GRAPHICS_VMEM_H_INCLUDED */

2
devg/vesabios/Makefile Обычный файл
Просмотреть файл

@ -0,0 +1,2 @@
LIST=OS
include recurse.mk

116
devg/vesabios/draw.c Обычный файл
Просмотреть файл

@ -0,0 +1,116 @@
/*
* (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*
* The "vesabios" driver - hands off all drawing functionality to the
* Flat Frame Buffer library.
*/
#include "vesabios.h"
#include <graphics/ffb.h>
int
vesa_misc_wait_idle(disp_adapter_t *adapter)
{
return 0;
}
int
vesa_draw_init(disp_adapter_t *adapter, char *optstring)
{
return 0;
}
void
vesa_fini(disp_adapter_t *adapter)
{
}
void
vesa_module_info(disp_adapter_t *adapter, disp_module_info_t *info)
{
info->description = "vesa - unaccelerated driver "
"for VESA 2.00 compliant adapters";
info->ddk_version_major = DDK_VERSION_MAJOR;
info->ddk_version_minor = DDK_VERSION_MINOR;
info->ddk_rev = DDK_REVISION;
info->driver_rev = 0;
}
int
devg_get_miscfuncs(disp_adapter_t *adapter,
disp_draw_miscfuncs_t *funcs, int tabsize)
{
DISP_ADD_FUNC(disp_draw_miscfuncs_t, funcs,
init, vesa_draw_init, tabsize);
DISP_ADD_FUNC(disp_draw_miscfuncs_t, funcs,
fini, vesa_fini, tabsize);
DISP_ADD_FUNC(disp_draw_miscfuncs_t, funcs,
module_info, vesa_module_info, tabsize);
DISP_ADD_FUNC(disp_draw_miscfuncs_t, funcs,
get_2d_caps, ffb_get_2d_caps, tabsize);
DISP_ADD_FUNC(disp_draw_miscfuncs_t, funcs,
get_corefuncs_sw, ffb_get_corefuncs, tabsize);
DISP_ADD_FUNC(disp_draw_miscfuncs_t, funcs,
get_contextfuncs_sw, ffb_get_contextfuncs, tabsize);
DISP_ADD_FUNC(disp_draw_miscfuncs_t, funcs,
attach_external, vesa_attach_external, tabsize);
DISP_ADD_FUNC(disp_draw_miscfuncs_t, funcs,
detach_external, vesa_detach_external, tabsize);
DISP_ADD_FUNC(disp_draw_miscfuncs_t, funcs,
recover, vesa_recover, tabsize);
DISP_ADD_FUNC(disp_draw_miscfuncs_t, funcs,
wait_idle, vesa_misc_wait_idle, tabsize);
return 0;
}
int
devg_get_corefuncs(disp_adapter_t *adapter,
unsigned pixel_format, disp_draw_corefuncs_t *funcs, int tabsize)
{
return ffb_get_corefuncs(adapter, pixel_format, funcs, tabsize);
}
int
devg_get_contextfuncs(disp_adapter_t *adapter,
disp_draw_contextfuncs_t *funcs, int tabsize)
{
return ffb_get_contextfuncs(adapter, funcs, tabsize);
}
/*
* Set up things so that miscfuncs, corefuncs and contextfuncs
* can be called by an external process.
*/
int
vesa_attach_external(disp_adapter_t *adapter, disp_aperture_t aper[])
{
vb_context_t *vb_ctx = adapter->shmem;
adapter->ms_ctx = vb_ctx;
return 0;
}
int
vesa_detach_external(disp_adapter_t *adapter)
{
return 0;
}
/*
* Called when a client process terminated unexpectedly. This could have
* happened in the middle of adding draw commands to the ring buffer.
* Reset the ring buffer so any partial draw commands are not sent to
* the Radeon.
*/
int
vesa_recover(disp_adapter_t *adapter)
{
return 0;
}

151
devg/vesabios/init.c Обычный файл
Просмотреть файл

@ -0,0 +1,151 @@
/*
* (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <malloc.h>
#include <sys/mman.h>
#include "vesabios.h"
static int
vesa_init(disp_adapter_t *adapter, char *optstring)
{
vb_context_t *vb_ctx = NULL;
vbios_regs_t regs;
VESAInfoBlockStruct *VIPtr;
char *rombase;
int rc = -1;
if (vbios_register(adapter, 0) == -1)
goto done;
if (adapter->shmem == NULL) {
if ((vb_ctx = calloc(1, sizeof (*vb_ctx))) == NULL)
goto fail;
vb_ctx->free_context = 1;
} else {
vb_ctx = adapter->shmem;
memset(vb_ctx, 0, sizeof (*vb_ctx));
}
adapter->ms_ctx = vb_ctx;
vb_ctx->adapter = adapter;
/* Register with the display utility lib */
if (disp_register_adapter(adapter) == -1)
goto fail;
/*
* Grab ownership of legacy VGA registers before activating
* the device.
*/
if (disp_acquire_vga_resources(adapter) == -1) {
disp_unregister_adapter(adapter);
goto fail;
}
disp_pci_init(adapter, DISP_PCI_INIT_BASES);
if ((rombase = disp_get_rom_image(adapter, 0, NULL, 0, 0)) == NULL)
goto done;
disp_warm_boot(adapter, rombase);
free(rombase);
disp_device_active(adapter, 1, 1);
VIPtr = (void *)adapter->vbios->xfer_area_ptr;
/* Make sure the BIOS is present and correct */
regs.eax = 0x4f00;
regs.es = adapter->vbios->xfer_area_seg;
regs.edi = adapter->vbios->xfer_area_off;
VIPtr = (VESAInfoBlockStruct *)adapter->vbios->xfer_area_ptr;
VIPtr->VESASignature = 0x32454256; /* VBE2 */
vbios_int(adapter->vbios, 0x10, &regs, 512);
disp_device_active(adapter, 0, 1);
#ifndef __ARM__
adapter->caps |= DISP_CAP_NO_IO_PRIVITY;
#endif
if ((regs.eax & 0xffff) == 0x004f) {
/* Max one display controller supported */
rc = 1;
adapter->caps |= DISP_CAP_MULTI_MONITOR_SAFE;
}
done:
disp_release_vga_resources(adapter);
if (rc == -1) {
disp_unregister_adapter(adapter);
fail:
if (vb_ctx && vb_ctx->free_context)
free(vb_ctx);
if (adapter->vbios)
vbios_unregister(adapter->vbios);
}
return rc;
}
static void
vesa_fini(disp_adapter_t *adapter)
{
vb_context_t *vb = adapter->ms_ctx;
if (adapter->ms_ctx == NULL)
/* Tsk tsk */
return;
if (vb->vidptr)
disp_munmap_device_memory(vb->vidptr, vb->vidsize);
vesa_restore_vga(adapter);
if (vb->free_context)
free(vb);
disp_pci_shutdown(adapter);
disp_unregister_adapter(adapter);
vbios_unregister(adapter->vbios);
}
int
devg_get_modefuncs(disp_adapter_t *adp, disp_modefuncs_t *funcs, int tabsize)
{
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
init, vesa_init, tabsize);
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
fini, vesa_fini, tabsize);
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
module_info, vesa_module_info, tabsize);
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
get_modeinfo, vesa_get_modeinfo, tabsize);
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
get_modelist, vesa_get_modelist, tabsize);
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
set_mode, vesa_set_mode, tabsize);
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
set_dpms_mode, vesa_set_dpms_mode, tabsize);
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
set_display_offset, vesa_set_display_offset, tabsize);
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
set_palette, vesa_set_palette, tabsize);
DISP_ADD_FUNC(disp_modefuncs_t, funcs,
set_scroll_position, vesa_set_scroll_pos, tabsize);
return 0;
}

182
devg/vesabios/mem.c Обычный файл
Просмотреть файл

@ -0,0 +1,182 @@
/*
* (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#include <string.h>
#include <stdlib.h>
#include "vesabios.h"
/*
* Since this driver is unaccelerated, everything execpt the main display
* is allocated from system RAM, since access to frame buffer RAM is
* generally *much* slower.
*/
int
devg_get_memfuncs(disp_adapter_t *adp, disp_memfuncs_t *funcs, int tabsize)
{
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
init, vesa_mem_init, tabsize);
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
fini, vesa_mem_fini, tabsize);
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
module_info, vesa_module_info, tabsize);
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
reset, vesa_mem_reset, tabsize);
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
alloc_surface, vesa_alloc_surface, tabsize);
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
free_surface, vesa_free_surface, tabsize);
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
mem_avail, vesa_mem_avail, tabsize);
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
query_apertures, vesa_query_apertures, tabsize);
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
query_surface, vesa_query_surface, tabsize);
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
get_alloc_info, vesa_get_alloc_info, tabsize);
DISP_ADD_FUNC(disp_memfuncs_t, funcs,
get_alloc_layer_info, vesa_get_alloc_layer_info, tabsize);
return 0;
}
int
vesa_mem_init(disp_adapter_t *adapter, char *optstring)
{
vb_context_t *vb = adapter->ms_ctx;
vb->visible_allocated = 0;
return 0;
}
void
vesa_mem_fini(disp_adapter_t *adapter)
{
}
int
vesa_mem_reset(disp_adapter_t *adapter, disp_surface_t *surf)
{
vb_context_t *vb = adapter->ms_ctx;
vb->visible_allocated = 0;
return 0;
}
disp_surface_t *
vesa_alloc_surface(disp_adapter_t *adapter,
int width, int height, unsigned format, unsigned flags, unsigned user_flags)
{
vb_context_t *vb = adapter->ms_ctx;
disp_surface_t *surf = NULL;
if (vb->visible.height != 0 && (flags & DISP_SURFACE_DISPLAYABLE)) {
/*
* We cannot move the display offset, so there can only
* be a single displayable surface, at offset 0
*/
if(vb->visible_allocated) {
return NULL;
}
vb->visible_allocated = 1;
vb->visible.size = sizeof(vb->visible);
return &vb->visible;
}
return surf;
}
int
vesa_free_surface(disp_adapter_t *adapter, disp_surface_t *surf)
{
vb_context_t *vb = adapter->ms_ctx;
if (surf == &vb->visible) {
vb->visible_allocated = 0;
return 0;
}
disp_freemem(surf->vidptr, surf->height * surf->stride);
free(surf);
return 0;
}
unsigned long
vesa_mem_avail(disp_adapter_t *adapter, unsigned flags)
{
return 0;
}
int
vesa_query_apertures(disp_adapter_t *adp, disp_aperture_t *ap)
{
vb_context_t *vb_ctx = adp->ms_ctx;
ap->base = vb_ctx->vidbase;
ap->size = vb_ctx->vidsize;
ap->flags = DISP_APER_NOCACHE;
return 1;
}
/*
* return the aperture within which the memory surface resides, and
* the physical offset of the memory within that aperture
*/
int
vesa_query_surface(disp_adapter_t *adp,
disp_surface_t *surf, disp_surface_info_t *info)
{
info->aperture_index = 0;
info->offset = surf->offset;
return 0;
}
/*
* If a client of the driver wants to allocate memory itself,
* it must allocate it in accordance with the parameters returned by
* this process. Since this memory will not be coming from
* video memory, we must check the flags accordingly.
*/
int
vesa_get_alloc_info(disp_adapter_t *adp,
int width, int height, unsigned format,
unsigned flags, unsigned user_flags, disp_alloc_info_t *info)
{
flags &= DISP_SURFACE_CAPS_MASK;
if (flags & ~(DISP_SURFACE_CPU_LINEAR_READABLE |
DISP_SURFACE_CPU_LINEAR_WRITEABLE|
DISP_SURFACE_PAGE_ALIGNED|DISP_SURFACE_PHYS_CONTIG))
return -1;
info->start_align = 4;
info->end_align = 1;
info->min_stride = width * DISP_BYTES_PER_PIXEL(format);
info->max_stride = ~0;
info->stride_gran = 4;
info->map_flags = 0;
info->prot_flags = DISP_PROT_READ | DISP_PROT_WRITE;
info->surface_flags = DISP_SURFACE_CPU_LINEAR_READABLE |
DISP_SURFACE_CPU_LINEAR_WRITEABLE | DISP_SURFACE_DRIVER_NOT_OWNER;
return 0;
}
int
vesa_get_alloc_layer_info(disp_adapter_t *adp, int dispno[], int layer_idx[],
int nlayers, unsigned format, int surface_index, int width, int height,
unsigned sflags, unsigned hint_flags, disp_alloc_info_t *info)
{
/* No layers */
return -1;
}

440
devg/vesabios/mode.c Обычный файл
Просмотреть файл

@ -0,0 +1,440 @@
/*
* (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "vesabios.h"
static void
vga_enter(disp_adapter_t *adapter)
{
disp_acquire_vga_resources(adapter);
disp_device_active(adapter, 1, 1);
}
static void
vga_leave(disp_adapter_t *adapter)
{
vb_context_t *vb = adapter->ms_ctx;
disp_device_active(adapter, 0, vb->mode_set);
disp_release_vga_resources(adapter);
}
static int
setstride(vb_context_t *ctx)
{
vbios_regs_t regs;
memset(&regs, 0, sizeof regs);
regs.eax = 0x4f06;
regs.ebx = 2;
regs.ecx = ctx->vidstride; /* set stride to specific width */
if (vbios_int(ctx->adapter->vbios, 0x10, &regs, 0) != -1)
return 0;
else
return -1;
}
static int
setmode(vb_context_t *ctx, unsigned mode, CRTCInfoBlock_t *crtc_params)
{
vbios_regs_t regs;
int xfer_size = 0;
struct vbios_context *vbios = ctx->adapter->vbios;
memset(&regs, 0, sizeof regs);
if (mode < 0x100) {
/* VGA bios set mode */
regs.eax = mode;
} else {
/* VESA bios set mode */
regs.eax = 0x4f02;
regs.ebx = mode;
if (crtc_params != NULL) {
/* VBE 3.0 refresh rate support */
regs.ebx |= 1<<11;
regs.es = vbios->xfer_area_seg;
regs.edi = vbios->xfer_area_off;
xfer_size = sizeof (*crtc_params);
}
}
if (vbios_int(ctx->adapter->vbios, 0x10, &regs, xfer_size) != -1 &&
!(mode >= 0x100 && (regs.eax & 0xffff) != 0x004f))
return 0;
else
return -1;
}
/* Put the chip back into standard VGA mode */
void
vesa_restore_vga(disp_adapter_t *ctx)
{
vb_context_t *vb = ctx->ms_ctx;
vga_enter(ctx);
if (setmode(ctx->ms_ctx, 3, NULL) == -1)
disp_perror(ctx, "vesa_restore_vga");
vga_leave(ctx);
vb->mode_set = 0;
}
static void
vesa_get_crtc_params(disp_adapter_t *adapter,
int refresh, int xres, int yres, CRTCInfoBlock_t *crtc_params)
{
disp_crtc_settings_t crtc;
int h_gran;
if (disp_mode_get_entry(adapter, &crtc,
"/etc/system/config/crtc-settings", xres, yres, refresh) != 0) {
crtc.xres = xres;
crtc.yres = yres;
crtc.refresh = refresh;
crtc.h_granularity = h_gran = 8;
crtc.v_granularity = 1;
disp_crtc_calc(&crtc);
} else
h_gran = 1;
memset(crtc_params, 0, sizeof (*crtc_params));
crtc_params->HorizontalTotal = crtc.h_total * h_gran;
crtc_params->HorizontalSyncStart = crtc.h_sync_start * h_gran;
crtc_params->HorizontalSyncEnd =
(crtc.h_sync_start+crtc.h_sync_len) * h_gran;
crtc_params->VerticalTotal = crtc.v_total;
crtc_params->VerticalSyncStart = crtc.v_sync_start;
crtc_params->VerticalSyncEnd =
(crtc.v_sync_start+crtc.v_sync_len);
crtc_params->Flags = 0;
crtc_params->PixelClock = crtc.pixel_clock * 1000;
crtc_params->RefreshRate = crtc.refresh * 100;
}
/* Place details on `mode' into `info' struct */
int
vesa_get_modeinfo(disp_adapter_t *ctx,
int dispno, disp_mode_t mode, disp_mode_info_t *info)
{
VESAModeInfoStruct vmode;
VESAInfoBlockStruct VIB;
int rc = -1;
DISP_ASSERT(dispno == 0);
memset(info, 0, sizeof (*info));
vga_enter(ctx);
if (vesa_ModeInfo(ctx->vbios, mode & ~0x4000, &vmode) == NULL)
goto done;
if (vesa_InfoBlock(ctx->vbios, &VIB) == NULL)
goto done;
info->size = sizeof (*info);
info->mode = mode;
info->xres = vmode.XResolution;
info->yres = vmode.YResolution;
/* Linear frame buffer properties */
if (vmode.PhysBasePtr == 0)
goto done;
else
info->fb_addr = vmode.PhysBasePtr;
if (info->fb_addr == 0) {
errno = EINVAL;
goto done;
}
info->fb_stride = vmode.BytesPerScanLine;
info->fb_size = VIB.TotalMemory * 0x10000;
switch (vmode.BitsPerPixel) {
case 8:
info->pixel_format = DISP_SURFACE_FORMAT_PAL8;
break;
case 15:
case 16:
if (vmode.GreenMaskSize == 5)
info->pixel_format = DISP_SURFACE_FORMAT_ARGB1555;
else
info->pixel_format = DISP_SURFACE_FORMAT_RGB565;
break;
case 24:
info->pixel_format = DISP_SURFACE_FORMAT_RGB888;
break;
case 32:
info->pixel_format = DISP_SURFACE_FORMAT_ARGB8888;
break;
}
#if 0
if (vesa_HaveSetDisplayOffset(ctx->vbios))
info->caps |= DISP_MCAP_SET_DISPLAY_OFFSET;
#endif
if (vesa_HaveDPMS(ctx->vbios))
info->caps |= DISP_MCAP_DPMS_SUPPORTED;
info->crtc_start_gran = DISP_BITS_PER_PIXEL(info->pixel_format);
// Panning supported if not 24bpp (24bpp screwed up strides on a lot of cards)
if(info->pixel_format != DISP_SURFACE_FORMAT_RGB888) {
info->caps |= DISP_MCAP_VIRTUAL_PANNING;
info->crtc_pitch_gran = 16;
info->max_virtual_width = 3200;
info->max_virtual_height = 2400;
}
if (VIB.VESAVersion >= 0x300) {
info->u.fixed.refresh[0] = 60;
info->u.fixed.refresh[1] = 70;
info->u.fixed.refresh[2] = 72;
info->u.fixed.refresh[3] = 75;
info->u.fixed.refresh[4] = 85;
info->u.fixed.refresh[5] = 0;
} else {
info->u.fixed.refresh[0] = 60; /* More than likely if not VESA 3 */
info->u.fixed.refresh[1] = 0;
}
rc = 0;
done:
vga_leave(ctx);
return rc;
}
int
vesa_set_mode(disp_adapter_t *ctx, int dispno, disp_mode_t mode,
disp_crtc_settings_t *settings, disp_surface_t *surf, unsigned flags)
{
vb_context_t *vb = ctx->ms_ctx;
disp_mode_info_t mi;
int rc;
CRTCInfoBlock_t *crtc_params;
DISP_ASSERT(dispno == 0);
if (vesa_get_modeinfo(ctx, 0, mode, &mi) == -1)
return -1;
if (vb->vidptr) {
disp_munmap_device_memory(vb->vidptr, mi.fb_size);
vb->vidptr = NULL;
}
if (mi.fb_addr == 0) {
errno = EINVAL;
return -1;
}
vb->vidptr = disp_mmap_device_memory(mi.fb_addr, mi.fb_size,
DISP_PROT_READ | DISP_PROT_WRITE, DISP_MAP_LAZY);
if (vb->vidptr == NULL)
return -1;
vb->vidbase = mi.fb_addr;
ctx->adapter_ram = vb->vidsize = mi.fb_size;
if(surf->stride > mi.fb_stride && mi.caps & DISP_MCAP_VIRTUAL_PANNING)
vb->vidstride = surf->stride;
else
vb->vidstride = mi.fb_stride;
vb->format = mi.pixel_format;
/* Fill in info about where to draw */
surf->vidptr = vb->vidptr;
surf->paddr = mi.fb_addr;
surf->offset = 0;
surf->stride = vb->vidstride;
surf->pixel_format = mi.pixel_format;
surf->flags = DISP_SURFACE_DISPLAYABLE | DISP_SURFACE_PAGE_ALIGNED |
DISP_SURFACE_CPU_LINEAR_READABLE |
DISP_SURFACE_CPU_LINEAR_WRITEABLE | DISP_SURFACE_2D_TARGETABLE;
if (!(mi.caps & DISP_MCAP_SET_DISPLAY_OFFSET)) {
/*
* There can only be a single displayable surface, and
* it must begin at offset 0
*/
memcpy(&vb->visible, surf, sizeof (*surf));
vb->visible.height = surf->height;
} else
vb->visible.height = 0;
vb->visible.offset = 0;
vb->current_mode_caps = mi.caps;
if (settings->refresh > 60) {
/* VBE 3.0 refresh rate support */
crtc_params = (void *)ctx->vbios->xfer_area_ptr;
vesa_get_crtc_params(ctx, settings->refresh, mi.xres, mi.yres,
crtc_params);
} else
crtc_params = NULL;
vga_enter(ctx);
rc = setmode(ctx->ms_ctx, mode, crtc_params);
if(surf->stride > mi.fb_stride && mi.caps & DISP_MCAP_VIRTUAL_PANNING)
if (setstride(ctx->ms_ctx) == -1)
disp_printf(vb->adapter,"Set Stride failed");
if (rc == 0)
vb->mode_set = 1;
else
errno = ENOSYS;
vga_leave(ctx);
return rc;
}
/* Place a list of mode ID's in `list' */
int
vesa_get_modelist(disp_adapter_t *ctx, int dispno, unsigned short *list,
int index, int size)
{
uint16_t VModes[DISP_MAX_MODES + 1];
int i, j = 0, rc = -1;
VESAInfoBlockStruct VIB;
VESAModeInfoStruct VMI;
if (dispno != 0)
return -1;
list[0] = DISP_MODE_LISTEND;
vga_enter(ctx);
if (vesa_InfoBlock(ctx->vbios, &VIB) != NULL) {
/* Get the list of VESA modes */
if (vesa_ModeList(ctx->vbios, &VIB, VModes) == NULL)
goto done;
for (i = 0; i < DISP_MAX_MODES; i++) {
if (i < index)
continue;
if (j >= size-1)
break;
if (VModes[i] == 0xffff)
break;
(void)vesa_ModeInfo(ctx->vbios, VModes[i], &VMI);
if (VMI.MemoryModel != VESA_MM_DirectColor &&
!(VMI.MemoryModel == VESA_MM_VGA8Packed &&
(VModes[i] & 0xf00)))
continue;
/* Don't support any of this tripe yet */
if (VMI.NumberOfPlanes > 1 || VMI.NumberOfBanks > 1
|| VMI.BitsPerPixel < 8)
continue;
if (!(VMI.ModeAttributes & 1))
continue;
/* Check that mode fits into memory */
if ((VMI.BytesPerScanLine * VMI.YResolution) > (VIB.TotalMemory * 0x10000))
continue;
if (VModes[i] >= 0x100 && (VMI.ModeAttributes & 0x80) &&
VIB.VESAVersion >= 0x200) {
/* A linear VESA mode */
list[j++] = VModes[i] | 0x4000;
}
rc = 0;
}
}
list[j] = DISP_MODE_LISTEND;
done:
vga_leave(ctx);
return rc;
}
int
vesa_set_display_offset(disp_adapter_t *ctx,
int dispno, unsigned offset, int wait_vsync)
{
vb_context_t *vb = ctx->ms_ctx;
int rc;
DISP_ASSERT(dispno == 0);
vga_enter(ctx);
rc = vesa_SetDisplayOffset(ctx->vbios,
offset%vb->vidstride, offset/vb->vidstride, wait_vsync);
vga_leave(ctx);
return rc;
}
void
vesa_set_scroll_pos(disp_adapter_t *adapter, int dispno,
unsigned xoff, unsigned yoff)
{
vb_context_t *vb = adapter->ms_ctx;
int rc;
unsigned offset;
offset = (yoff*vb->vidstride) +
((xoff*DISP_BITS_PER_PIXEL(vb->format)+ 7)>>3);
DISP_ASSERT(dispno == 0);
vga_enter(adapter);
rc = vesa_SetDisplayOffset(adapter->vbios,
(offset/DISP_BYTES_PER_PIXEL(vb->format))%vb->vidstride,
offset/vb->vidstride, 0);
vga_leave(adapter);
}
int
vesa_set_palette(disp_adapter_t *ctx, int dispno,
int index, int count, disp_color_t *pal)
{
int rc;
DISP_ASSERT(dispno == 0);
vga_enter(ctx);
rc = vesa_BIOSSetPalette(ctx->vbios, pal, index, count);
vga_leave(ctx);
return rc;
}
int
vesa_set_dpms_mode(disp_adapter_t *ctx, int dispno, int dpms_mode)
{
int rc;
DISP_ASSERT(dispno == 0);
vga_enter(ctx);
rc = vesa_SetDPMSMode(ctx->vbios, dpms_mode);
vga_leave(ctx);
return rc;
}

2
devg/vesabios/nto/Makefile Обычный файл
Просмотреть файл

@ -0,0 +1,2 @@
LIST=CPU
include recurse.mk

2
devg/vesabios/nto/x86/Makefile Обычный файл
Просмотреть файл

@ -0,0 +1,2 @@
LIST=VARIANT
include recurse.mk

1
devg/vesabios/nto/x86/dll/Makefile Обычный файл
Просмотреть файл

@ -0,0 +1 @@
include ../../../../common.mk

8
devg/vesabios/pinfo.mk Обычный файл
Просмотреть файл

@ -0,0 +1,8 @@
#
# (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
#
define PINFO
PINFO DESCRIPTION=Generic graphics driver dll for VESA 2.0 BIOS or greater - loaded by io-graphics
endef
EXTRA_CCDEPS += $(PROJECT_ROOT)/$(SECTION)/vesabios.h

62
devg/vesabios/vesabios.h Обычный файл
Просмотреть файл

@ -0,0 +1,62 @@
/*
* (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
*/
#include <graphics/display.h>
#include <graphics/disputil.h>
#include <graphics/vesa.h>
#include <graphics/vbios.h>
typedef struct {
disp_adapter_t *adapter;
unsigned char *vidptr;
unsigned vidsize;
unsigned vidstride;
unsigned vidbase;
unsigned current_mode_caps;
disp_surface_t visible;
int visible_allocated;
int mode_set;
uint32_t format;
int free_context;
} vb_context_t;
int vesa_mem_init(disp_adapter_t *adapter, char *optstring);
void vesa_mem_fini(disp_adapter_t *adapter);
int vesa_mem_reset(disp_adapter_t *adapter, disp_surface_t *surf);
disp_surface_t *vesa_alloc_surface(disp_adapter_t *adapter,
int width, int height, unsigned format, unsigned flags, unsigned user_flags);
int vesa_free_surface(disp_adapter_t *adapter, disp_surface_t *surf);
unsigned long vesa_mem_avail(disp_adapter_t *adapter, unsigned sflags);
int vesa_get_modelist(disp_adapter_t *ctx, int dispno, unsigned short *list,
int index, int size);
int vesa_get_modeinfo(disp_adapter_t *ctx, int dispno,
disp_mode_t mode, disp_mode_info_t *info);
int vesa_set_mode(disp_adapter_t *ctx, int dispno, disp_mode_t mode,
disp_crtc_settings_t *settings, disp_surface_t *surface, unsigned flags);
void vesa_disable_vga(disp_adapter_t *ctx);
void vesa_restore_vga(disp_adapter_t *ctx);
int vesa_set_dpms_mode(disp_adapter_t *ctx, int dispno, int dpms_mode);
int vesa_set_display_offset(disp_adapter_t *ctx, int dispno,
unsigned offset, int wait_vsync);
int vesa_set_palette(disp_adapter_t *ctx, int dispno,
int index, int count, disp_color_t *pal);
void vesa_set_scroll_pos(disp_adapter_t *adapter, int dispno,
unsigned xoff, unsigned yoff);
void vesa_module_info(disp_adapter_t *adapter, disp_module_info_t *info);
int vesa_attach_external(disp_adapter_t *adapter, disp_aperture_t aper[]);
int vesa_detach_external(disp_adapter_t *adapter);
int vesa_recover(disp_adapter_t *adapter);
int vesa_query_apertures(disp_adapter_t *adp, disp_aperture_t *aptertures);
int vesa_query_surface(disp_adapter_t *adapter,
disp_surface_t *surf, disp_surface_info_t *info);
int vesa_get_alloc_info(disp_adapter_t *adp,
int width, int height, unsigned format,
unsigned flags, unsigned user_flags, disp_alloc_info_t *info);
int vesa_get_alloc_layer_info(disp_adapter_t *adp, int dispno[], int layer_idx[],
int nlayers, unsigned format, int surface_index, int width, int height,
unsigned sflags, unsigned hint_flags, disp_alloc_info_t *info);

9
devg/vesabios/vesabios.use Обычный файл
Просмотреть файл

@ -0,0 +1,9 @@
Generic Vesa 2.00+ BIOS modeswitcher
Supported controllers: VESA compatible
Multiple displays support: no
Layers support: 1
Acceleration support: -
Color depths support: 16, 24, 32
Supported interfaces: -

2
devg/vpoutfb/Makefile Обычный файл
Просмотреть файл

@ -0,0 +1,2 @@
LIST=OS
include recurse.mk

30
devg/vpoutfb/configs/vpoutfb.conf Обычный файл
Просмотреть файл

@ -0,0 +1,30 @@
# devg-vpoutfb.so parameters
#
# dispmode Display configuration.
# Acceptable values: "hdmi-0" (pipe a, default mode)
# base Display controller registers base phys-address
# size Display controller registers area size (default - 0x1000)
# irq Display controller interrupt id (default - polling mode)
# memory Video memory size. Default/minimum GPU memory size - 128 Mb. This option causes
# increasing initialization time.
# Acceptable values: up to "2048" Mb
# hdmi HDMI transmitter configuration. Only 1 HDMI port supported.
# Acceptable values:
# "IT66121:<i2c-bus>:<i2c-address>:<i2c-speed>:<gpio-base>:<gpio-reg>:<gpio-pin>"
# "TDA998x:<i2c-bus>:<i2c-address>:<i2c-speed>:<video-ports>"
# "TFP410EP:<i2c-bus>:<i2c-address>:<i2c-speed>:<ddc-bus>:<ddc-slave>"
# enable Enable features:
# "lcd_sync_fix" Enable LCD sync generation fix
# verbose Verbosity level: "silent" (default), "info", "warn", "debug"
#
# The driver will use the first un-commented entry.
# Elvees Salute EL24D1 configuration sample
#base=0x38004000,size=0x1000,irq=69,memory=128,hdmi=IT66121:1:0x4c:100:0x38034000:0xc:14,verbose=debug
# Elvees Salute EL24OM1 configuration sample
base=0x38004000,size=0x1000,irq=69,memory=128,hdmi=TDA998x:0:0x70:100:0x234501,enable=lcd_sync_fix,verbose=debug
# Elvees Salute ????? configuration sample
base=0x38004000,size=0x1000,irq=69,memory=128,hdmi=TFP410EP:2:0x38:100:0:0x50,enable=lcd_sync_fix,verbose=debug

28
devg/vpoutfb/context.c Обычный файл
Просмотреть файл

@ -0,0 +1,28 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* FUNCTIONS */
/*************************************************/
/* Populate the function table of core drawing routines. tabsize is the size of the function table in bytes.
* pixel_format specifies the surface type that the draw routines must be able to render to */
int devg_get_contextfuncs( disp_adapter_t *adapter, disp_draw_contextfuncs_t *funcs, int tabsize )
{
/* Get the default software functions first */
if ( ffb_get_contextfuncs( adapter, funcs, tabsize ) == -1 )
return (-1);
return (0);
}

26
devg/vpoutfb/core.c Обычный файл
Просмотреть файл

@ -0,0 +1,26 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* FUNCTIONS */
/*************************************************/
int devg_get_corefuncs( disp_adapter_t *adapter, unsigned pixel_format, disp_draw_corefuncs_t *funcs, int tabsize )
{
/* Get the default software drawing routines first. */
if ( ffb_get_corefuncs( adapter, pixel_format, funcs, tabsize ) == -1 )
return (-1);
return (0);
}

123
devg/vpoutfb/cursor.c Обычный файл
Просмотреть файл

@ -0,0 +1,123 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* FUNCTIONS */
/*************************************************/
#ifdef ENABLE_HW_CURSOR
void vpout_enable_hw_cursor( disp_adapter_t *adapter, int dispno )
{
//vpout_context_t *vpout = adapter->ms_ctx;
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
uint32_t mode;
mode = *MMIO32( LCDMODE );
mode |= LCDMODE_HWCEN | LCDMODE_HWC_MODE_64x64;
*MMIO32( LCDMODE ) = mode;
}
void vpout_disable_hw_cursor( disp_adapter_t *adapter, int dispno )
{
//vpout_context_t *vpout = adapter->ms_ctx;
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
uint32_t mode;
mode = *MMIO32( LCDMODE );
mode &= ~LCDMODE_HWCEN;
*MMIO32( LCDMODE ) = mode;
}
void vpout_set_hw_cursor_pos( disp_adapter_t *adapter, int dispno, int x, int y )
{
//vpout_context_t *vpout = adapter->ms_ctx;
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
if ( x < 0 )
x = -x | 0x8000;
if ( y < 0 )
y = -y | 0x8000;
*MMIO32( LCDXY ) = (x & 0xFFFF) | (y << 16);
}
int vpout_set_hw_cursor( disp_adapter_t *adapter, int dispno, uint8_t *bmp0, uint8_t *bmp1, unsigned color0, unsigned color1,
int hotspot_x, int hotspot_y, int size_x, int size_y, int bmp_stride )
{
//vpout_context_t *vpout = adapter->ms_ctx;
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
uint8_t *cursor_ptr = NULL;
int x = 0,
y = 0,
byte = 0,
bit = 0,
code = 0;
uint32_t cursor_sz = 0;
//unsigned cursor_stride;
uint32_t mode;
/* Fallback into software if we can't handle oversized cursor */
if ( size_x > 64 || size_y > 64 )
return (-1);
cursor_sz = 64;
/* Need to enable cursor before updating it's contents */
mode = *MMIO32( LCDMODE );
mode |= LCDMODE_HWCEN | LCDMODE_HWC_MODE_64x64;
*MMIO32( LCDMODE ) = mode;
cursor_ptr = (uint8_t *)(MMIO32(HWC_MEM));
for ( y = 0; y < cursor_sz; y++ )
{
byte = y * bmp_stride;
bit = 0x80;
for ( x = 0; x < cursor_sz; x++ )
{
unsigned off;
code = 0;
if ( y < size_y && x < size_x )
{
if ( bmp0[byte] & bit )
code = 2;
if ( bmp1[byte] & bit )
code = 3;
}
off = (x & 3) * 2;
cursor_ptr[(y * cursor_sz + x) >> 2] &= ~(3 << off);
cursor_ptr[(y * cursor_sz + x) >> 2] |= (code << off);
bit >>= 1;
if ( bit == 0 )
{
bit = 0x80;
byte++;
}
}
}
*MMIO32( LCDCOLOR0 ) = color0;
*MMIO32( LCDCOLOR1 ) = color1;
*MMIO32( LCDXYP ) = hotspot_x | (hotspot_y << 16);
return (0);
}
#endif /* ENABLE_HW_CURSOR */

12
devg/vpoutfb/driver.mk Обычный файл
Просмотреть файл

@ -0,0 +1,12 @@
LIBS += drmhelperS
ifndef DEVILIB_ROOT
DEVILIB_ROOT=$(PROJECT_ROOT)/lib
endif
EXTRA_LIBVPATH+=$(DEVILIB_ROOT)/drmhelper/$(OS)/$(CPU)/a.shared.le.v7
# Config-files
CONFIG = $(firstword $(wildcard $(PROJECT_ROOT)/$(SECTION)/configs/vpoutfb.conf.$(CPUVARDIR)) $(PROJECT_ROOT)/$(SECTION)/configs/vpoutfb.conf)
POST_INSTALL += $(CP_HOST) $(CONFIG) $(INSTALL_ROOT_$(OS))/$(CPUVARDIR)/etc/system/config/
POST_UNINSTALL += $(RM_HOST) $(INSTALL_ROOT_$(OS))/$(CPUVARDIR)/etc/system/config/vpoutfb.conf

167
devg/vpoutfb/i2c.c Обычный файл
Просмотреть файл

@ -0,0 +1,167 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
#include <hw/i2c.h>
/*************************************************/
/* FUNCTIONS */
/*************************************************/
static int bus[VPOUT_HDMI_PORTS + 1];
static int bus_en[VPOUT_HDMI_PORTS + 1];
int i2c_read( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t bus_, uint32_t speed_, uint8_t addr, unsigned short offset,
uint8_t *buf, unsigned count )
{
disp_adapter_t *adapter = vpout->adapter;
int status = 0;
uint8_t buf_[sizeof(i2c_send_t) + 256];
i2c_send_t *hdr = (i2c_send_t *)buf_;
int rbytes;
uint32_t speed = speed_ * 1000;
if ( bus_en[port] != 1 )
{
disp_printf( adapter, "[vpout: i2c] Error: I2C bus read failed [bus not found: bus=#%u, port=%d]", bus_, port );
return (-1);
}
if ( speed_ > 0 )
{
if ( devctl( bus[port], DCMD_I2C_SET_BUS_SPEED, &speed, sizeof( speed ), NULL ) )
{
disp_printf( adapter, "[vpout: i2c] Error: I2C bus read failed [can't set bus speed: bus=#%u, port=%d]", bus_, port );
return (-1);
}
}
#if 0
memset( buf_, 0, sizeof(i2c_send_t) + 1 );
hdr->slave.addr = addr;
hdr->slave.fmt = I2C_ADDRFMT_7BIT;
hdr->len = 1;
hdr->stop = 0;
buf_[sizeof( i2c_send_t )] = offset;
status = devctl( bus[port], DCMD_I2C_SEND, buf_, sizeof( i2c_send_t ) + 1, NULL );
if ( status )
{
disp_printf( adapter, "[vpout: i2c] Error: I2C bus read failed [transaction failed on write address: bus=#%u, addr=0x%x, port=%d]", bus_, addr, port );
return (-1);
}
#endif
memset( buf_, 0, sizeof(i2c_send_t) + count );
hdr->slave.addr = addr;
hdr->slave.fmt = I2C_ADDRFMT_7BIT;
hdr->len = count;
hdr->stop = 0;
buf_[sizeof( i2c_send_t )] = offset;
status = devctl( bus[port], DCMD_I2C_RECV, buf_, sizeof( i2c_send_t ) + count, &rbytes );
if ( status )
{
disp_printf( adapter, "[vpout: i2c] Error: I2C bus read failed [transaction failed on read: bus=#%u, addr=0x%x, port=%d]", bus_, addr, port );
return (-1);
}
memcpy( buf, &buf_[sizeof( i2c_send_t )], count );
return (0);
}
int i2c_write( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t bus_, uint32_t speed_, uint8_t addr, unsigned short offset,
uint8_t *buf, unsigned count )
{
disp_adapter_t *adapter = vpout->adapter;
int status = 0;
uint8_t buf_[sizeof(i2c_send_t) + 256];
i2c_send_t *hdr = (i2c_send_t *)buf_;
uint32_t speed = speed_ * 1000;
if ( bus_en[port] != 1 )
{
disp_printf( adapter, "[vpout: i2c] Error: I2C bus writing failed [bus not found: bus=#%u, port=%d]", bus_, port );
return (-1);
}
if ( devctl( bus[port], DCMD_I2C_SET_BUS_SPEED, &speed, sizeof( speed ), NULL ) )
{
disp_printf( adapter, "[vpout: i2c] Error: I2C bus read failed [can't set bus speed: bus=#%u, port=%d]", bus_, port );
return (-1);
}
#if 0
memset( buf_, 0, sizeof(i2c_send_t) + 1 );
hdr->slave.addr = addr;
hdr->slave.fmt = I2C_ADDRFMT_7BIT;
hdr->len = 1;
hdr->stop = 0;
buf_[sizeof( i2c_send_t )] = offset;
status = devctl( bus[port], DCMD_I2C_SEND, buf_, sizeof( i2c_send_t ) + 1, NULL );
if ( status )
{
disp_printf( adapter, "[vpout: i2c] Error: I2C bus read failed [transaction failed on write address: bus=#%u, addr=0x%x, port=%d]", bus_, addr, port );
return (-1);
}
#endif
memset( buf_, 0, sizeof(i2c_send_t) + count );
memcpy( &buf_[sizeof( i2c_send_t ) + 1], buf, count );
hdr->slave.addr = addr;
hdr->slave.fmt = I2C_ADDRFMT_7BIT;
hdr->len = count + 1;
hdr->stop = 0;
buf_[sizeof( i2c_send_t )] = offset;
status = devctl( bus[port], DCMD_I2C_SEND, buf_, sizeof( i2c_send_t ) + count + 1, NULL );
if ( status )
{
disp_printf( adapter, "[vpout: i2c] Error: I2C bus write failed [transaction failed on write: bus=#%u, addr=0x%x, port=%d]", bus_, addr, port );
return (-1);
}
return (0);
}
int i2c_init( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t bus_, uint8_t port )
{
disp_adapter_t *adapter = vpout->adapter;
char path[16];
sprintf( path, "/dev/i2c%u", bus_ );
bus[port] = open( path, O_RDWR );
if ( bus[port] < 0 )
{
disp_printf( adapter, "[vpout: i2c] Error: can't open bus [bus=#%u, port=%d]", bus_, port );
return (-1);
}
bus_en[port] = 1;
return (0);
}
void i2c_fini( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port )
{
if ( bus_en[port] )
{
close( bus_en[port] );
bus_en[port] = 0;
}
}

254
devg/vpoutfb/init.c Обычный файл
Просмотреть файл

@ -0,0 +1,254 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* FUNCTIONS */
/*************************************************/
const struct sigevent * vpout_isr_handler( void *ptr, int id )
{
vpout_draw_context_t *vpout_draw = (vpout_draw_context_t *)ptr;
vpout_context_t *vpout = vpout_draw->vpout;
return vpout_hw_isr( vpout, vpout_draw );
}
int vpout_isr_setup( disp_adapter_t *adapter, vpout_context_t *vpout, vpout_draw_context_t *vpout_draw )
{
int err = EOK;
#ifdef ENABLE_IRQ
vpout->irq_polling = 0;
#else
vpout->irq_polling = 1;
return (0);
#endif
if ( vpout->irq == 0 )
/* Switch to polling */
return (-1);
if ( (vpout->irq_chid = ChannelCreate( _NTO_CHF_DISCONNECT | _NTO_CHF_UNBLOCK )) == -1 )
{
disp_printf( adapter, "[vpoutfb] Error: can't setup interrupt handler [channel creation failed]" );
return (-1);
}
if ( (vpout->irq_coid = ConnectAttach( 0, 0, vpout->irq_chid, _NTO_SIDE_CHANNEL, 0 )) == -1 )
{
err = errno;
goto vpout_isr_fail;
}
SIGEV_PULSE_INIT( &vpout->irq_event, vpout->irq_coid, vpout->adapter->pulseprio + 20, VBLANK_PULSE, 0 );
vpout->irq_iid = InterruptAttach( _NTO_INTR_CLASS_EXTERNAL | vpout->irq, vpout_isr_handler, vpout_draw, sizeof( *vpout_draw ),
_NTO_INTR_FLAGS_END | _NTO_INTR_FLAGS_TRK_MSK | _NTO_INTR_FLAGS_PROCESS );
if ( vpout->irq_iid == -1 )
{
err = errno;
goto vpout_isr_fail2;
}
/* Enable IRQs: see register LCDINTMASK in the vpout_hw_configure_display() */
return (0);
vpout_isr_fail2:
disp_printf( adapter, "[vpoutfb] Error: can't setup interrupt handler [interrupt attaching failed]" );
ConnectDetach( vpout->irq_coid );
vpout->irq_coid = -1;
vpout_isr_fail:
disp_printf( adapter, "[vpoutfb] Error: can't setup interrupt handler [channel connection failed]" );
ChannelDestroy( vpout->irq_chid );
vpout->irq_chid = -1;
errno = err;
return (-1);
}
void vpout_isr_cleanup( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw )
{
if ( (vpout->irq_coid != -1) && (vpout->irq_coid != 0) )
ConnectDetach( vpout->irq_coid );
if ( (vpout->irq_chid != -1) && (vpout->irq_chid != 0) )
ChannelDestroy( vpout->irq_chid );
if ( (vpout->irq_iid != -1) && (vpout->irq_iid != 0) )
InterruptDetach( vpout->irq_iid );
}
int devg_shmem_size = sizeof( vpout_context_t );
int vpout_init( disp_adapter_t *adapter, char *optstring )
{
vpout_context_t *vpout = NULL;
vpout_draw_context_t *vpout_draw = NULL;
int i = 0;
uint8_t *gpio_registers = NULL;
if ( disp_register_adapter( adapter ) == -1 )
{
disp_printf( adapter, "[vpoutfb] Fatal: can't register driver" );
return (-1);
}
/* Allocate GPU context */
vpout = adapter->shmem;
if ( vpout )
memset( vpout, 0, sizeof( vpout_context_t ) );
else {
vpout = calloc( 1, sizeof( vpout_context_t ) );
if ( vpout == NULL )
{
disp_printf( adapter, "[vpoutfb] Fatal: can't allocate GPU context" );
goto fail;
}
vpout->context_allocated = 1;
}
/* Parse configuration options */
if ( parse_options( adapter, vpout, optstring ) )
goto fail;
/* Allocate draw-context */
vpout_draw = calloc( 1, sizeof( vpout_draw_context_t ) );
if ( vpout_draw == NULL )
{
disp_printf( adapter, "[vpoutfb] Fatal: can't allocate GPU draw-context" );
goto fail;
}
vpout->adapter = adapter;
vpout_draw->vpout = vpout;
adapter->ms_ctx = vpout;
adapter->vsync_counter = &vpout->vsync_counter[0];
adapter->gd_ctx = vpout_draw;
/* Mmap registers */
vpout->registers = (uint8_t *)mmap64( NULL, vpout->registers_size, PROT_READ | PROT_WRITE | PROT_NOCACHE, MAP_PHYS, NOFD, vpout->registers_base );
if ( vpout->registers == MAP_FAILED || vpout->registers == NULL )
{
disp_printf( adapter, "[vpoutfb] Fatal: can't mmap registers" );
goto fail1;
}
vpout_draw->registers = vpout->registers;
/* Get aperture metrics */
vpout->cmctr_registers = (uint8_t *)mmap64( NULL, CMCTR_REGISTERS_SIZE, PROT_READ | PROT_WRITE | PROT_NOCACHE, MAP_PHYS, NOFD, CMCTR_REGISTERS_BASE );
if ( vpout->cmctr_registers == MAP_FAILED || vpout->cmctr_registers == NULL )
{
disp_printf( adapter, "[vpoutfb] Fatal: can't mmap CMCTR registers" );
goto fail2;
}
/* Check PLLs */
if ( (*CMCTR_MMIO32( SEL_CPLL ) & SEL_CPLL_LOCK) || ((*CMCTR_MMIO32( SEL_CPLL ) & SEL_CPLL_SEL) == 0) )
disp_printf( adapter, "[vpoutfb] CPLL frequency: %d MHz", ((*CMCTR_MMIO32( SEL_CPLL ) & SEL_CPLL_SEL) + 1) * VPOUT_XTI_FREQUENCY );
else {
disp_printf( adapter, "[vpoutfb] Fatal: CPLL disabled" );
goto fail4;
}
if ( (*CMCTR_MMIO32( SEL_SPLL ) & SEL_SPLL_LOCK) || ((*CMCTR_MMIO32( SEL_SPLL ) & SEL_SPLL_SEL) == 0) )
disp_printf( adapter, "[vpoutfb] SPLL frequency: %d MHz (288 MHz expected)", ((*CMCTR_MMIO32( SEL_SPLL ) & SEL_SPLL_SEL) + 1) * VPOUT_XTI_FREQUENCY );
else {
disp_printf( adapter, "[vpoutfb] Fatal: SPLL disabled" );
goto fail4;
}
for ( i = 0; i < vpout->hdmi_count; i++ )
{
if ( (strcmp( vpout->hdmi[i].transmitter, VPOUT_OPT_HDMI_IT66121 ) == 0) && gpio_registers == NULL )
{
gpio_registers = (uint8_t *)mmap64( NULL, GPIO_REGISTERS_SIZE, PROT_READ | PROT_WRITE | PROT_NOCACHE, MAP_PHYS, NOFD,
vpout->hdmi[i].device.it66121.base );
if ( gpio_registers == MAP_FAILED || gpio_registers == NULL )
{
disp_printf( adapter, "[vpoutfb] Fatal: can't mmap GPIO registers" );
goto fail4;
}
vpout->hdmi[i].device.it66121.registers = gpio_registers;
}
}
adapter->adapter_ram = 0;
adapter->caps = DISP_CAP_NO_IO_PRIVITY;
/* Setup ISR */
if ( vpout_isr_setup( adapter, vpout, vpout_draw ) == -1 )
{
disp_printf( adapter, "[vpoutfb] Error: can't attach interrupt handler [switching to vsync polling]" );
vpout->irq_polling = 1;
}
return VPOUT_GPU_PIPES;
fail4:
munmap( vpout->cmctr_registers, CMCTR_REGISTERS_SIZE );
fail2:
munmap( vpout_draw->registers, vpout->registers_size );
fail1:
free( vpout_draw );
fail:
if ( vpout->context_allocated )
free( vpout );
disp_unregister_adapter( adapter );
return (-1);
}
void vpout_fini( disp_adapter_t *adapter )
{
vpout_context_t *vpout = adapter->ms_ctx;
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
int i = 0;
/* Done if vpout_init failed */
if ( adapter->gd_ctx == NULL )
return;
/* Disable hardware */
vpout_hw_disable( vpout, vpout_draw );
/* Cleanup ISR */
vpout_isr_cleanup( vpout, vpout_draw );
/* Free mmapings */
for ( i = 0; i < vpout->hdmi_count; i++ )
if ( vpout->hdmi[i].device.it66121.registers )
{
munmap( vpout->hdmi[i].device.it66121.registers, GPIO_REGISTERS_SIZE );
break;
}
munmap( vpout->cmctr_registers, CMCTR_REGISTERS_SIZE );
munmap( vpout->registers, vpout->registers_size );
/* Free draw-context */
free( vpout_draw );
adapter->gd_ctx = NULL;
/* Free GPU context */
if ( vpout->context_allocated )
free( vpout );
adapter->ms_ctx = NULL;
disp_unregister_adapter( adapter );
}

238
devg/vpoutfb/it66121.c Обычный файл
Просмотреть файл

@ -0,0 +1,238 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* ITE IT66121 I2C HDMI transmitter interface */
/*************************************************/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* I2C FUNCTIONS */
/*************************************************/
static int hdmi_read( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint16_t offset )
{
int ret = 0;
uint8_t data = 0;
ret = i2c_read( vpout, vpout_draw, port, vpout->hdmi[port].device.it66121.bus, vpout->hdmi[port].device.it66121.speed, vpout->hdmi[port].device.it66121.address,
offset, &data, 1 );
if ( ret < 0 )
return ret;
return data;
}
static int hdmi_write_masked( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t offset, uint8_t value, uint8_t mask )
{
int ret = 0;
ret = hdmi_read( vpout, vpout_draw, port, offset );
if ( ret < 0 )
return ret;
value = (value & mask) | ((uint8_t)ret & ~mask);
ret = i2c_write( vpout, vpout_draw, port, vpout->hdmi[port].device.it66121.bus, vpout->hdmi[port].device.it66121.speed, vpout->hdmi[port].device.it66121.address,
offset, &value, 1 );
return (ret < 0) ? ret : 0;
}
/*************************************************/
/* INTERFACE FUNCTIONS */
/*************************************************/
void it66121_probe( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index )
{
disp_adapter_t *adapter = vpout->adapter;
uint32_t gpio_data = 0;
uint32_t gpio_direction = 0;
uint32_t gpio_control = 0;
if ( i2c_init( vpout, vpout_draw, vpout->hdmi[port_index].device.it66121.bus, port_index ) )
{
disp_printf( adapter, "[vpoutfb: it66121] Fatal: I2C HDMI controller initialization failed [I2C issue: port=%d]", port_index );
return;
}
/* Initial HDMI chip GPIO port value */
switch ( vpout->hdmi[port_index].device.it66121.reg )
{
case 0xa:
gpio_data = GPIO_SWPORTA_DR;
gpio_direction = GPIO_SWPORTA_DDR;
gpio_control = GPIO_SWPORTA_CTL;
break;
case 0xb:
gpio_data = GPIO_SWPORTB_DR;
gpio_direction = GPIO_SWPORTB_DDR;
gpio_control = GPIO_SWPORTB_CTL;
break;
case 0xc:
gpio_data = GPIO_SWPORTC_DR;
gpio_direction = GPIO_SWPORTC_DDR;
gpio_control = GPIO_SWPORTC_CTL;
break;
case 0xd:
gpio_data = GPIO_SWPORTD_DR;
gpio_direction = GPIO_SWPORTD_DDR;
gpio_control = GPIO_SWPORTD_CTL;
break;
}
/* Switch to the software control */
*GPIO_MMIO32( vpout->hdmi[port_index].device.it66121.registers, gpio_control ) &= ~(1 << vpout->hdmi[port_index].device.it66121.pin);
/* Switch to the output */
*GPIO_MMIO32( vpout->hdmi[port_index].device.it66121.registers, gpio_direction ) |= 1 << vpout->hdmi[port_index].device.it66121.pin;
*GPIO_MMIO32( vpout->hdmi[port_index].device.it66121.registers, gpio_data ) |= 1 << vpout->hdmi[port_index].device.it66121.pin;
}
void it66121_reset( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index )
{
uint32_t gpio_data = 0;
switch ( vpout->hdmi[port_index].device.it66121.reg )
{
case 0xa:
gpio_data = GPIO_SWPORTA_DR;
break;
case 0xb:
gpio_data = GPIO_SWPORTB_DR;
break;
case 0xc:
gpio_data = GPIO_SWPORTC_DR;
break;
case 0xd:
gpio_data = GPIO_SWPORTD_DR;
break;
}
*GPIO_MMIO32( vpout->hdmi[port_index].device.it66121.registers, gpio_data ) &= ~(1 << vpout->hdmi[port_index].device.it66121.pin);
/* Takes a pause or reset won't take effect */
disp_usecspin( 1000 );
*GPIO_MMIO32( vpout->hdmi[port_index].device.it66121.registers, gpio_data ) |= 1 << vpout->hdmi[port_index].device.it66121.pin;
}
void it66121_remove( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index )
{
i2c_fini( vpout, vpout_draw, port_index );
}
int it66121_init( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index /* ignored */, uint32_t pixel_clock )
{
disp_adapter_t *adapter = vpout->adapter;
uint8_t ident[] = { 0x54, 0x49, 0x12, 0x16 };
int ret = 0, i;
it66121_reset( vpout, vpout_draw, port_index );
disp_usecspin( 5000 );
/* Verify it's the correct device */
for ( i = 0; i < 4; i++ )
{
if ( ident[i] != hdmi_read( vpout, vpout_draw, port_index, i ) )
{
disp_printf( adapter, "[vpoutfb: it66121] Fatal: ITE IT66121 I2C HDMI controller not found [port=%d]", port_index );
return (-ENODEV);
}
}
/* reset whole circuit */
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_RESET, 0x20, 0x20 );
disp_usecspin( 5000 );
/* each circuit is off so we can switch them on one by one */
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_RESET, RESET_RCLK_MASK | RESET_AUDIO_MASK | RESET_VIDEO_MASK | RESET_AFIFO_MASK |
RESET_HDCP_MASK, 0xFF );
disp_usecspin( 5000 );
/* hdmi tx flipflops reset */
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_TX_RESET, 0x10, 0xFF );
/* DVI mode, packet interface off */
for ( i = 0xc0; i <= 0xd0; i++ )
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, i, 0, 0xFF );
/* Ignore all the interrupts */
for ( i = REG_IRQ_FIRST; i <= REG_IRQ_LAST; i++ )
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, i, 0xFF, 0xFF );
/* Enable video circuit */
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_RESET, 0x00, RESET_VIDEO_MASK );
/* Switch avmute on */
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_AVMUTE, 0x01, 0xFF );
/* Disable audio */
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, 0xE0, 0x00, 0x0F );
/* Set up clock-related settings */
if ( (float)pixel_clock >= (float)12500.0 )
{
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_CLK1, 0x18, 0xFF );
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_CLK2, 0x10, 0xFF );
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_CLK3, 0x0C, 0xFF );
} else {
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_CLK1, 0x88, 0xFF );
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_CLK2, 0x10, 0xFF );
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_CLK3, 0x84, 0xFF );
}
/* Clear TX FIFO */
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_TXFIFO_SET, 0x02, 0x02 );
disp_usecspin( 2000 );
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_TXFIFO_SET, 0x00, 0x02 );
/* It takes a while to measure clocks, so we give it time */
disp_usecspin( 150000 );
for ( i = 0; i < 10; i++ )
{
if ( !(hdmi_read( vpout, vpout_draw, port_index, 0x0e ) & 0x10) )
{
disp_printf( adapter, "[vpoutfb: it66121] Warning: transmitter video input not stable [port=%d]", port_index );
disp_usecspin( 20000 );
} else
break;
}
if ( i == 10 )
{
it66121_reset( vpout, vpout_draw, port_index );
return (-EBUSY);
}
/* Switch avmute off */
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, REG_AVMUTE, 0x00, 0xFF );
/* Turn on display */
ret |= hdmi_write_masked( vpout, vpout_draw, port_index, 0x61, 0x03, 0xFF );
if ( ret )
it66121_reset( vpout, vpout_draw, port_index );
return ret;
}

137
devg/vpoutfb/mem.c Обычный файл
Просмотреть файл

@ -0,0 +1,137 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* FUNCTIONS */
/*************************************************/
static int vpout_mem_init( disp_adapter_t *adapter, char *optstring )
{
return 0;
}
static void vpout_mem_fini( disp_adapter_t *adapter )
{
}
static int vpout_mem_reset( disp_adapter_t *adapter, disp_surface_t *surf_ )
{
vpout_mem_fini( adapter );
vpout_mem_init( adapter, NULL );
return 0;
}
/* return the aperture within which the memory surface resides, and the physical offset of the memory within that aperture */
static int vpout_query_apertures( disp_adapter_t *adapter, disp_aperture_t *ap )
{
vpout_context_t *vpout = adapter->ms_ctx;
ap->base = vpout->registers_base;
ap->size = vpout->registers_size;
ap->flags = DISP_APER_NOCACHE;
ap ++;
return 1;
}
/* If a client of the driver wants to allocate memory itself, it must allocate it in accordance with the parameters returned by
* this function. Since this memory will not be mapped into the video aperture, we must check the flags accordingly. */
static int vpout_get_alloc_info( disp_adapter_t *adapter, int width, int height, unsigned format, unsigned flags, unsigned user_flags, disp_alloc_info_t *info )
{
flags &= DISP_SURFACE_CAPS_MASK;
/*if ( flags & ~( DISP_SURFACE_CPU_LINEAR_READABLE | DISP_SURFACE_CPU_LINEAR_WRITEABLE | DISP_SURFACE_PAGE_ALIGNED | DISP_SURFACE_PHYS_CONTIG) )
return -1;*/
info->start_align = 64/8; /*4096;*/
info->end_align = 1;
info->min_stride = width * DISP_BYTES_PER_PIXEL(format); /* actual stride */
info->max_stride = ~0;
info->stride_gran = 64/8; /* this is actually ignored */
info->map_flags = 0;
info->prot_flags = DISP_PROT_READ | DISP_PROT_WRITE;
info->surface_flags = flags | DISP_SURFACE_PAGE_ALIGNED;
if ( flags & DISP_SURFACE_DISPLAYABLE )
{
info->min_stride = ALIGN_64BIT( info->min_stride );
info->map_flags |= DISP_MAP_PHYS;
info->prot_flags |= DISP_PROT_NOCACHE;
info->surface_flags |= DISP_SURFACE_NON_CACHEABLE | DISP_SURFACE_DMA_SAFE |
DISP_SURFACE_PHYS_CONTIG | DISP_SURFACE_PAGE_ALIGNED |
DISP_SURFACE_CPU_LINEAR_READABLE | DISP_SURFACE_CPU_LINEAR_WRITEABLE;
}
return 0;
}
static int vpout_get_alloc_layer_info( disp_adapter_t *adapter, int dispno[], int layer[], int nlayers, unsigned format, int surface_index,
int width, int height, unsigned sflags, unsigned hint_flags, disp_alloc_info_t *info )
{
unsigned alloc_format;
switch (format) {
case DISP_LAYER_FORMAT_PAL8:
alloc_format = DISP_SURFACE_FORMAT_PAL8;
break;
case DISP_LAYER_FORMAT_ARGB1555:
alloc_format = DISP_SURFACE_FORMAT_ARGB1555;
break;
case DISP_LAYER_FORMAT_RGB565:
alloc_format = DISP_SURFACE_FORMAT_RGB565;
break;
case DISP_LAYER_FORMAT_RGB888:
alloc_format = DISP_SURFACE_FORMAT_RGB888;
break;
case DISP_LAYER_FORMAT_ARGB8888:
alloc_format = DISP_SURFACE_FORMAT_ARGB8888;
break;
default:
return -1;
}
return vpout_get_alloc_info( adapter, width, height, alloc_format,
sflags | DISP_SURFACE_DISPLAYABLE, hint_flags, info );
}
static int vpout_submit_alloced_info(disp_adapter_t *adp, disp_surface_t *surf, unsigned flags)
{
/*surf->offset = surf->paddr;*/
disp_printf_debug( adp, "[vpoutfb] Debug: surface allocated [w=%d h=%d s=%d o=0x%x ptr=0x%p(phys=0x%llx), flags=0x%x]",
surf->width, surf->height, surf->stride, surf->offset,
surf->vidptr, disp_phys_addr( surf->vidptr ), flags );
return 0;
}
int devg_get_memfuncs( disp_adapter_t *adapter, disp_memfuncs_t *funcs, int tabsize )
{
DISP_ADD_FUNC( disp_memfuncs_t, funcs, init, vpout_mem_init, tabsize );
DISP_ADD_FUNC( disp_memfuncs_t, funcs, fini, vpout_mem_fini, tabsize );
DISP_ADD_FUNC( disp_memfuncs_t, funcs, module_info, vpout_module_info, tabsize );
DISP_ADD_FUNC( disp_memfuncs_t, funcs, reset, vpout_mem_reset, tabsize );
DISP_ADD_FUNC( disp_memfuncs_t, funcs, query_apertures, vpout_query_apertures, tabsize );
DISP_ADD_FUNC( disp_memfuncs_t, funcs, get_alloc_info, vpout_get_alloc_info, tabsize );
DISP_ADD_FUNC( disp_memfuncs_t, funcs, get_alloc_layer_info, vpout_get_alloc_layer_info, tabsize );
DISP_ADD_FUNC( disp_memfuncs_t, funcs, submit_alloced_info, vpout_submit_alloced_info, tabsize );
return 0;
}

101
devg/vpoutfb/misc.c Обычный файл
Просмотреть файл

@ -0,0 +1,101 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* FUNCTIONS */
/*************************************************/
int vpout_misc_wait_idle( disp_adapter_t *adapter )
{
return 0;
}
int vpout_draw_init( disp_adapter_t *adapter, char *opt )
{
return 0;
}
void vpout_draw_fini( disp_adapter_t *adapter )
{
return;
}
void vpout_module_info( disp_adapter_t *adapter, disp_module_info_t *info )
{
info->description = "vpoutfb - Elvees 1892VM14YA ARMv7 SoC";
info->ddk_version_major = DDK_VERSION_MAJOR;
info->ddk_version_minor = DDK_VERSION_MINOR;
info->ddk_rev = DDK_REVISION;
info->driver_rev = 0;
}
/* Set up things so that miscfuncs, corefuncs and contextfuncs can be called by an external process. */
int vpout_attach_external( disp_adapter_t *adapter, disp_aperture_t aper[] )
{
vpout_context_t *vpout = adapter->shmem;
vpout_draw_context_t *vpout_draw = NULL;
/* Allocate external process local draw-context */
vpout_draw = (vpout_draw_context_t *)calloc( 1, sizeof( vpout_draw_context_t ) );
if ( vpout_draw == NULL )
return (-1);
/* Assign GPU context and draw-context */
vpout_draw->vpout = vpout;
adapter->ms_ctx = vpout;
adapter->gd_ctx = vpout_draw;
adapter->caps = DISP_CAP_NO_IO_PRIVITY;
/* Assign remmaped pointers */
vpout_draw->registers = aper[0].vaddr;
vpout_draw->external_process = 1;
return 0;
}
int vpout_detach_external( disp_adapter_t *adapter )
{
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
free( vpout_draw );
adapter->gd_ctx = NULL;
return 0;
}
/* Populate the miscellaneuous graphics driver function table. tabsize is the size of the function table in bytes */
int devg_get_miscfuncs( disp_adapter_t *adapter, disp_draw_miscfuncs_t *funcs, int tabsize )
{
DISP_ADD_FUNC( disp_draw_miscfuncs_t, funcs, init, vpout_draw_init, tabsize );
DISP_ADD_FUNC( disp_draw_miscfuncs_t, funcs, fini, vpout_draw_fini, tabsize );
DISP_ADD_FUNC( disp_draw_miscfuncs_t, funcs, module_info, vpout_module_info, tabsize );
DISP_ADD_FUNC( disp_draw_miscfuncs_t, funcs, get_2d_caps, ffb_get_2d_caps, tabsize );
DISP_ADD_FUNC( disp_draw_miscfuncs_t, funcs, get_corefuncs_sw, ffb_get_corefuncs, tabsize );
DISP_ADD_FUNC( disp_draw_miscfuncs_t, funcs, get_contextfuncs_sw, ffb_get_contextfuncs, tabsize );
#ifdef __QNXNTO__
DISP_ADD_FUNC( disp_draw_miscfuncs_t, funcs, wait_idle, vpout_misc_wait_idle, tabsize );
DISP_ADD_FUNC( disp_draw_miscfuncs_t, funcs, attach_external, vpout_attach_external, tabsize );
DISP_ADD_FUNC( disp_draw_miscfuncs_t, funcs, detach_external, vpout_detach_external, tabsize );
#endif
return 0;
}

450
devg/vpoutfb/mode.c Обычный файл
Просмотреть файл

@ -0,0 +1,450 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* FUNCTIONS */
/*************************************************/
static int vpout_get_modeinfo( disp_adapter_t *adapter, int dispno, disp_mode_t mode, disp_mode_info_t *info )
{
info->caps = DISP_MCAP_SET_DISPLAY_OFFSET | DISP_MCAP_VIRTUAL_PANNING | DISP_MCAP_DPMS_SUPPORTED;
info->crtc_start_gran = DISP_BYTES_PER_PIXEL( info->pixel_format );
info->crtc_pitch_gran = 1;
info->max_virtual_width = 4096;
info->max_virtual_height = 4096;
info->u.generic.min_pixel_clock = 0;
info->u.generic.max_pixel_clock = 1847000; /* In KHz */
info->u.generic.h_granularity = 1;
info->u.generic.v_granularity = 1;
/* All modes we report are generic modes. The mode numbers we
* define are simply the number of bits per pixel for the mode */
switch ( mode )
{
case 8: info->pixel_format = DISP_SURFACE_FORMAT_PAL8; break;
case 15: info->pixel_format = DISP_SURFACE_FORMAT_ARGB1555; break;
case 16: info->pixel_format = DISP_SURFACE_FORMAT_RGB565; break;
case 24: info->pixel_format = DISP_SURFACE_FORMAT_RGB888; break;
case 32: info->pixel_format = DISP_SURFACE_FORMAT_ARGB8888; break;
default:
return -1;
}
info->flags = DISP_MODE_GENERIC;
return 0;
}
static int vpout_get_modelist( disp_adapter_t *adapter, int dispno, disp_mode_t *list, int index, int size )
{
static unsigned modes[] = { 8, 15, 16, 24, 32 };
int i = 0;
int j = 0;
for ( i = index; j < size - 1 && i < sizeof( modes ) / sizeof( modes[0] ); i++ )
list[j++] = modes[i];
list[j] = DISP_MODE_LISTEND;
return 0;
}
static int vpout_set_mode( disp_adapter_t *adapter, int dispno, disp_mode_t mode, disp_crtc_settings_t *settings, disp_surface_t *surf, unsigned flags )
{
vpout_context_t *vpout = adapter->ms_ctx;
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
int pipe = dispno;
disp_mode_info_t mi = { 0 };
vpout_get_modeinfo( adapter, dispno, mode, &mi );
disp_printf_info( adapter, "[vpoutfb] Info: mode switch sequence started [%d:%d@%d %dbpp]", settings->xres, settings->yres, settings->refresh, mode );
disp_printf_info( adapter, "[vpoutfb] Info: mode switcher surface [ptr=0x%x(phys=0x%x)]", (unsigned int)surf->vidptr, (unsigned int)surf->paddr );
/* Checking wrong display.conf settings */
if ( VPOUT_DISPMODE_BAD_PIPE( pipe ) )
{
disp_printf( adapter, "[vpoutfb] Fatal: too much display sections in the display.conf" );
return -1;
}
/* Disable sequence only at the first display mode set */
if ( pipe == 0 )
{
disp_printf_debug( adapter, "[vpoutfb] Debug: Prepare HW disabling" );
vpout_hw_disable( vpout, vpout_draw );
disp_printf_debug( adapter, "[vpoutfb] Debug: HW disabled" );
}
/* Current pipe's settings */
vpout->bpp = mode;
vpout->xres = settings->xres;
vpout->yres = settings->yres;
vpout->refresh = settings->refresh;
/* Only width, height and stride are set. Update fake surface data */
surf->vidptr = NULL;
surf->stride = ALIGN_64BIT(surf->stride);
surf->offset = surf->paddr = 0x40000000; /* TODO: hardcoded RAM start to make DMA happy */
surf->pixel_format = mi.pixel_format;
surf->flags = DISP_SURFACE_DISPLAYABLE | DISP_SURFACE_PAGE_ALIGNED |
DISP_SURFACE_CPU_LINEAR_READABLE | DISP_SURFACE_CPU_LINEAR_WRITEABLE |
DISP_SURFACE_2D_READABLE | DISP_SURFACE_2D_TARGETABLE;
/* Mode set sequences */
disp_printf_debug( adapter, "[vpoutfb] Debug: %s[%d] configuration = 0x%08x", DISPLAY_PORT_NAME( vpout->display[pipe] ), pipe, vpout->display[pipe] );
if ( DISPLAY_PORT( vpout->display[pipe] ) == DISPLAY_PORT_TYPE_HDMI )
{
if ( vpout_hw_configure_display( vpout, vpout_draw, settings, vpout->display[pipe], pipe, surf, mode ) != 0 )
{
disp_printf( adapter, "[vpoutfb] Fatal: %s[%d] mode switch sequence failed", DISPLAY_PORT_NAME( vpout->display[pipe] ), pipe );
return -1;
}
disp_printf_info( adapter, "[vpoutfb] Info: %s[%d] mode set sequence finished successfully", DISPLAY_PORT_NAME( vpout->display[pipe] ), pipe );
}
vpout->display_paddr = surf->paddr;
vpout->display_stride = surf->stride;
vpout->display_format = surf->pixel_format;
/* Wait for the current pipe vsync */
vpout_hw_pipe_wait_for_vblank( vpout, vpout_draw, pipe );
if ( VPOUT_DISPMODE_LAST_PIPE( pipe ) )
disp_printf_debug( adapter, "[vpoutfb] Debug: HW enabled" );
return 0;
}
static int vpout_wait_vsync( disp_adapter_t *adapter, int dispno )
{
vpout_context_t *vpout = adapter->ms_ctx;
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
int pipe = dispno;
if ( VPOUT_DISPMODE_BAD_PIPE( pipe ) )
return -1;
if ( adapter->callback )
adapter->callback( adapter->callback_handle, DISP_CALLBACK_UNLOCK, NULL );
#ifdef ENABLE_IRQ
if ( vpout->error_counter || vpout->error_reset_counter )
{
disp_printf_debug( adapter, "[vpoutfb] Error: caught OUT_FIFO interrupt (display controller FIFO reinitialized %d times)",
vpout->error_counter );
vpout->error_counter = 0;
disp_printf_debug( adapter, "[vpoutfb] Error: display controller reset failed at OUT_FIFO interrupt (counter: %d)",
vpout->error_reset_counter );
vpout->error_reset_counter = 0;
}
#endif
if ( !vpout->irq_polling )
{
iov_t iov;
struct _pulse pulse;
int rcvid;
unsigned prev_vsync;
uint64_t timeout = 500 * 1000 * 1000 /* 500 ms */;
prev_vsync = vpout->vsync_counter[dispno];
SETIOV( &iov, &pulse, sizeof( pulse ) );
while ( 1 )
{
TimerTimeout( CLOCK_REALTIME, _NTO_TIMEOUT_RECEIVE, NULL, &timeout, NULL );
rcvid = MsgReceivev( vpout->irq_chid, &iov, 1, NULL );
if ( rcvid == -1 )
{
vpout->irq_polling = 1;
disp_printf( adapter, "[vpoutfb] Error: switching to vsync polling mode" );
break;
} else
if ( pulse.code == VBLANK_PULSE )
if ( prev_vsync != vpout->vsync_counter[dispno] )
break;
}
}
if ( vpout->irq_polling )
{
vpout_hw_pipe_wait_for_vblank( vpout, vpout_draw, pipe );
vpout->vsync_counter[pipe]++;
}
if ( adapter->callback )
adapter->callback( adapter->callback_handle, DISP_CALLBACK_LOCK, NULL );
return 0;
}
static int vpout_set_display_offset( disp_adapter_t *adapter, int dispno, unsigned offset, int wait_vsync )
{
vpout_context_t *vpout = adapter->ms_ctx;
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
int pipe = dispno;
//disp_printf_debug( adapter, "[vpoutfb] Debug: set display offset 0x%.8x", offset );
vpout_hw_pipe_set_display_offset( vpout, vpout_draw, pipe, offset );
vpout->display_paddr = offset;
if ( wait_vsync && adapter->callback )
adapter->callback( adapter->callback_handle, DISP_CALLBACK_WAIT_VSYNC, &dispno );
return 0;
}
static int vpout_set_palette(disp_adapter_t *adapter, int dispno, int index, int count, disp_color_t *pal)
{
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
vpout_wait_vsync(adapter, dispno);
for (; count--; index++, pal++)
MMIO32(PAL_MEM)[index] = *pal;
return 0;
}
static inline uint32_t get_layer_format( uint32_t surface_format )
{
uint32_t layer_format = 0;
switch ( surface_format )
{
case DISP_SURFACE_FORMAT_BYTES: layer_format = DISP_LAYER_FORMAT_BYTES; break;
case DISP_SURFACE_FORMAT_PAL8: layer_format = DISP_LAYER_FORMAT_PAL8; break;
case DISP_SURFACE_FORMAT_ARGB1555: layer_format = DISP_LAYER_FORMAT_ARGB1555; break;
case DISP_SURFACE_FORMAT_RGB565: layer_format = DISP_LAYER_FORMAT_RGB565; break;
case DISP_SURFACE_FORMAT_RGB888: layer_format = DISP_LAYER_FORMAT_RGB888; break;
case DISP_SURFACE_FORMAT_ARGB8888: layer_format = DISP_LAYER_FORMAT_ARGB8888; break;
case DISP_SURFACE_FORMAT_PACKEDYUV_UYVY: layer_format = DISP_LAYER_FORMAT_UYVY; break;
case DISP_SURFACE_FORMAT_PACKEDYUV_YUY2: layer_format = DISP_LAYER_FORMAT_YUY2; break;
case DISP_SURFACE_FORMAT_PACKEDYUV_YVYU: layer_format = DISP_LAYER_FORMAT_YVYU; break;
case DISP_SURFACE_FORMAT_PACKEDYUV_V422: layer_format = DISP_LAYER_FORMAT_V422; break;
case DISP_SURFACE_FORMAT_PACKEDYUV_UYVY_INTERLACED: layer_format = DISP_LAYER_FORMAT_UYVY_INTERLACED; break;
case DISP_SURFACE_FORMAT_PACKEDYUV_YUY2_INTERLACED: layer_format = DISP_LAYER_FORMAT_YUY2_INTERLACED; break;
case DISP_SURFACE_FORMAT_PACKEDYUV_YVYU_INTERLACED: layer_format = DISP_LAYER_FORMAT_YVYU_INTERLACED; break;
case DISP_SURFACE_FORMAT_PACKEDYUV_V422_INTERLACED: layer_format = DISP_LAYER_FORMAT_V422_INTERLACED; break;
}
return layer_format;
}
static int vpout_devctl( disp_adapter_t *adapter, int dispno, disp_mode_devctl_t cmd, void *data_in, int nbytes, void *data_out, int *out_buffer_size )
{
vpout_context_t *vpout = adapter->ms_ctx;
vpout_draw_context_t *vpout_draw = adapter->gd_ctx;
switch ( cmd )
{
#if defined( ENABLE_DDC )
#define DEVCTL_DDC_EXIT_STATUS( error ) { \
if ( *out_buffer_size >= sizeof( uint32_t ) ) \
*((uint32_t *)data_out) = error; \
*out_buffer_size = sizeof( uint32_t ); \
return 0; \
}
case DEVCTL_DDC:
{
int size = *out_buffer_size;
int port = 0;
devctl_ddc_request_t *request = (devctl_ddc_request_t *)data_in;
disp_printf_debug( adapter, "[vpoutfb] Debug: DEVCTL_DDC received (isize=%d, osize=%d)", nbytes, size );
if ( nbytes != sizeof( devctl_ddc_request_t ) )
{
disp_printf_debug( adapter, "[vpoutfb] Debug: DEVCTL_DDC failed (invalid request isize)" );
DEVCTL_DDC_EXIT_STATUS( EINVAL );
}
if ( request->mode == DEVCTL_DDC_MODE_DISPLAY )
port = dispno;
else {
switch ( request->bus )
{
case 0: port = dispno; break;
default:
disp_printf_debug( adapter, "[vpoutfb] Debug: DEVCTL_DDC failed (invalid bus)" );
DEVCTL_DDC_EXIT_STATUS( ENODEV );
}
}
memset( data_out, 0, size );
size = vpout_hw_read_edid( vpout, vpout_draw, port, data_out, size );
if ( size <= 0 )
DEVCTL_DDC_EXIT_STATUS( EIO );
if ( DEBUG )
{
int j = 0,
i = 0;
uint8_t *edid = data_out;
char str[256];
sprintf( str, "EDID dump: " );
for ( i = 0; i < 16; i++ )
sprintf( str, "%s%X: ", str, i );
disp_printf_debug( adapter, "[vpoutfb] Debug: %s", str );
disp_printf_debug( adapter, "[vpoutfb] ----------------------------------------------------------------------------------------------" );
for ( i = 0; i < size / 16; i++ )
{
sprintf( str, " %02X: | ", i );
for ( j = 0; j < 16; j++ )
sprintf( str, "%s0x%02X ", str, edid[i * 16 + j] );
disp_printf_debug( adapter, "[vpoutfb] %s", str );
}
}
*out_buffer_size = size;
break;
}
#endif
#if defined( ENABLE_DISPLAY_INFO )
case DEVCTL_DISPLAY_INFO:
{
devctl_display_mode_t *buffer = (devctl_display_mode_t *)data_in;
devctl_display_mode_request_t *request = &((devctl_display_mode_t *)data_in)->request;
devctl_display_mode_reply_t *reply = &((devctl_display_mode_t *)data_out)->reply;
uint8_t mode = request->mode;
uint8_t display = request->display;
uint8_t layer = request->layer;
disp_printf_debug( adapter, "[vpoutfb] Debug: DEVCTL_DISPLAY_INFO received (isize=%d, osize=%d)", nbytes, *out_buffer_size );
*out_buffer_size = sizeof( devctl_display_mode_t );
memset( buffer, 0, sizeof( devctl_display_mode_t ) );
switch ( mode )
{
case DEVCTL_DISPLAY_INFO_LAYER:
reply->status = DEVCTL_DISPLAY_INFO_STATUS_OK;
if ( display < 0 || display >= VPOUT_GPU_PIPES )
{
reply->status = DEVCTL_DISPLAY_INFO_STATUS_FAIL;
disp_printf_debug( adapter, "[vpoutfb] Debug: DEVCTL_DISPLAY_INFO failed (invalid display index)" );
break;
}
if ( layer < 0 || layer >= VPOUT_GPU_LAYERS )
{
reply->status = DEVCTL_DISPLAY_INFO_STATUS_FAIL;
disp_printf_debug( adapter, "[vpoutfb] Debug: DEVCTL_DISPLAY_INFO failed (invalid layer index)" );
break;
}
reply->layer.id = layer;
reply->layer.format = -1;
reply->layer.state = vpout->xres > 0 ? DEVCTL_DISPLAY_INFO_STATE_ON : DEVCTL_DISPLAY_INFO_STATE_OFF;
if ( reply->layer.state == DEVCTL_DISPLAY_INFO_STATE_ON )
{
/*reply->layer.sid = (uint32_t)adapter->callback( adapter->callback_handle, DISP_CALLBACK_SURFACE_SID, &vpout->display_surface ); can't be computed without layer functions */
reply->layer.format = get_layer_format( vpout->display_format );
reply->layer.width = vpout->xres;
reply->layer.height = vpout->yres;
reply->layer.stride = vpout->display_stride;
reply->layer.x = 0;
reply->layer.y = 0;
reply->layer.addr = vpout->display_paddr;
reply->layer.viewport.source.x1 = 0;
reply->layer.viewport.source.y1 = 0;
reply->layer.viewport.source.x2 = vpout->xres - 1;
reply->layer.viewport.source.y2 = vpout->yres - 1;
reply->layer.viewport.destination.x1 = 0;
reply->layer.viewport.destination.y1 = 0;
reply->layer.viewport.destination.x2 = vpout->xres - 1;
reply->layer.viewport.destination.y2 = vpout->yres - 1;
reply->layer.chroma_key.color = 0;
reply->layer.chroma_key.mode = DEVCTL_DISPLAY_INFO_CHROMA_NONE;
}
case DEVCTL_DISPLAY_INFO_DISPLAY:
reply->status = DEVCTL_DISPLAY_INFO_STATUS_OK;
if ( display < 0 || display >= VPOUT_GPU_PIPES )
{
reply->status = DEVCTL_DISPLAY_INFO_STATUS_FAIL;
disp_printf_debug( adapter, "[vpoutfb] Debug: DEVCTL_DISPLAY_INFO failed (invalid display index)" );
break;
}
reply->display.id = display;
reply->display.state = display < VPOUT_GPU_PIPES ? DEVCTL_DISPLAY_INFO_STATE_ON : DEVCTL_DISPLAY_INFO_STATE_OFF;
reply->display.layers = VPOUT_GPU_LAYERS;
reply->display.interface = DEVCTL_DISPLAY_INFO_IFACE_NONE;
if ( reply->display.state == DEVCTL_DISPLAY_INFO_STATE_ON )
{
reply->display.width = vpout->xres;
reply->display.height = vpout->yres;
reply->display.refresh = vpout->refresh;
reply->display.interface = DEVCTL_DISPLAY_INFO_IFACE_HDMI;
}
case DEVCTL_DISPLAY_INFO_DISPLAYS:
reply->status = DEVCTL_DISPLAY_INFO_STATUS_OK;
reply->displays = VPOUT_GPU_PIPES;
break;
}
break;
}
#endif
default:
return -1;
}
return EOK;
}
int devg_get_modefuncs( disp_adapter_t *adapter, disp_modefuncs_t *funcs, int tabsize )
{
DISP_ADD_FUNC( disp_modefuncs_t, funcs, init, vpout_init, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, fini, vpout_fini, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, module_info, vpout_module_info, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, get_modeinfo, vpout_get_modeinfo, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, get_modelist, vpout_get_modelist, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, set_mode, vpout_set_mode, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, wait_vsync, vpout_wait_vsync, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, set_display_offset, vpout_set_display_offset, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, set_palette, vpout_set_palette, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, devctl, vpout_devctl, tabsize );
#ifdef ENABLE_HW_CURSOR
DISP_ADD_FUNC( disp_modefuncs_t, funcs, set_hw_cursor, vpout_set_hw_cursor, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, enable_hw_cursor, vpout_enable_hw_cursor, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, disable_hw_cursor, vpout_disable_hw_cursor, tabsize );
DISP_ADD_FUNC( disp_modefuncs_t, funcs, set_hw_cursor_pos, vpout_set_hw_cursor_pos, tabsize );
#endif
return 0;
}

8
devg/vpoutfb/nto/Makefile Обычный файл
Просмотреть файл

@ -0,0 +1,8 @@
LIST=CPU
ifndef QRECURSE
QRECURSE=recurse.mk
ifdef QCONFIG
QRDIR=$(dir $(QCONFIG))
endif
endif
include $(QRDIR)$(QRECURSE)

8
devg/vpoutfb/nto/arm/Makefile Обычный файл
Просмотреть файл

@ -0,0 +1,8 @@
LIST=VARIANT
ifndef QRECURSE
QRECURSE=recurse.mk
ifdef QCONFIG
QRDIR=$(dir $(QCONFIG))
endif
endif
include $(QRDIR)$(QRECURSE)

1
devg/vpoutfb/nto/arm/dll.le.v7/Makefile Обычный файл
Просмотреть файл

@ -0,0 +1 @@
include ../../../../common.mk

369
devg/vpoutfb/options.c Обычный файл
Просмотреть файл

@ -0,0 +1,369 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* VARS / DEFS */
/*************************************************/
static char *vpout_opts[] = {
#define VPOUT_OPT_DISPMODE 0
"dispmode",
#define VPOUT_OPT_BASE 1
"base",
#define VPOUT_OPT_SIZE 2
"size",
#define VPOUT_OPT_IRQ 3
"irq",
#define VPOUT_OPT_HDMI 4
"hdmi",
#define VPOUT_OPT_ENABLE 5
"enable",
#define VPOUT_OPT_VERBOSE 6
"verbose",
NULL
};
int verbose = VPOUT_SLOG_LEVEL_0;
/*************************************************/
/* FUNCTIONS */
/*************************************************/
int parse_options( disp_adapter_t *adapter, vpout_context_t *vpout, char *filename )
{
FILE *fin = NULL;
char buf[256],
*c = NULL,
*opt = NULL,
*value = NULL;
char path[255];
if ( (filename == NULL) || ( strlen( filename ) == 0 ) )
{
int fd = 0;
strcpy( path, "/etc/system/config/vpoutfb.conf" );
fd = open( path, O_RDONLY );
if ( fd != -1 )
{
close( fd );
filename = path;
}
}
if ( (filename == NULL) || ( strlen( filename ) == 0 ) ) {
/* Fatal: configuration file not found */
} else if ( (fin = fopen( filename, "r" )) == NULL )
disp_printf( adapter, "[vpoutfb] Critical: could not open config file \"%s\": %s", filename, strerror( errno ) );
else
disp_printf( adapter, "[vpoutfb] Configuration: \"%s\"", filename );
vpout->display[0] = CONFIG_DISPLAY_PORT_HDMI0;
vpout->enabled = 0;
vpout->registers_size = 0x1000;
if ( fin == NULL )
{
disp_printf( adapter, "[vpoutfb] Fatal: configuration file not found" );
return (-1);
}
while ( fgets( buf, sizeof (buf), fin ) != NULL )
{
c = buf;
while ( *c == ' ' || *c == '\t' )
c++;
if ( *c == '\015' || *c== '\032' || *c == '\0' || *c == '\n' || *c == '#' )
continue;
opt = c;
while ( *c == '\015' || *c== '\032' || (*c != '\0' && *c != '\n' && *c != '#') )
c++;
*c = '\0';
break;
}
while ( *opt != '\0' )
{
c = opt;
switch ( getsubopt( &opt, vpout_opts, &value ) )
{
case VPOUT_OPT_DISPMODE:
if ( strcmp( value, "hdmi-0" ) == 0 ) {
vpout->display[0] = CONFIG_DISPLAY_PORT_HDMI0;
disp_printf( adapter, "[vpoutfb] Configuration: display[0] -> HDMI-0" );
} else
disp_printf( adapter, "[vpoutfb] Warning: unknown display configuration (see vpoutfb.conf)" );
break;
case VPOUT_OPT_BASE:
vpout->registers_base = strtoul( value, NULL, 0 );
disp_printf( adapter, "[vpoutfb] Configuration: display controller registers base - 0x%08x", vpout->registers_base );
break;
case VPOUT_OPT_SIZE:
vpout->registers_size = strtoul( value, NULL, 0 );
disp_printf( adapter, "[vpoutfb] Configuration: display controller registers size - 0x%x", vpout->registers_size );
break;
case VPOUT_OPT_IRQ:
vpout->irq = strtoul( value, NULL, 0 );
disp_printf( adapter, "[vpoutfb] Configuration: display controller interrupt - %d", vpout->irq );
break;
case VPOUT_OPT_HDMI:
if ( strncmp( value, VPOUT_OPT_HDMI_IT66121":", strlen( VPOUT_OPT_HDMI_IT66121 ) + 1 ) == 0 )
{
char *name = value;
int bus;
int address;
int speed;
int base;
int reg;
int pin;
value += strlen( VPOUT_OPT_HDMI_IT66121 );
*value= 0;
value++;
if ( sscanf( value, "%d:0x%x:%d:0x%x:0x%x:%d", &bus, &address, &speed, &base, &reg, &pin ) == 6 )
{
if ( bus < 0 || bus > 3 )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter I2C bus invalid (see vpoutfb.conf)" );
break;
}
if ( address < 0 || address > 0xffff )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter I2C address invalid (see vpoutfb.conf)" );
break;
}
if ( speed <= 0 )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter I2C speed invalid (see vpoutfb.conf)" );
break;
}
if ( base <= 0 )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter GPIO base invalid (see vpoutfb.conf)" );
break;
}
if ( reg < 0xa || reg > 0xd )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter GPIO register invalid (see vpoutfb.conf: [0xa; 0xd] expected)" );
break;
}
if ( vpout->hdmi_count >= VPOUT_HDMI_PORTS )
{
disp_printf( adapter, "[vpoutfb] Error: only %d HDMI ports supported", VPOUT_HDMI_PORTS );
break;
}
vpout->hdmi[vpout->hdmi_count].assigned = true;
strcpy( vpout->hdmi[vpout->hdmi_count].transmitter, name );
vpout->hdmi[vpout->hdmi_count].device.it66121.bus = bus;
vpout->hdmi[vpout->hdmi_count].device.it66121.address = address;
vpout->hdmi[vpout->hdmi_count].device.it66121.speed = speed;
vpout->hdmi[vpout->hdmi_count].device.it66121.base = base;
vpout->hdmi[vpout->hdmi_count].device.it66121.reg = reg;
vpout->hdmi[vpout->hdmi_count].device.it66121.pin = pin;
vpout->hdmi_count++;
disp_printf( adapter, "[vpoutfb] Configuration: HDMI[%d] - controller:%s I2C:bus=%d,address=0x%x,speed=%d GPIO:base=0x%x,reg=GPIO%X,pin=%d",
vpout->hdmi_count - 1, name, bus, address, speed * 1000, base, reg, pin );
break;
}
} else
if ( strncmp( value, VPOUT_OPT_HDMI_TDA998x":", strlen( VPOUT_OPT_HDMI_TDA998x ) + 1 ) == 0 )
{
char *name = value;
int bus;
int address;
int speed;
int video_ports = 0;
value += strlen( VPOUT_OPT_HDMI_TDA998x );
*value= 0;
value++;
if ( sscanf( value, "%d:0x%x:%d:0x%x", &bus, &address, &speed, &video_ports ) == 4 )
{
if ( bus < 0 || bus > 3 )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter I2C bus invalid (see vpoutfb.conf)" );
break;
}
if ( address < 0 || address > 0xffff )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter I2C address invalid (see vpoutfb.conf)" );
break;
}
if ( speed <= 0 )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter I2C speed invalid (see vpoutfb.conf)" );
break;
}
if ( vpout->hdmi_count >= VPOUT_HDMI_PORTS )
{
disp_printf( adapter, "[vpoutfb] Error: only %d HDMI ports supported", VPOUT_HDMI_PORTS );
break;
}
vpout->hdmi[vpout->hdmi_count].assigned = true;
strcpy( vpout->hdmi[vpout->hdmi_count].transmitter, name );
vpout->hdmi[vpout->hdmi_count].device.tda998x.bus = bus;
vpout->hdmi[vpout->hdmi_count].device.tda998x.address = address;
vpout->hdmi[vpout->hdmi_count].device.tda998x.speed = speed;
vpout->hdmi[vpout->hdmi_count].device.tda998x.video_ports = video_ports;
vpout->hdmi_count++;
disp_printf( adapter, "[vpoutfb] Configuration: HDMI[%d] - controller:%s I2C:bus=%d,address=0x%x,speed=%d",
vpout->hdmi_count - 1, name, bus, address, speed * 1000 );
break;
}
} else
if ( strncmp( value, VPOUT_OPT_HDMI_TFP410EP":", strlen( VPOUT_OPT_HDMI_TFP410EP ) + 1 ) == 0 )
{
char *name = value;
int bus;
int address;
int speed;
int ddc_bus;
int ddc_slave;
value += strlen( VPOUT_OPT_HDMI_TFP410EP );
*value= 0;
value++;
if ( sscanf( value, "%d:0x%x:%d:%d:0x%x", &bus, &address, &speed, &ddc_bus, &ddc_slave ) == 5 )
{
if ( bus < 0 || bus > 3 )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter I2C bus invalid (see vpoutfb.conf)" );
break;
}
if ( address < 0 || address > 0xffff )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter I2C address invalid (see vpoutfb.conf)" );
break;
}
if ( speed <= 0 )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter I2C speed invalid (see vpoutfb.conf)" );
break;
}
if ( ddc_bus < 0 || ddc_bus > 2 )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter DDC bus invalid (see vpoutfb.conf)" );
break;
}
if ( ddc_slave < 0 || ddc_slave > 0x7f )
{
disp_printf( adapter, "[vpoutfb] Error: HDMI transmitter DDC slave invalid (see vpoutfb.conf)" );
break;
}
if ( vpout->hdmi_count >= VPOUT_HDMI_PORTS )
{
disp_printf( adapter, "[vpoutfb] Error: only %d HDMI ports supported", VPOUT_HDMI_PORTS );
break;
}
vpout->hdmi[vpout->hdmi_count].assigned = true;
strcpy( vpout->hdmi[vpout->hdmi_count].transmitter, name );
vpout->hdmi[vpout->hdmi_count].device.tfp410ep.bus = bus;
vpout->hdmi[vpout->hdmi_count].device.tfp410ep.address = address;
vpout->hdmi[vpout->hdmi_count].device.tfp410ep.speed = speed;
vpout->hdmi[vpout->hdmi_count].device.tfp410ep.ddc_bus = ddc_bus;
vpout->hdmi[vpout->hdmi_count].device.tfp410ep.ddc_slave = ddc_slave;
vpout->hdmi_count++;
disp_printf( adapter, "[vpoutfb] Configuration: HDMI[%d] - controller:%s I2C:bus=%d,address=0x%x,speed=%d,ddc-bus=%d,ddc-slave=0x%x",
vpout->hdmi_count - 1, name, bus, address, speed * 1000, ddc_bus, ddc_slave );
break;
}
}
disp_printf( adapter, "[vpoutfb] Warning: unknown HDMI transmitter configuration (see vpoutfb.conf; configuration->\"%s\")", value );
break;
case VPOUT_OPT_ENABLE:
if ( strstr( value, "lcd_sync_fix" ) != NULL ) {
disp_printf( adapter, "[vpoutfb] Configuration: LCD sync generation fix enabled" );
vpout->enabled |= CONFIG_ENABLE_LCD_SYNC_FIX;
}
break;
case VPOUT_OPT_VERBOSE:
if ( strstr( value, "silent" ) != NULL ) {
disp_printf( adapter, "[vpoutfb] Configuration: \"silent\" output level" );
verbose = VPOUT_SLOG_LEVEL_0;
} else if ( strstr( value, "warn" ) != NULL ) {
disp_printf( adapter, "[vpoutfb] Configuration: \"warn\" output level" );
verbose = VPOUT_SLOG_LEVEL_WARNING;
} else if ( strstr( value, "info" ) != NULL ) {
disp_printf( adapter, "[vpoutfb] Configuration: \"info\" output level" );
verbose = VPOUT_SLOG_LEVEL_INFO;
} else if ( strstr( value, "debug" ) != NULL ) {
disp_printf( adapter, "[vpoutfb] Configuration: \"debug\" output level" );
verbose = VPOUT_SLOG_LEVEL_DEBUG;
} else
disp_printf( adapter, "[vpoutfb] Warning: unknown verbosity level (see vpoutfb.conf)" );
break;
default:
disp_printf( adapter, "[vpoutfb] Unknown option %s", c );
break;
}
}
fclose( fin );
/* Error detection */
#define CONFIG_ERROR( text ) { disp_printf( adapter, text ); return (-1); }
/* base option */
if ( vpout->registers_base == 0 )
CONFIG_ERROR( "[vpoutfb] Fatal: unknown display controller registers base phys-address (see vpoutfb.conf)" );
/* size option */
if ( vpout->registers_size == 0 )
disp_printf( adapter, "[vpoutfb] Warning: using display controller default registers size (see vpoutfb.conf)" );
/* irq option */
if ( vpout->irq == 0 )
disp_printf( adapter, "[vpoutfb] Warning: unknown display controller interrupt (see vpoutfb.conf)" );
/* dispmode option */
switch ( vpout->display[0] )
{
case CONFIG_DISPLAY_PORT_HDMI0:
if ( !vpout->hdmi[DISPLAY_PORT_INDEX( CONFIG_DISPLAY_PORT_HDMI0 )].assigned )
CONFIG_ERROR( "[vpoutfb] Fatal: damaged display controller configuration (see vpoutfb.conf::hdmi option)" );
break;
}
return (0);
}

4
devg/vpoutfb/pinfo.mk Обычный файл
Просмотреть файл

@ -0,0 +1,4 @@
define PINFO
PINFO DESCRIPTION=Graphics driver for Elvees 1892VM14YA ARMv7 SoC \(VPOUT display controller\)
endef
LIBS += m

930
devg/vpoutfb/tda998x.c Обычный файл
Просмотреть файл

@ -0,0 +1,930 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* NXP TDA998x I2C HDMI transmitter interface */
/*************************************************/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* REGISTERS */
/*************************************************/
/* Registers access */
#define REGISTER( page, addr ) (((page) << 8) | (addr))
#define REGISTER_ADDRESS( reg ) ((reg) & 0xff)
#define REGISTER_PAGE( reg ) (((reg) >> 8) & 0xff)
/* Registers pages */
#define REGISTER_PAGE_HDMI_CTRL (0x00)
#define REGISTER_PAGE_HDMI_PPL (0x02)
#define REGISTER_PAGE_HDMI_EDID (0x09)
#define REGISTER_PAGE_HDMI_INFO (0x10)
#define REGISTER_PAGE_HDMI_AUDIO (0x11)
#define REGISTER_PAGE_HDMI_HDCP_OTP (0x12)
#define REGISTER_PAGE_HDMI_GAMUT (0x13)
/* Page setup register */
#define REGISTER_CURPAGE (0xff) /* W */
/* General Control (page: 00h) */
#define REGISTER_VERSION_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x00 ) /* R */
#define REGISTER_MAIN_CNTRL0 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x01 ) /* RW */
#define REGISTER_MAIN_CNTRL0_SCALER (1 << 7)
#define REGISTER_MAIN_CNTRL0_CEHS (1 << 4)
#define REGISTER_MAIN_CNTRL0_CECS (1 << 3)
#define REGISTER_MAIN_CNTRL0_DEHS (1 << 2)
#define REGISTER_MAIN_CNTRL0_DECS (1 << 1)
#define REGISTER_MAIN_CNTRL0_SR (1 << 0)
#define REGISTER_VERSION_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x02 ) /* R */
#define REGISTER_SOFTRESET REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x0a ) /* W */
#define REGISTER_SOFTRESET_I2C_MASTER (1 << 1)
#define REGISTER_SOFTRESET_AUDIO (1 << 0)
#define REGISTER_DDC_DISABLE REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x0b ) /* RW */
#define REGISTER_CCLK_ON REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x0c ) /* RW */
#define REGISTER_I2C_MASTER REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x0d ) /* RW */
#define REGISTER_I2C_MASTER_APP_STRT_LAT (1 << 2)
#define REGISTER_I2C_MASTER_DIS_FILT (1 << 1)
#define REGISTER_I2C_MASTER_DIS_MM (1 << 0)
#define REGISTER_FEAT_POWERDOWN REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x0e ) /* RW */
#define REGISTER_FEAT_POWERDOWN_SPDIF (1 << 3)
#define REGISTER_INT_FLAGS_0 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x0f ) /* RW */
#define REGISTER_INT_FLAGS_1 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x10 ) /* RW */
#define REGISTER_INT_FLAGS_2 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x11 ) /* RW */
#define REGISTER_INT_FLAGS_2_EDID_BLK_RD (1 << 1)
#define REGISTER_ENA_ACLK REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x16 ) /* RW */
#define REGISTER_ENA_VP_0 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x18 ) /* RW */
#define REGISTER_ENA_VP_1 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x19 ) /* RW */
#define REGISTER_ENA_VP_2 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x1a ) /* RW */
#define REGISTER_ENA_AP REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x1e ) /* RW */
#define REGISTER_VIP_CNTRL_0 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x20 ) /* W */
#define REGISTER_VIP_CNTRL_0_MIRR_A (1 << 7)
#define REGISTER_VIP_CNTRL_0_SWAP_A( x )(((x) & 7) << 4)
#define REGISTER_VIP_CNTRL_0_MIRR_B (1 << 3)
#define REGISTER_VIP_CNTRL_0_SWAP_B( x )(((x) & 7) << 0)
#define REGISTER_VIP_CNTRL_1 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x21 ) /* W */
#define REGISTER_VIP_CNTRL_1_MIRR_C (1 << 7)
#define REGISTER_VIP_CNTRL_1_SWAP_C( x )(((x) & 7) << 4)
#define REGISTER_VIP_CNTRL_1_MIRR_D (1 << 3)
#define REGISTER_VIP_CNTRL_1_SWAP_D( x )(((x) & 7) << 0)
#define REGISTER_VIP_CNTRL_2 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x22 ) /* W */
#define REGISTER_VIP_CNTRL_2_MIRR_E (1 << 7)
#define REGISTER_VIP_CNTRL_2_SWAP_E( x )(((x) & 7) << 4)
#define REGISTER_VIP_CNTRL_2_MIRR_F (1 << 3)
#define REGISTER_VIP_CNTRL_2_SWAP_F( x )(((x) & 7) << 0)
#define REGISTER_VIP_CNTRL_3 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x23 ) /* W */
#define REGISTER_VIP_CNTRL_3_EDGE (1 << 7)
#define REGISTER_VIP_CNTRL_3_DE_INT (1 << 6)
#define REGISTER_VIP_CNTRL_3_SYNC_HS (1 << 5)
#define REGISTER_VIP_CNTRL_3_SYNC_DE (1 << 4)
#define REGISTER_VIP_CNTRL_3_EMB (1 << 3)
#define REGISTER_VIP_CNTRL_3_V_TGL (1 << 2)
#define REGISTER_VIP_CNTRL_3_H_TGL (1 << 1)
#define REGISTER_VIP_CNTRL_3_X_TGL (1 << 0)
#define REGISTER_VIP_CNTRL_4 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x24 ) /* W */
#define REGISTER_VIP_CNTRL_4_TST_PAT (1 << 7)
#define REGISTER_VIP_CNTRL_4_TST_656 (1 << 6)
#define REGISTER_VIP_CNTRL_4_656_ALT (1 << 5)
#define REGISTER_VIP_CNTRL_4_CCIR656 (1 << 4)
#define REGISTER_VIP_CNTRL_4_BLANKIT( x )(((x) & 3) << 2)
#define REGISTER_VIP_CNTRL_4_BLC( x ) (((x) & 3) << 0)
#define REGISTER_VIP_CNTRL_5 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x25 ) /* W */
#define REGISTER_VIP_CNTRL_5_SP_CNT( x )(((x) & 3) << 1)
#define REGISTER_VIP_CNTRL_5_CKCASE (1 << 0)
#define REGISTER_MUX_AP REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x26 ) /* RW */
#define REGISTER_MUX_AP_SELECT_I2S (0x64)
#define REGISTER_MUX_AP_SELECT_SPDIF (0x40)
#define REGISTER_MUX_VP_VIP_OUT REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x27 ) /* RW */
#define REGISTER_MAT_CONTRL REGISTER( REGISTER_PAGE_HDMI_CTRL, 0x80 ) /* W */
#define REGISTER_MAT_CONTRL_MAT_BP (1 << 2)
#define REGISTER_MAT_CONTRL_MAT_SC( x ) (((x) & 3) << 0)
#define REGISTER_VIDFORMAT REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xa0 ) /* W */
#define REGISTER_REFPIX_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xa1 ) /* W */
#define REGISTER_REFPIX_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xa2 ) /* W */
#define REGISTER_REFLINE_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xa3 ) /* W */
#define REGISTER_REFLINE_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xa4 ) /* W */
#define REGISTER_NPIX_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xa5 ) /* W */
#define REGISTER_NPIX_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xa6 ) /* W */
#define REGISTER_NLINE_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xa7 ) /* W */
#define REGISTER_NLINE_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xa8 ) /* W */
#define REGISTER_VS_LINE_STRT_1_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xa9 ) /* W */
#define REGISTER_VS_LINE_STRT_1_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xaa ) /* W */
#define REGISTER_VS_PIX_STRT_1_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xab ) /* W */
#define REGISTER_VS_PIX_STRT_1_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xac ) /* W */
#define REGISTER_VS_LINE_END_1_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xad ) /* W */
#define REGISTER_VS_LINE_END_1_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xae ) /* W */
#define REGISTER_VS_PIX_END_1_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xaf ) /* W */
#define REGISTER_VS_PIX_END_1_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xb0 ) /* W */
#define REGISTER_VS_LINE_STRT_2_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xb1 ) /* W */
#define REGISTER_VS_LINE_STRT_2_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xb2 ) /* W */
#define REGISTER_VS_PIX_STRT_2_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xb3 ) /* W */
#define REGISTER_VS_PIX_STRT_2_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xb4 ) /* W */
#define REGISTER_VS_LINE_END_2_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xb5 ) /* W */
#define REGISTER_VS_LINE_END_2_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xb6 ) /* W */
#define REGISTER_VS_PIX_END_2_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xb7 ) /* W */
#define REGISTER_VS_PIX_END_2_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xb8 ) /* W */
#define REGISTER_HS_PIX_START_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xb9 ) /* W */
#define REGISTER_HS_PIX_START_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xba ) /* W */
#define REGISTER_HS_PIX_STOP_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xbb ) /* W */
#define REGISTER_HS_PIX_STOP_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xbc ) /* W */
#define REGISTER_VWIN_START_1_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xbd ) /* W */
#define REGISTER_VWIN_START_1_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xbe ) /* W */
#define REGISTER_VWIN_END_1_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xbf ) /* W */
#define REGISTER_VWIN_END_1_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xc0 ) /* W */
#define REGISTER_VWIN_START_2_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xc1 ) /* W */
#define REGISTER_VWIN_START_2_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xc2 ) /* W */
#define REGISTER_VWIN_END_2_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xc3 ) /* W */
#define REGISTER_VWIN_END_2_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xc4 ) /* W */
#define REGISTER_DE_START_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xc5 ) /* W */
#define REGISTER_DE_START_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xc6 ) /* W */
#define REGISTER_DE_STOP_MSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xc7 ) /* W */
#define REGISTER_DE_STOP_LSB REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xc8 ) /* W */
#define REGISTER_TBG_CNTRL_0 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xca ) /* W */
#define REGISTER_TBG_CNTRL_0_SYNC_ONCE (1 << 7)
#define REGISTER_TBG_CNTRL_0_SYNC_MTHD (1 << 6)
#define REGISTER_TBG_CNTRL_0_FRAME_DIS (1 << 5)
#define REGISTER_TBG_CNTRL_0_TOP_EXT (1 << 3)
#define REGISTER_TBG_CNTRL_0_DE_EXT (1 << 2)
#define REGISTER_TBG_CNTRL_0_TOP_SEL (1 << 1)
#define REGISTER_TBG_CNTRL_0_TOP_TGL (1 << 0)
#define REGISTER_TBG_CNTRL_1 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xcb ) /* W */
#define REGISTER_TBG_CNTRL_1_DWIN_DIS (1 << 6)
#define REGISTER_TBG_CNTRL_1_V_EXT (1 << 5)
#define REGISTER_TBG_CNTRL_1_H_EXT (1 << 4)
#define REGISTER_TBG_CNTRL_1_X_EXT (1 << 3)
#define REGISTER_TBG_CNTRL_1_TGL_EN (1 << 2)
#define REGISTER_TBG_CNTRL_1_V_TGL (1 << 1)
#define REGISTER_TBG_CNTRL_1_H_TGL (1 << 0)
#define REGISTER_ENABLE_SPACE REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xd6 ) /* W */
#define REGISTER_HVF_CNTRL_0 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xe4 ) /* W */
#define REGISTER_HVF_CNTRL_0_SM (1 << 7)
#define REGISTER_HVF_CNTRL_0_RWB (1 << 6)
#define REGISTER_HVF_CNTRL_0_PREFIL( x )(((x) & 3) << 2)
#define REGISTER_HVF_CNTRL_0_INTPOL( x )(((x) & 3) << 0)
#define REGISTER_HVF_CNTRL_1 REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xe5 ) /* W */
#define REGISTER_HVF_CNTRL_1_SEMI_PLANAR (1 << 6)
#define REGISTER_HVF_CNTRL_1_PAD( x ) (((x) & 3) << 4)
#define REGISTER_HVF_CNTRL_1_VQR( x ) (((x) & 3) << 2)
#define REGISTER_HVF_CNTRL_1_YUVBLK (1 << 1)
#define REGISTER_HVF_CNTRL_1_FOR (1 << 0)
#define REGISTER_RPT_CNTRL REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xf0 ) /* W */
#define REGISTER_I2S_FORMAT REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xfc ) /* RW */
#define REGISTER_I2S_FORMAT_VALUE( x ) (((x) & 3) << 0)
#define REGISTER_AIP_CLKSEL REGISTER( REGISTER_PAGE_HDMI_CTRL, 0xfd ) /* W */
#define REGISTER_AIP_CLKSEL_AIP (1 << 3)
#define REGISTER_AIP_CLKSEL_AIP_I2S (1 << 3)
#define REGISTER_AIP_CLKSEL_AIP_SPDIF (0 << 3)
#define REGISTER_AIP_CLKSEL_FS (3 << 0)
#define REGISTER_AIP_CLKSEL_FS_FS64SPDIF (2 << 0)
#define REGISTER_AIP_CLKSEL_FS_MCLK (1 << 0)
#define REGISTER_AIP_CLKSEL_FS_ACLK (0 << 0)
/* PLL settings (page: 02h) */
#define REGISTER_PLL_SERIAL_1 REGISTER( REGISTER_PAGE_HDMI_PPL, 0x00 ) /* RW */
#define REGISTER_PLL_SERIAL_1_SRL_MAN_IZ (1 << 6)
#define REGISTER_PLL_SERIAL_1_SRL_IZ( x ) (((x) & 3) << 1)
#define REGISTER_PLL_SERIAL_1_SRL_FDN (1 << 0)
#define REGISTER_PLL_SERIAL_2 REGISTER( REGISTER_PAGE_HDMI_PPL, 0x01 ) /* RW */
#define REGISTER_PLL_SERIAL_2_SRL_PR( x ) (((x) & 0xf) << 4)
#define REGISTER_PLL_SERIAL_2_SRL_NOSC( x ) ((x) << 0)
#define REGISTER_PLL_SERIAL_3 REGISTER( REGISTER_PAGE_HDMI_PPL, 0x02 ) /* RW */
#define REGISTER_PLL_SERIAL_3_SRL_PXIN_SEL (1 << 4)
#define REGISTER_PLL_SERIAL_3_SRL_DE (1 << 2)
#define REGISTER_PLL_SERIAL_3_SRL_CCIR (1 << 0)
#define REGISTER_SERIALIZER REGISTER( REGISTER_PAGE_HDMI_PPL, 0x03 ) /* RW */
#define REGISTER_BUFFER_OUT REGISTER( REGISTER_PAGE_HDMI_PPL, 0x04 ) /* RW */
#define REGISTER_PLL_SCG1 REGISTER( REGISTER_PAGE_HDMI_PPL, 0x05 ) /* RW */
#define REGISTER_PLL_SCG2 REGISTER( REGISTER_PAGE_HDMI_PPL, 0x06 ) /* RW */
#define REGISTER_PLL_SCGN1 REGISTER( REGISTER_PAGE_HDMI_PPL, 0x07 ) /* RW */
#define REGISTER_PLL_SCGN2 REGISTER( REGISTER_PAGE_HDMI_PPL, 0x08 ) /* RW */
#define REGISTER_PLL_SCGR1 REGISTER( REGISTER_PAGE_HDMI_PPL, 0x09 ) /* RW */
#define REGISTER_PLL_SCGR2 REGISTER( REGISTER_PAGE_HDMI_PPL, 0x0a ) /* RW */
#define REGISTER_AUDIO_DIV REGISTER( REGISTER_PAGE_HDMI_PPL, 0x0e ) /* RW */
#define REGISTER_AUDIO_DIV_SERCLK_32 (5)
#define REGISTER_AUDIO_DIV_SERCLK_16 (4)
#define REGISTER_AUDIO_DIV_SERCLK_8 (3)
#define REGISTER_AUDIO_DIV_SERCLK_4 (2)
#define REGISTER_AUDIO_DIV_SERCLK_2 (1)
#define REGISTER_AUDIO_DIV_SERCLK_1 (0)
#define REGISTER_SEL_CLK REGISTER( REGISTER_PAGE_HDMI_PPL, 0x11 ) /* RW */
#define REGISTER_SEL_CLK_ENA_SC_CLK (1 << 3)
#define REGISTER_SEL_CLK_SEL_VRF_CLK( x )(((x) & 3) << 1)
#define REGISTER_SEL_CLK_SEL_CLK1 (1 << 0)
#define REGISTER_ANA_GENERAL REGISTER( REGISTER_PAGE_HDMI_PPL, 0x12 ) /* RW */
/* EDID Control (page: 09h) */
#define REGISTER_EDID_DATA_0 REGISTER( REGISTER_PAGE_HDMI_EDID, 0x00 ) /* R */
#define REGISTER_EDID_CTRL REGISTER( REGISTER_PAGE_HDMI_EDID, 0xfa ) /* RW */
#define REGISTER_DDC_ADDR REGISTER( REGISTER_PAGE_HDMI_EDID, 0xfb ) /* RW */
#define REGISTER_DDC_OFFS REGISTER( REGISTER_PAGE_HDMI_EDID, 0xfc ) /* RW */
#define REGISTER_DDC_SEGM_ADDR REGISTER( REGISTER_PAGE_HDMI_EDID, 0xfd ) /* RW */
#define REGISTER_DDC_SEGM REGISTER( REGISTER_PAGE_HDMI_EDID, 0xfe ) /* RW */
/* Information frames and packets (page: 10h) */
#define REGISTER_IF1_HB0 REGISTER( REGISTER_PAGE_HDMI_INFO, 0x20 ) /* RW */
#define REGISTER_IF2_HB0 REGISTER( REGISTER_PAGE_HDMI_INFO, 0x40 ) /* RW */
#define REGISTER_IF3_HB0 REGISTER( REGISTER_PAGE_HDMI_INFO, 0x60 ) /* RW */
#define REGISTER_IF4_HB0 REGISTER( REGISTER_PAGE_HDMI_INFO, 0x80 ) /* RW */
#define REGISTER_IF5_HB0 REGISTER( REGISTER_PAGE_HDMI_INFO, 0xa0 ) /* RW */
/* Audio settings and content info packets (page: 11h) */
#define REGISTER_AIP_CNTRL_0 REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x00 ) /* RW */
#define REGISTER_AIP_CNTRL_0_RST_CTS (1 << 6)
#define REGISTER_AIP_CNTRL_0_ACR_MAN (1 << 5)
#define REGISTER_AIP_CNTRL_0_LAYOUT (1 << 2)
#define REGISTER_AIP_CNTRL_0_SWAP (1 << 1)
#define REGISTER_AIP_CNTRL_0_RST_FIFO (1 << 0)
#define REGISTER_CA_I2S REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x01 ) /* RW */
#define REGISTER_CA_I2S_HBR_CHSTAT (1 << 6)
#define REGISTER_CA_I2S_CA_I2S( x ) (((x) & 31) << 0)
#define REGISTER_LATENCY_RD REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x04 ) /* RW */
#define REGISTER_ACR_CTS_0 REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x05 ) /* RW */
#define REGISTER_ACR_CTS_1 REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x06 ) /* RW */
#define REGISTER_ACR_CTS_2 REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x07 ) /* RW */
#define REGISTER_ACR_N_0 REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x08 ) /* RW */
#define REGISTER_ACR_N_1 REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x09 ) /* RW */
#define REGISTER_ACR_N_2 REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x0a ) /* RW */
#define REGISTER_CTS_N REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x0c ) /* RW */
#define REGISTER_CTS_N_M( x ) (((x) & 3) << 4)
#define REGISTER_CTS_N_K( x ) (((x) & 7) << 0)
#define REGISTER_ENC_CNTRL REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x0d ) /* RW */
#define REGISTER_ENC_CNTRL_CTL_CODE( x )(((x) & 3) << 2)
#define REGISTER_ENC_CNTRL_RST_SEL (1 << 1)
#define REGISTER_ENC_CNTRL_RST_ENC (1 << 0)
#define REGISTER_DIP_FLAGS REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x0e ) /* RW */
#define REGISTER_DIP_FLAGS_GC (1 << 1)
#define REGISTER_DIP_FLAGS_ACR (1 << 0)
#define REGISTER_DIP_IF_FLAGS REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x0f ) /* RW */
#define REGISTER_DIP_IF_FLAGS_IF5 (1 << 5)
#define REGISTER_DIP_IF_FLAGS_IF4 (1 << 4)
#define REGISTER_DIP_IF_FLAGS_IF3 (1 << 3)
#define REGISTER_DIP_IF_FLAGS_IF2 (1 << 2)
#define REGISTER_DIP_IF_FLAGS_IF1 (1 << 1)
#define REGISTER_CH_STAT_B( x ) REGISTER( REGISTER_PAGE_HDMI_AUDIO, 0x14 + (x) ) /* RW */
/* HDCP and OTP (page: 12h) */
#define REGISTER_TX3 REGISTER( REGISTER_PAGE_HDMI_HDCP_OTP, 0x9a ) /* RW */
#define REGISTER_TX4 REGISTER( REGISTER_PAGE_HDMI_HDCP_OTP, 0x9b ) /* RW */
#define REGISTER_TX4_PD_RAM (1 << 1)
#define REGISTER_TX33 REGISTER( REGISTER_PAGE_HDMI_HDCP_OTP, 0xb8 ) /* RW */
#define REGISTER_TX33_HDMI (1 << 1)
/* CEC registers (not paged) */
#define REGISTER_CEC_INTSTATUS REGISTER( 0x00, 0xee ) /* R */
#define REGISTER_CEC_INTSTATUS_HDMI (1 << 1)
#define REGISTER_CEC_INTSTATUS_CEC (1 << 0)
#define REGISTER_CEC_FRO_IM_CLK_CTRL REGISTER( 0x00, 0xfb ) /* RW */
#define REGISTER_CEC_FRO_IM_CLK_CTRL_GHOST_DIS (1 << 7)
#define REGISTER_CEC_FRO_IM_CLK_CTRL_ENA_OTP (1 << 6)
#define REGISTER_CEC_FRO_IM_CLK_CTRL_IMCLK_SEL (1 << 1)
#define REGISTER_CEC_FRO_IM_CLK_CTRL_FRO_DIV (1 << 0)
#define REGISTER_CEC_RXSHPDINTENA REGISTER( 0x00, 0xfc ) /* RW */
#define REGISTER_CEC_RXSHPDINT REGISTER( 0x00, 0xfd ) /* R */
#define REGISTER_CEC_RXSHPDLEV REGISTER( 0x00, 0xfe ) /* R */
#define REGISTER_CEC_RXSHPDLEV_HPD (1 << 1)
#define REGISTER_CEC_RXSHPDLEV_RXSENS (1 << 0)
#define REGISTER_CEC_ENAMODS REGISTER( 0x00, 0xff ) /* RW */
#define REGISTER_CEC_ENAMODS_DIS_FRO (1 << 6)
#define REGISTER_CEC_ENAMODS_DIS_CCLK (1 << 5)
#define REGISTER_CEC_ENAMODS_EN_RXSENS (1 << 2)
#define REGISTER_CEC_ENAMODS_EN_HDMI (1 << 1)
#define REGISTER_CEC_ENAMODS_EN_CEC (1 << 0)
/*************************************************/
/* HARDWARE */
/*************************************************/
/* Device version */
#define TDA9989N2 0x0101
#define TDA19989 0x0201
#define TDA19989N2 0x0202
#define TDA19988 0x0301
/*************************************************/
/* I2C FUNCTIONS */
/*************************************************/
static void tda998x_cec_register_write8( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t reg, uint8_t val )
{
disp_adapter_t *adapter = vpout->adapter;
uint16_t cec_addr = 0x34 + (vpout->hdmi[port].device.tda998x.address & 0x03) /* CEC I2C address bound to TDA998x I2C addr by configuration pins */;
int ret = 0;
ret = i2c_write( vpout, vpout_draw, port, vpout->hdmi[port].device.tda998x.bus, vpout->hdmi[port].device.tda998x.speed, cec_addr, reg, &val, 1 );
if ( ret < 0 )
goto fail;
return;
fail:
disp_printf( adapter, "[vpoutfb: tda998x] Fatal: I2C HDMI controller CEC register writing failed [I2C issue: port=%d, register=0x%x, status=%d]", port, reg, ret );
}
static uint8_t tda998x_cec_register_read8( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t reg )
{
disp_adapter_t *adapter = vpout->adapter;
uint16_t cec_addr = 0x34 + (vpout->hdmi[port].device.tda998x.address & 0x03) /* CEC I2C address bound to TDA998x I2C addr by configuration pins */;
uint8_t val = 0;
int ret = 0;
ret = i2c_read( vpout, vpout_draw, port, vpout->hdmi[port].device.tda998x.bus, vpout->hdmi[port].device.tda998x.speed, cec_addr, reg, &val, 1 );
if ( ret < 0 )
goto fail;
return val;
fail:
disp_printf( adapter, "[vpoutfb: tda998x] Fatal: I2C HDMI controller CEC register reading failed [I2C issue: port=%d, register=0x%x, status=%d]", port, reg, ret );
return (0);
}
static int tda998x_set_page( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t page )
{
if ( page != vpout->hdmi[port].device.tda998x.current_page )
{
disp_adapter_t *adapter = vpout->adapter;
int ret = 0;
ret = i2c_write( vpout, vpout_draw, port, vpout->hdmi[port].device.tda998x.bus, vpout->hdmi[port].device.tda998x.speed,
vpout->hdmi[port].device.tda998x.address, REGISTER_CURPAGE, &page, 1 );
if ( ret < 0 )
{
disp_printf( adapter, "[vpoutfb: tda998x] Fatal: I2C HDMI controller registers page setup failed [I2C issue: port=%d, status=%d]", port, ret );
return ret;
}
vpout->hdmi[port].device.tda998x.current_page = page;
}
return (0);
}
static int tda998x_register_read8_range( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint16_t reg, char *buf, int count )
{
disp_adapter_t *adapter = vpout->adapter;
int ret = 0;
ret = tda998x_set_page( vpout, vpout_draw, port, REGISTER_PAGE( reg ) );
if ( ret < 0 )
goto out;
ret = i2c_read( vpout, vpout_draw, port, vpout->hdmi[port].device.tda998x.bus, vpout->hdmi[port].device.tda998x.speed, vpout->hdmi[port].device.tda998x.address,
REGISTER_ADDRESS( reg ), (uint8_t *)buf, count );
if ( ret < 0 )
goto fail;
goto out;
fail:
disp_printf( adapter, "[vpoutfb: tda998x] Fatal: I2C HDMI controller register reading failed [I2C issue: port=%d, register=0x%x, status=%d]", port, reg, ret );
out:
return ret;
}
static __attribute__((unused)) void tda998x_register_write8_range( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint16_t reg,
uint8_t *ptr, int count )
{
disp_adapter_t *adapter = vpout->adapter;
uint8_t *buf = (uint8_t *)malloc( count * sizeof( uint8_t ) );
int ret = 0;
memcpy( buf, ptr, count );
ret = tda998x_set_page( vpout, vpout_draw, port, REGISTER_PAGE( reg ) );
if ( ret < 0 )
goto out;
ret = i2c_write( vpout, vpout_draw, port, vpout->hdmi[port].device.tda998x.bus, vpout->hdmi[port].device.tda998x.speed, vpout->hdmi[port].device.tda998x.address,
REGISTER_ADDRESS( reg ), buf, count );
if ( ret < 0 )
disp_printf( adapter, "[vpoutfb: tda998x] Fatal: I2C HDMI controller register writing failed [I2C issue: port=%d, register=0x%x, status=%d]", port, reg, ret );
out:
if ( buf )
free( buf );
return;
}
static int tda998x_register_read8( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint16_t reg )
{
uint8_t val = 0;
int ret = 0;
ret = tda998x_register_read8_range( vpout, vpout_draw, port, reg, (char *)&val, sizeof( val ) );
if ( ret < 0 )
return ret;
return val;
}
static void tda998x_register_write8( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint16_t reg, uint8_t val )
{
disp_adapter_t *adapter = vpout->adapter;
int ret = 0;
ret = tda998x_set_page( vpout, vpout_draw, port, REGISTER_PAGE( reg ) );
if ( ret < 0 )
goto out;
ret = i2c_write( vpout, vpout_draw, port, vpout->hdmi[port].device.tda998x.bus, vpout->hdmi[port].device.tda998x.speed, vpout->hdmi[port].device.tda998x.address,
REGISTER_ADDRESS( reg ), &val, 1 );
if ( ret < 0 )
disp_printf( adapter, "[vpoutfb: tda998x] Fatal: I2C HDMI controller register writing failed [I2C issue: port=%d, register=0x%x, status=%d]", port, reg, ret );
out:
return;
}
static void tda998x_register_write16( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint16_t reg, uint16_t val )
{
disp_adapter_t *adapter = vpout->adapter;
uint8_t buf[] = { val >> 8, val };
int ret = 0;
ret = tda998x_set_page( vpout, vpout_draw, port, REGISTER_PAGE( reg ) );
if ( ret < 0 )
goto out;
ret = i2c_write( vpout, vpout_draw, port, vpout->hdmi[port].device.tda998x.bus, vpout->hdmi[port].device.tda998x.speed, vpout->hdmi[port].device.tda998x.address,
REGISTER_ADDRESS( reg ), buf, 2 );
if ( ret < 0 )
disp_printf( adapter, "[vpoutfb: tda998x] Fatal: I2C HDMI controller register writing failed [I2C issue: port=%d, register=0x%x, status=%d]", port, reg, ret );
out:
return;
}
static void tda998x_register_set8( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint16_t reg, uint8_t val )
{
int old_val;
old_val = tda998x_register_read8( vpout, vpout_draw, port, reg );
if ( old_val >= 0 )
tda998x_register_write8( vpout, vpout_draw, port, reg, old_val | val );
}
static void tda998x_register_clear8( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint16_t reg, uint8_t val )
{
int old_val;
old_val = tda998x_register_read8( vpout, vpout_draw, port, reg );
if ( old_val >= 0 )
tda998x_register_write8( vpout, vpout_draw, port, reg, old_val & ~val );
}
/*************************************************/
/* HARDWARE FUNCTIONS */
/*************************************************/
static int tda998x_read_edid_block( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, uint8_t *buf, uint32_t block, size_t length )
{
disp_adapter_t *adapter = vpout->adapter;
uint8_t offset = (block & 1) ? 128 : 0,
segptr = block / 2;
int ret, i;
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_DDC_ADDR, 0xa0 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_DDC_OFFS, offset );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_DDC_SEGM_ADDR, 0x60 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_DDC_SEGM, segptr );
/* Enable EDID reading sequence */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_EDID_CTRL, 0x1 );
/* Clearing EDID reading sequence enable flag */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_EDID_CTRL, 0x0 );
/* wait for block read to complete: */
for ( i = 100; i > 0; i-- )
{
disp_usecspin( 1 * 1000 );
ret = tda998x_register_read8( vpout, vpout_draw, port_index, REGISTER_INT_FLAGS_2 );
if ( ret < 0 )
return ret;
if ( ret & REGISTER_INT_FLAGS_2_EDID_BLK_RD )
break;
}
if ( i == 0 )
{
disp_printf( adapter, "[vpoutfb: tda998x] Error: I2C HDMI controller DDC transaction timeout [I2C issue: port=%d]", port_index );
return (-ETIMEDOUT);
}
ret = tda998x_register_read8_range( vpout, vpout_draw, port_index, REGISTER_EDID_DATA_0, (char *)buf, length );
if ( ret )
{
disp_printf( adapter, "[vpoutfb: tda998x] Error: I2C HDMI controller DDC transaction failed [I2C issue: port=%d]", port_index );
return ret;
}
return (0);
}
static void tda998x_setup_dpms( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, bool switch_on )
{
if ( switch_on )
{
/* Enable video ports (audio lanes not enabled) */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_ENA_VP_0, 0xff );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_ENA_VP_1, 0xff );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_ENA_VP_2, 0xff );
/* Setup ports muxing */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_VIP_CNTRL_0, vpout->hdmi[port_index].device.tda998x.vip_cntrl_0 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_VIP_CNTRL_1, vpout->hdmi[port_index].device.tda998x.vip_cntrl_1 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_VIP_CNTRL_2, vpout->hdmi[port_index].device.tda998x.vip_cntrl_2 );
} else {
/* Disable video ports */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_ENA_VP_0, 0x00 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_ENA_VP_1, 0x00 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_ENA_VP_2, 0x00 );
}
}
/*************************************************/
/* INTERFACE FUNCTIONS */
/*************************************************/
void tda998x_probe( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index )
{
disp_adapter_t *adapter = vpout->adapter;
if ( i2c_init( vpout, vpout_draw, vpout->hdmi[port_index].device.tda998x.bus, port_index ) )
{
disp_printf( adapter, "[vpoutfb: tda998x] Fatal: I2C HDMI controller initialization failed [I2C issue: port=%d]", port_index );
return;
}
vpout->hdmi[port_index].device.tda998x.current_page = 0xff;
vpout->hdmi[port_index].device.tda998x.vip_cntrl_0 = REGISTER_VIP_CNTRL_0_SWAP_A( 2 ) | REGISTER_VIP_CNTRL_0_SWAP_B( 3 );
vpout->hdmi[port_index].device.tda998x.vip_cntrl_1 = REGISTER_VIP_CNTRL_1_SWAP_C( 0 ) | REGISTER_VIP_CNTRL_1_SWAP_D( 1 );
vpout->hdmi[port_index].device.tda998x.vip_cntrl_2 = REGISTER_VIP_CNTRL_2_SWAP_E( 4 ) | REGISTER_VIP_CNTRL_2_SWAP_F( 5 );
}
void tda998x_reset( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index )
{
/* reset audio and i2c master */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_SOFTRESET, REGISTER_SOFTRESET_AUDIO | REGISTER_SOFTRESET_I2C_MASTER );
disp_usecspin( 50 * 1000 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_SOFTRESET, 0 );
disp_usecspin( 50 * 1000 );
/* reset transmitter */
tda998x_register_set8( vpout, vpout_draw, port_index, REGISTER_MAIN_CNTRL0, REGISTER_MAIN_CNTRL0_SR );
tda998x_register_clear8( vpout, vpout_draw, port_index, REGISTER_MAIN_CNTRL0, REGISTER_MAIN_CNTRL0_SR );
/* PLL registers common configuration */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_PLL_SERIAL_1, 0x00 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_PLL_SERIAL_2, REGISTER_PLL_SERIAL_2_SRL_NOSC( 1 ) );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_PLL_SERIAL_3, 0x00 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_SERIALIZER, 0x00 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_BUFFER_OUT, 0x00 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_PLL_SCG1, 0x00 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_AUDIO_DIV, REGISTER_AUDIO_DIV_SERCLK_8 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_SEL_CLK, REGISTER_SEL_CLK_SEL_CLK1 | REGISTER_SEL_CLK_ENA_SC_CLK );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_PLL_SCGN1, 0xfa );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_PLL_SCGN2, 0x00 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_PLL_SCGR1, 0x5b );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_PLL_SCGR2, 0x00 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_PLL_SCG2, 0x10 );
/* Write the default value MUX register */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_MUX_VP_VIP_OUT, 0x24 );
}
void tda998x_remove( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index )
{
if ( vpout->hdmi[port_index].device.tda998x.revision != 0 )
{
/* Switch ports OFF */
tda998x_setup_dpms( vpout, vpout_draw, port_index, false );
/* Disable IRQs */
tda998x_cec_register_write8( vpout, vpout_draw, port_index, REGISTER_CEC_RXSHPDINTENA, 0 );
tda998x_register_clear8( vpout, vpout_draw, port_index, REGISTER_INT_FLAGS_2, REGISTER_INT_FLAGS_2_EDID_BLK_RD );
}
i2c_fini( vpout, vpout_draw, port_index );
}
int tda998x_init( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, uint32_t pixel_clock )
{
disp_adapter_t *adapter = vpout->adapter;
int ret = 0;
uint8_t value = 0;
uint8_t edid[256];
/* Wake up the device */
tda998x_cec_register_write8( vpout, vpout_draw, port_index, REGISTER_CEC_ENAMODS, REGISTER_CEC_ENAMODS_EN_RXSENS | REGISTER_CEC_ENAMODS_EN_HDMI );
tda998x_reset( vpout, vpout_draw, port_index );
/* Read device version */
ret = tda998x_register_read8( vpout, vpout_draw, port_index, REGISTER_VERSION_LSB );
if ( ret < 0 )
goto fail;
else
vpout->hdmi[port_index].device.tda998x.revision |= ret;
ret = tda998x_register_read8( vpout, vpout_draw, port_index, REGISTER_VERSION_MSB );
if ( ret < 0 )
goto fail;
else
vpout->hdmi[port_index].device.tda998x.revision |= ret << 8;
/* Mask features bits: not-hdcp and not-scalar bit cleanup */
vpout->hdmi[port_index].device.tda998x.revision &= ~0x30;
/* Decode device version */
switch ( vpout->hdmi[port_index].device.tda998x.revision )
{
case TDA9989N2:
disp_printf( adapter, "[vpoutfb: tda998x] Info: TDA9989-2 I2C HDMI transmitter detected" );
break;
case TDA19989:
disp_printf( adapter, "[vpoutfb: tda998x] Info: TDA19989 I2C HDMI transmitter detected" );
break;
case TDA19989N2:
disp_printf( adapter, "[vpoutfb: tda998x] Info: TDA19989-2 I2C HDMI transmitter detected" );
break;
case TDA19988:
disp_printf( adapter, "[vpoutfb: tda998x] Info: TDA19988 I2C HDMI transmitter detected" );
break;
default:
disp_printf( adapter, "[vpoutfb: tda998x] Fatal: I2C HDMI controller initialization failed [found unsupported device: %04x]",
vpout->hdmi[port_index].device.tda998x.revision );
goto fail;
}
/* Enable DDC */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_DDC_DISABLE, 0x00 );
/* Set clock on DDC channel */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_TX3, 39 );
/* Disable multi-master mode */
if ( vpout->hdmi[port_index].device.tda998x.revision == TDA19989 )
tda998x_register_set8( vpout, vpout_draw, port_index, REGISTER_I2C_MASTER, REGISTER_I2C_MASTER_DIS_MM );
tda998x_cec_register_write8( vpout, vpout_draw, port_index, REGISTER_CEC_FRO_IM_CLK_CTRL, REGISTER_CEC_FRO_IM_CLK_CTRL_GHOST_DIS |
REGISTER_CEC_FRO_IM_CLK_CTRL_IMCLK_SEL );
/* Enable EDID IRQ */
tda998x_register_set8( vpout, vpout_draw, port_index, REGISTER_INT_FLAGS_2, REGISTER_INT_FLAGS_2_EDID_BLK_RD );
/* Apply optional video-ports properties */
if ( vpout->hdmi[port_index].device.tda998x.video_ports != 0 )
{
vpout->hdmi[port_index].device.tda998x.vip_cntrl_0 = vpout->hdmi[port_index].device.tda998x.video_ports >> 16;
vpout->hdmi[port_index].device.tda998x.vip_cntrl_1 = vpout->hdmi[port_index].device.tda998x.video_ports >> 8;
vpout->hdmi[port_index].device.tda998x.vip_cntrl_2 = vpout->hdmi[port_index].device.tda998x.video_ports;
}
/* Check if monitor detected (hot-plug detection bit) */
value = tda998x_cec_register_read8( vpout, vpout_draw, port_index, REGISTER_CEC_RXSHPDLEV );
if ( value & REGISTER_CEC_RXSHPDLEV_HPD )
disp_printf( adapter, "[vpoutfb: tda998x] Info: monitor connected" );
/* Read EDID and detect HDMI sink */
if ( tda998x_read_edid( vpout, vpout_draw, port_index, (uint8_t *)edid, sizeof( edid ) ) != sizeof( edid ) )
disp_printf( adapter, "[vpoutfb: tda998x] Error: I2C HDMI controller DDC channel issue [EDID not found]" );
vpout->hdmi[port_index].device.tda998x.is_hdmi_sink = drm_detect_hdmi_monitor( (struct edid *)edid );
return (0);
fail:
return (-1);
}
void tda998x_encoder_mode_set( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, disp_crtc_settings_t *settings )
{
uint16_t ref_pix, ref_line, n_pix, n_line, hs_pix_s, hs_pix_e, vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e, vs2_pix_s, vs2_pix_e, vs2_line_s,
vs2_line_e, vwin1_line_s, vwin1_line_e, vwin2_line_s, vwin2_line_e, de_pix_s, de_pix_e;
uint8_t reg, div, rep,
h_sync_pol = settings->sync_polarity & DISP_SYNC_POLARITY_H_POS ? 1 : 0,
v_sync_pol = settings->sync_polarity & DISP_SYNC_POLARITY_V_POS ? 1 : 0;
/* Internally TDA998x is using ITU-R BT.656 style sync but we get VESA style sync. TDA998x is using a reference pixel relative to ITU to sync to the input
* frame and for output sync generation. Currently, we are using reference detection from HS/VS, i.e. REFPIX/REFLINE denote frame start sync point which is
* position of rising VS with coincident rising HS. Now there is some issues to take care of:
* - HDMI data islands require sync-before-active
* - TDA998x register values must be > 0 to be enabled
* - REFLINE needs an additional offset of +1
* - REFPIX needs an addtional offset of +1 for UYUV and +3 for RGB
* So we add +1 to all horizontal and vertical register values, plus an additional +3 for REFPIX as we are using RGB input only. */
n_pix = settings->h_total;
n_line = settings->v_total;
hs_pix_e = (settings->h_sync_start + settings->h_sync_len) - settings->xres;
hs_pix_s = settings->h_sync_start - settings->xres;
de_pix_e = settings->h_total;
de_pix_s = settings->h_total - settings->xres;
ref_pix = 3 + hs_pix_s;
#if 0
/* Attached LCD controllers may generate broken sync. Allow those to adjust the position of the rising VS edge by adding HSKEW to ref_pix. */
if ( adjusted_mode->flags & DRM_MODE_FLAG_HSKEW )
ref_pix += adjusted_mode->hskew;
#else
if ( VPOUT_LCD_SYNC_FIX( vpout ) )
{
ref_pix += settings->h_sync_len;
h_sync_pol = 1 - h_sync_pol;
}
#endif
if ( (settings->sync_polarity & DISP_SYNC_INTERLACED) == 0 )
{
ref_line = 1 + settings->v_sync_start - settings->yres;
vwin1_line_s = settings->v_total - settings->yres - 1;
vwin1_line_e = vwin1_line_s + settings->yres;
vs1_pix_s = vs1_pix_e = hs_pix_s;
vs1_line_s = settings->v_sync_start - settings->yres;
vs1_line_e = vs1_line_s + settings->v_sync_len;
vwin2_line_s = vwin2_line_e = 0;
vs2_pix_s = vs2_pix_e = 0;
vs2_line_s = vs2_line_e = 0;
} else {
ref_line = 1 + (settings->v_sync_start - settings->yres) / 2;
vwin1_line_s = (settings->v_total - settings->yres) / 2;
vwin1_line_e = vwin1_line_s + settings->yres / 2;
vs1_pix_s = vs1_pix_e = hs_pix_s;
vs1_line_s = (settings->v_sync_start - settings->yres) / 2;
vs1_line_e = vs1_line_s + settings->v_sync_len / 2;
vwin2_line_s = vwin1_line_s + settings->v_total / 2;
vwin2_line_e = vwin2_line_s + settings->yres / 2;
vs2_pix_s = vs2_pix_e = hs_pix_s + settings->h_total / 2;
vs2_line_s = vs1_line_s + settings->v_total / 2 ;
vs2_line_e = vs2_line_s + settings->v_sync_len / 2;
}
div = 148500 / settings->pixel_clock;
if ( div != 0 )
{
div--;
if ( div > 3 )
div = 3;
}
/* Mute audio FIFO */
tda998x_register_set8( vpout, vpout_draw, port_index, REGISTER_AIP_CNTRL_0, REGISTER_AIP_CNTRL_0_RST_FIFO );
/* HDMI HDCP mode off */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_TBG_CNTRL_1, REGISTER_TBG_CNTRL_1_DWIN_DIS );
tda998x_register_clear8( vpout, vpout_draw, port_index, REGISTER_TX33, REGISTER_TX33_HDMI );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_ENC_CNTRL, REGISTER_ENC_CNTRL_CTL_CODE( 0 ) );
/* No pre-filter/interpolator */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_HVF_CNTRL_0, REGISTER_HVF_CNTRL_0_PREFIL( 0 ) | REGISTER_HVF_CNTRL_0_INTPOL( 0 ) );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_VIP_CNTRL_5, REGISTER_VIP_CNTRL_5_SP_CNT( 0 ) );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_VIP_CNTRL_4, REGISTER_VIP_CNTRL_4_BLANKIT( 0 ) | REGISTER_VIP_CNTRL_4_BLC( 0 ) );
tda998x_register_clear8( vpout, vpout_draw, port_index, REGISTER_PLL_SERIAL_1, REGISTER_PLL_SERIAL_1_SRL_MAN_IZ );
tda998x_register_clear8( vpout, vpout_draw, port_index, REGISTER_PLL_SERIAL_3, REGISTER_PLL_SERIAL_3_SRL_CCIR | REGISTER_PLL_SERIAL_3_SRL_DE );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_SERIALIZER, 0 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_HVF_CNTRL_1, REGISTER_HVF_CNTRL_1_VQR( 0 ) );
/* TODO: enable pixel repeat for pixel rates less than 25Msamp/s */
rep = 0;
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_RPT_CNTRL, 0 );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_SEL_CLK, REGISTER_SEL_CLK_SEL_VRF_CLK( 0 ) | REGISTER_SEL_CLK_SEL_CLK1 |
REGISTER_SEL_CLK_ENA_SC_CLK );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_PLL_SERIAL_2, REGISTER_PLL_SERIAL_2_SRL_NOSC( div ) | REGISTER_PLL_SERIAL_2_SRL_PR( rep ) );
/* Set color matrix bypass flag */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_MAT_CONTRL, REGISTER_MAT_CONTRL_MAT_BP | REGISTER_MAT_CONTRL_MAT_SC( 1 ) );
/* Set BIAS tmds value */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_ANA_GENERAL, 0x09 );
/* Sync on rising HSYNC/VSYNC */
reg = REGISTER_VIP_CNTRL_3_SYNC_HS;
/* TDA19988 requires high-active sync at input stage, so invert low-active sync provided by master encoder here */
if ( h_sync_pol == 0 )
reg |= REGISTER_VIP_CNTRL_3_H_TGL;
if ( v_sync_pol == 0 )
reg |= REGISTER_VIP_CNTRL_3_V_TGL;
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_VIP_CNTRL_3, reg );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_VIDFORMAT, 0x00 );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_REFPIX_MSB, ref_pix );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_REFLINE_MSB, ref_line );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_NPIX_MSB, n_pix );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_NLINE_MSB, n_line );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VS_LINE_STRT_1_MSB, vs1_line_s );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VS_PIX_STRT_1_MSB, vs1_pix_s );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VS_LINE_END_1_MSB, vs1_line_e );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VS_PIX_END_1_MSB, vs1_pix_e );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VS_LINE_STRT_2_MSB, vs2_line_s );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VS_PIX_STRT_2_MSB, vs2_pix_s );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VS_LINE_END_2_MSB, vs2_line_e );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VS_PIX_END_2_MSB, vs2_pix_e );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_HS_PIX_START_MSB, hs_pix_s );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_HS_PIX_STOP_MSB, hs_pix_e );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VWIN_START_1_MSB, vwin1_line_s );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VWIN_END_1_MSB, vwin1_line_e );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VWIN_START_2_MSB, vwin2_line_s );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_VWIN_END_2_MSB, vwin2_line_e );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_DE_START_MSB, de_pix_s );
tda998x_register_write16( vpout, vpout_draw, port_index, REGISTER_DE_STOP_MSB, de_pix_e );
if ( vpout->hdmi[port_index].device.tda998x.revision == TDA19988 )
/* Let incoming pixels fill the active space (if any) */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_ENABLE_SPACE, 0x00 );
/* Always generate sync polarity relative to input sync and revert input stage toggled sync at output stage */
reg = REGISTER_TBG_CNTRL_1_DWIN_DIS | REGISTER_TBG_CNTRL_1_TGL_EN;
if ( h_sync_pol == 0 )
reg |= REGISTER_TBG_CNTRL_1_H_TGL;
if ( v_sync_pol == 0 )
reg |= REGISTER_TBG_CNTRL_1_V_TGL;
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_TBG_CNTRL_1, reg );
/* Must be last register set */
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_TBG_CNTRL_0, 0 );
/* Only setup the info frames if the sink is HDMI */
if ( vpout->hdmi[port_index].device.tda998x.is_hdmi_sink )
{
#if 0
/* We need to turn HDMI HDCP stuff on to get audio through */
reg &= ~REGISTER_TBG_CNTRL_1_DWIN_DIS;
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_TBG_CNTRL_1, reg );
tda998x_register_write8( vpout, vpout_draw, port_index, REGISTER_ENC_CNTRL, REGISTER_ENC_CNTRL_CTL_CODE( 1 ) );
tda998x_register_set8( vpout, vpout_draw, port_index, REGISTER_TX33, REGISTER_TX33_HDMI );
tda998x_write_avi( vpout, vpout_draw, port_index, adjusted_mode );
#endif
}
/* Switch ports ON */
tda998x_setup_dpms( vpout, vpout_draw, port_index, true );
}
int tda998x_read_edid( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, uint8_t *buf, int size_ )
{
int size = 0,
ret = 0;
if ( size_ != 256 )
return (-1);
if ( vpout->hdmi[port_index].device.tda998x.revision == TDA19988 )
tda998x_register_clear8( vpout, vpout_draw, port_index, REGISTER_TX4, REGISTER_TX4_PD_RAM );
ret = tda998x_read_edid_block( vpout, vpout_draw, port_index, &buf[0], 0 /* EDID block #0 */, 128 /* EDID block size */ );
size += 128;
if ( ret < 0 )
goto done;
ret = tda998x_read_edid_block( vpout, vpout_draw, port_index, &buf[128], 1 /* EDID block #1 */, 128 /* EDID block size */ );
size += 128;
if ( ret < 0 )
goto done;
ret = size;
done:
if ( vpout->hdmi[port_index].device.tda998x.revision == TDA19988 )
tda998x_register_set8( vpout, vpout_draw, port_index, REGISTER_TX4, REGISTER_TX4_PD_RAM );
return ret;
}

211
devg/vpoutfb/tfp410ep.c Обычный файл
Просмотреть файл

@ -0,0 +1,211 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* TI TFP410-EP I2C HDMI transmitter interface */
/*************************************************/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* REGISTERS */
/*************************************************/
/* Registers access */
#define REGISTER( addr ) (addr)
/* Registers */
#define REGISTER_VEN_ID REGISTER( 0x00 ) /* R: 16 bit */
#define REGISTER_DEV_ID REGISTER( 0x02 ) /* R: 16 bit */
#define REGISTER_REV_ID REGISTER( 0x04 ) /* R: 8 bit */
#define REGISTER_CTL_1_MODE REGISTER( 0x08 ) /* RW: 8 bit */
#define REGISTER_CTL_2_MODE REGISTER( 0x09 ) /* RW: 8 bit */
#define REGISTER_CTL_3_MODE REGISTER( 0x0A ) /* RW: 8 bit */
#define REGISTER_CFG REGISTER( 0x0B ) /* R: 8 bit */
#define REGISTER_DE_DLY REGISTER( 0x32 ) /* RW: 8 bit */
#define REGISTER_DE_CTL REGISTER( 0x33 ) /* RW: 8 bit */
#define REGISTER_DE_TOP REGISTER( 0x34 ) /* RW: 8 bit */
#define REGISTER_DE_CNT REGISTER( 0x36 ) /* RW: 16 bit */
#define REGISTER_DE_LIN REGISTER( 0x38 ) /* RW: 16 bit */
#define REGISTER_H_RES REGISTER( 0x3A ) /* R: 16 bit */
#define REGISTER_V_RES REGISTER( 0x3C ) /* R: 16 bit */
/*************************************************/
/* HARDWARE */
/*************************************************/
/* Device VID */
#define TFP410EP_VID 0x014c
/* Device DID */
#define TFP410EP_DID 0x0410
/*************************************************/
/* I2C FUNCTIONS */
/*************************************************/
static void reg_write8( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t reg, uint8_t val )
{
disp_adapter_t *adapter = vpout->adapter;
int ret = 0;
ret = i2c_write( vpout, vpout_draw, port, vpout->hdmi[port].device.tfp410ep.bus, vpout->hdmi[port].device.tfp410ep.speed,
vpout->hdmi[port].device.tfp410ep.address, reg, &val, 1 );
if ( ret < 0 )
goto fail;
return;
fail:
disp_printf( adapter, "[vpoutfb: tfp410ep] Fatal: I2C HDMI controller register writing failed [I2C issue: port=%d, register=0x%x, status=%d]", port, reg, ret );
}
static uint8_t reg_read8( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t reg )
{
disp_adapter_t *adapter = vpout->adapter;
uint8_t val = 0;
int ret = 0;
ret = i2c_read( vpout, vpout_draw, port, vpout->hdmi[port].device.tfp410ep.bus, vpout->hdmi[port].device.tfp410ep.speed,
vpout->hdmi[port].device.tfp410ep.address, reg, &val, 1 );
if ( ret < 0 )
goto fail;
return val;
fail:
disp_printf( adapter, "[vpoutfb: tfp410ep] Fatal: I2C HDMI controller register reading failed [I2C issue: port=%d, register=0x%x, status=%d]", port, reg, ret );
return (0);
}
static uint16_t reg_read16( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t reg )
{
disp_adapter_t *adapter = vpout->adapter;
uint8_t val[2] = {0, 0};
int ret = 0;
ret = i2c_read( vpout, vpout_draw, port, vpout->hdmi[port].device.tfp410ep.bus, vpout->hdmi[port].device.tfp410ep.speed,
vpout->hdmi[port].device.tfp410ep.address, reg, &val[0], 1 );
if ( ret < 0 )
goto fail;
ret = i2c_read( vpout, vpout_draw, port, vpout->hdmi[port].device.tfp410ep.bus, vpout->hdmi[port].device.tfp410ep.speed,
vpout->hdmi[port].device.tfp410ep.address, reg + 1, &val[1], 1 );
if ( ret < 0 )
goto fail;
return (uint16_t)val[0] | ((uint16_t)val[1] << 8);
fail:
disp_printf( adapter, "[vpoutfb: tfp410ep] Fatal: I2C HDMI controller register reading failed [I2C issue: port=%d, register=0x%x, status=%d]", port, reg, ret );
return (0);
}
/*************************************************/
/* INTERFACE FUNCTIONS */
/*************************************************/
void tfp410ep_probe( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index )
{
disp_adapter_t *adapter = vpout->adapter;
if ( i2c_init( vpout, vpout_draw, vpout->hdmi[port_index].device.tfp410ep.bus, port_index ) )
{
disp_printf( adapter, "[vpoutfb: tfp410ep] Fatal: I2C HDMI controller initialization failed [I2C issue: port=%d]", port_index );
return;
}
}
void tfp410ep_reset( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index )
{
}
void tfp410ep_remove( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index )
{
i2c_fini( vpout, vpout_draw, port_index );
}
int tfp410ep_init( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, uint32_t pixel_clock )
{
disp_adapter_t *adapter = vpout->adapter;
uint16_t vid = 0,
did = 0,
rev = 0;
/* Device detection */
vid = reg_read16( vpout, vpout_draw, port_index, REGISTER_VEN_ID );
did = reg_read16( vpout, vpout_draw, port_index, REGISTER_DEV_ID );
rev = reg_read8( vpout, vpout_draw, port_index, REGISTER_REV_ID );
if ( (vid == TFP410EP_VID) && (did == TFP410EP_DID) )
disp_printf( adapter, "[vpoutfb: tfp410ep] Info: TFP410-EP transmitter detected (%x:%x:%d)", vid, did, rev );
else {
disp_printf( adapter, "[vpoutfb: tfp410ep] Fatal: I2C HDMI controller initialization failed [found unsupported device: %x:%x]", vid, did );
goto fail;
}
return (0);
fail:
return (-1);
}
void tfp410ep_encoder_mode_set( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, disp_crtc_settings_t *settings )
{
/* Enable transmitter 0xbe -> 0xbf */
reg_write8( vpout, vpout_draw, port_index, REGISTER_CTL_1_MODE, 0xb7 /* RIMR device only (default 0xbf)? */ );
/* Enable data deskew 0x80 -> 0x90 */
reg_write8( vpout, vpout_draw, port_index, REGISTER_CTL_3_MODE, 0x10 );
}
int tfp410ep_read_edid( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, uint8_t *buf, int size_ )
{
disp_adapter_t *adapter = vpout->adapter;
int ddc_bus = vpout->hdmi[port_index].device.tfp410ep.ddc_bus,
ddc_port = port_index + 1,
ddc_slave = vpout->hdmi[port_index].device.tfp410ep.ddc_slave,
ret = -1;
if ( size_ != 256 )
return (-1);
if ( i2c_init( vpout, vpout_draw, ddc_bus, ddc_port ) < 0 )
{
disp_printf( adapter, "[vpoutfb: tfp410ep] Error: DDC bus detection failed (bus: %d)", ddc_bus );
goto done;
}
if ( i2c_read( vpout, vpout_draw, ddc_port, ddc_bus, 0, ddc_slave, 0, (uint8_t *)buf, size_ ) != 0 )
{
disp_printf( adapter, "[vpoutfb: tfp410ep] Error: DDC bus reading failed (bus:%d, slave: 0x%x)", ddc_bus, ddc_slave );
goto done;
} else
ret = size_;
done:
i2c_fini( vpout, vpout_draw, ddc_port );
return ret;
}

398
devg/vpoutfb/vpout.c Обычный файл
Просмотреть файл

@ -0,0 +1,398 @@
/*
* (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include "vpoutfb.h"
/*************************************************/
/* DEFINITIONS */
/*************************************************/
/* Hardware definitions */
#define UNDIVPIXCLK 2315 /* UNDIVPIXCLK is undivided pixclock in picoseconds for 432MHz */
#define CLEAR_MSEC 40 /* FIFO clear delay (ms) */
/* Misc definitions */
#define DIV_ROUND_CLOSEST( x, divisor ) ({ typeof( divisor ) __divisor = divisor; (((x) + ((__divisor) / 2)) / (__divisor)); })
/*************************************************/
/* MISC FUNCTIONS */
/*************************************************/
/* Hz to picoseconds */
static inline uint32_t hz_to_ps( uint32_t rate )
{
uint32_t ps_in_us = 1000000;
/* convert to times / microsecond */
rate /= 1000000;
return ps_in_us / rate;
}
/* APLL frequency in Hz */
static inline uint32_t get_apll_frequency( vpout_context_t *vpout )
{
/* Same as CPLL */
return ((*CMCTR_MMIO32( SEL_CPLL ) & SEL_CPLL_SEL) + 1) * VPOUT_XTI_FREQUENCY * 1000 * 1000;
}
/*************************************************/
/* FUNCTIONS */
/*************************************************/
struct sigevent * vpout_hw_isr( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw )
{
uint32_t status = *MMIO32( LCDINT );
if ( status & INTERRUPT_OUT_FIFO )
{
uint32_t i, j;
/* Reset VPOUT display controller */
for (j = 0; j < 2; j++)
{
*MMIO32( LCDCSR ) = CSR_EN;
*MMIO32( LCDCSR ) = CSR_INIT | CSR_EN;
for ( i = 0; i < 250; i++ )
{
if ( !(*MMIO32( LCDCSR ) & CSR_INIT) )
break;
disp_usecspin( 1000 );
}
if ( i == 250 )
vpout->error_reset_counter++;
}
*MMIO32( LCDCSR ) = CSR_RUN | CSR_EN;
vpout->error_counter++;
}
/* Clear IRQ source */
*MMIO32( LCDINT ) = status;
if ( status & INTERRUPT_SYNC_DONE )
{
/* Update counter */
vpout->vsync_counter[0 /*dispno*/]++;
return &vpout->irq_event;
}
return (NULL);
}
void vpout_hw_pipe_wait_for_vblank( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, int pipe )
{
disp_adapter_t *adapter = vpout->adapter;
uint32_t counter = 50 /* 50 ms */;
/* Clear previous VSYNC IRQ */
*MMIO32( LCDINT ) |= INTERRUPT_SYNC_DONE;
while ( counter )
{
if ( *MMIO32( LCDINT ) & INTERRUPT_SYNC_DONE )
{
*MMIO32( LCDINT ) |= INTERRUPT_SYNC_DONE;
return;
}
disp_usecspin( 1000 );
counter--;
}
disp_printf_warning( adapter, "[vpout] Warning: pipe %d vsync timeout", pipe );
}
void vpout_hw_disable( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw )
{
disp_adapter_t *adapter = vpout->adapter;
int i, pipe = 0;
/* Mask all IRQs */
*MMIO32( LCDINTMASK ) = 0;
/* If the device is currently on, clear FIFO and power it off */
if ( *MMIO32( LCDCSR ) & CSR_EN )
{
*MMIO32( LCDCSR ) = CSR_EN;
*MMIO32( LCDCSR ) = CSR_EN | CSR_CLR;
for ( i = 0; i < CLEAR_MSEC; i++ )
{
if ( !(*MMIO32( LCDCSR ) & CSR_CLR) )
break;
disp_usecspin( 1000 );
}
if ( i == CLEAR_MSEC )
disp_printf_warning( adapter, "[vpoutfb] Warning: LCD disable sequence failed [FIFO clear timeout]" );
*MMIO32( LCDCSR ) = 0;
}
/* vpoutfb_clocks_destroy() */
//~ *CMCTR_MMIO32( GATE_CORE_CTR ) &= ~VPOUT_EN;
/* Reset HDMI device */
for ( pipe = 0; pipe < VPOUT_GPU_PIPES; pipe++ )
if ( DISPLAY_PORT( vpout->display[pipe] ) == DISPLAY_PORT_TYPE_HDMI )
{
/* IT66121 HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( vpout->display[pipe] )].transmitter, VPOUT_OPT_HDMI_IT66121 ) == 0 )
{
it66121_reset( vpout, vpout_draw, DISPLAY_PORT_INDEX( vpout->display[pipe] ) );
it66121_remove( vpout, vpout_draw, DISPLAY_PORT_INDEX( vpout->display[pipe] ) );
}
/* TDA998x HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( vpout->display[pipe] )].transmitter, VPOUT_OPT_HDMI_TDA998x ) == 0 )
tda998x_remove( vpout, vpout_draw, DISPLAY_PORT_INDEX( vpout->display[pipe] ) );
/* TFP410EP HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( vpout->display[pipe] )].transmitter, VPOUT_OPT_HDMI_TFP410EP ) == 0 )
tfp410ep_remove( vpout, vpout_draw, DISPLAY_PORT_INDEX( vpout->display[pipe] ) );
}
}
void vpout_hw_pipe_set_display_offset( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, int pipe, uint32_t offset )
{
*MMIO32( LCDAB0 ) = offset;
*MMIO32( LCDAB1 ) = offset;
}
int vpout_hw_configure_display( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, disp_crtc_settings_t *settings,
vpout_display_conf_t display, int pipe, disp_surface_t *surface, disp_mode_t mode_ )
{
disp_adapter_t *adapter = vpout->adapter;
uint32_t mode = 0;
int hsw, hgdel, hgate, hlen, vsw, vgdel, vgate, vlen, div, i, undiv;
disp_printf_info( adapter, "[vpout] Info: %s[%d] mode set sequence started [%d:%d@%d %dbpp]",
DISPLAY_PORT_NAME( display ), DISPLAY_PORT_INDEX( display ), vpout->xres, vpout->yres, vpout->refresh, vpout->bpp );
/* vpoutfb_clocks_init() */
//~ *CMCTR_MMIO32( GATE_CORE_CTR ) |= VPOUT_EN;
/* Prepare HDMI port */
if ( DISPLAY_PORT( display ) == DISPLAY_PORT_TYPE_HDMI )
{
/* IT66121 HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( display )].transmitter, VPOUT_OPT_HDMI_IT66121 ) == 0 )
it66121_probe( vpout, vpout_draw, DISPLAY_PORT_INDEX( display ) );
/* TDA998x HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( display )].transmitter, VPOUT_OPT_HDMI_TDA998x ) == 0 )
tda998x_probe( vpout, vpout_draw, DISPLAY_PORT_INDEX( display ) );
/* TFP410EP HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( display )].transmitter, VPOUT_OPT_HDMI_TFP410EP ) == 0 )
tfp410ep_probe( vpout, vpout_draw, DISPLAY_PORT_INDEX( display ) );
}
/* vpoutfb_set_par() */
/* If the device is currently on, clear FIFO and power it off */
if ( *MMIO32( LCDCSR ) & CSR_EN )
{
*MMIO32( LCDCSR ) = CSR_EN;
*MMIO32( LCDCSR ) = CSR_EN | CSR_CLR;
for ( i = 0; i < CLEAR_MSEC; i++ )
{
if ( !(*MMIO32( LCDCSR ) & CSR_CLR) )
break;
disp_usecspin( 1000 );
}
if ( i == CLEAR_MSEC )
{
disp_printf( adapter, "[vpoutfb] Fatal: HDMI mode set sequence failed [FIFO clear timeout]" );
return (-EBUSY);
}
*MMIO32( LCDCSR ) = 0;
}
/* Turn on and reset the device */
*MMIO32( LCDCSR ) = CSR_EN;
*MMIO32( LCDCSR ) = CSR_EN | CSR_CLR;
for ( i = 0; i < CLEAR_MSEC; i++ )
{
if ( !(*MMIO32( LCDCSR ) & CSR_CLR) )
break;
disp_usecspin( 1000 );
}
if ( i == CLEAR_MSEC )
{
disp_printf( adapter, "[vpoutfb] Fatal: HDMI mode set sequence failed [LCD reset timeout]" );
return (-EBUSY);
}
/* Configure video mode */
hsw = settings->h_sync_len - 1;
vsw = settings->v_sync_len - 1;
hgate = settings->xres - 1;
vgate = settings->yres - 1;
hgdel = settings->h_total - settings->h_sync_start - settings->h_sync_len - 1;
vgdel = settings->v_total - settings->v_sync_start - settings->v_sync_len - 1;
hlen = settings->h_total - 1;
vlen = settings->v_total - 1;
#ifdef __QNX__
undiv = hz_to_ps( get_apll_frequency( vpout ) );
div = DIV_ROUND_CLOSEST( hz_to_ps( settings->pixel_clock * 1000 ), undiv ) - 1;
#else
if ( par->clk_count == 2 )
undiv = hz_to_ps( get_apll_frequency( vpout ) );
else
undiv = UNDIVPIXCLK;
div = DIV_ROUND_CLOSEST( hz_to_ps( settings->pixel_clock ), undiv ) - 1;
#endif
*MMIO32( LCDHT0 ) = ((hgdel << LCDHT0_HGDEL_SHIFT) & LCDHT0_HGDEL_MASK) |
((hsw << LCDHT0_HSW_SHIFT) & LCDHT0_HSW_MASK);
*MMIO32( LCDHT1 ) = ((hlen << LCDHT1_HLEN_SHIFT) & LCDHT1_HLEN_MASK) |
((hgate << LCDHT1_HGATE_SHIFT) & LCDHT1_HGATE_MASK);
*MMIO32( LCDVT0 ) = ((vgdel << LCDHT1_VGDEL_SHIFT) & LCDHT1_VGDEL_MASK) |
((vsw << LCDHT1_VSW_SHIFT) & LCDHT1_VSW_MASK);
*MMIO32( LCDVT1 ) = ((vlen << LCDHT1_VLEN_SHIFT) & LCDHT1_VLEN_MASK) |
((vgate << LCDHT1_VGATE_SHIFT) & LCDHT1_VGATE_MASK);
*MMIO32( LCDDIV ) = div;
*MMIO32( LCDAB0 ) = surface->offset;
*MMIO32( LCDAB1 ) = surface->offset;
*MMIO32( LCDOF0 ) = 0;
*MMIO32( LCDOF1 ) = 0;
/* Setup LCD display controller mode */
#if 0
if ( DISPLAY_PORT( display ) == DISPLAY_PORT_TYPE_HDMI )
mode = LCDMODE_VINV | LCDMODE_HINV;
#else
if ( VPOUT_LCD_SYNC_FIX( vpout ) )
mode = (settings->flags & DISP_SYNC_POLARITY_H_POS ? LCDMODE_HINV : 0) |
(settings->flags & DISP_SYNC_POLARITY_V_POS ? 0 : LCDMODE_VINV);
else
mode = (settings->flags & DISP_SYNC_POLARITY_H_POS ? 0 : LCDMODE_HINV) |
(settings->flags & DISP_SYNC_POLARITY_V_POS ? 0 : LCDMODE_VINV);
#endif
switch( surface->pixel_format )
{
case DISP_SURFACE_FORMAT_BYTES:
mode |= LCDMODE_INSIZE_RGB332;
break;
case DISP_SURFACE_FORMAT_PAL8:
mode |= LCDMODE_INSIZE_INDEXED_8BIT;
break;
case DISP_SURFACE_FORMAT_ARGB1555:
mode |= LCDMODE_INSIZE_ARGB1555;
mode |= LCDMODE_CCM;
break;
case DISP_SURFACE_FORMAT_RGB565:
mode |= LCDMODE_INSIZE_RGB565;
mode |= LCDMODE_CCM;
break;
case DISP_SURFACE_FORMAT_RGB888:
mode |= LCDMODE_INSIZE_RGB888;
break;
default:
case DISP_SURFACE_FORMAT_ARGB8888:
mode |= LCDMODE_INSIZE_ARGB8888;
break;
}
*MMIO32( LCDMODE ) = mode;
/* Unmask and clear IRQ source */
#ifdef ENABLE_IRQ
*MMIO32( LCDINT ) = INTERRUPT_SYNC_DONE | INTERRUPT_OUT_FIFO;
*MMIO32( LCDINTMASK ) = INTERRUPT_SYNC_DONE | INTERRUPT_OUT_FIFO;
#else
*MMIO32( LCDINTMASK ) = 0;
#endif
/* Finally, initialize and run the device */
*MMIO32( LCDCSR ) = CSR_INIT | CSR_EN;
for ( i = 0; i < CLEAR_MSEC; i++ )
{
if ( !(*MMIO32( LCDCSR ) & CSR_INIT) )
break;
disp_usecspin( 1000 );
}
if ( i == CLEAR_MSEC )
{
disp_printf( adapter, "[vpoutfb] Fatal: HDMI mode set sequence failed [timeout]" );
return (-EBUSY);
}
*MMIO32( LCDCSR ) = CSR_RUN | CSR_EN;
if ( DISPLAY_PORT( display ) == DISPLAY_PORT_TYPE_HDMI )
{
/* IT66121 HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( display )].transmitter, VPOUT_OPT_HDMI_IT66121 ) == 0 )
return it66121_init( vpout, vpout_draw, DISPLAY_PORT_INDEX( display ), hz_to_ps( settings->pixel_clock * 1000 ) );
/* TDA998x HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( display )].transmitter, VPOUT_OPT_HDMI_TDA998x ) == 0 )
{
if ( !tda998x_init( vpout, vpout_draw, DISPLAY_PORT_INDEX( display ), hz_to_ps( settings->pixel_clock * 1000 ) ) )
tda998x_encoder_mode_set( vpout, vpout_draw, DISPLAY_PORT_INDEX( display ), settings );
else
return (-1);
}
/* TFP410EP HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( display )].transmitter, VPOUT_OPT_HDMI_TFP410EP ) == 0 )
{
if ( !tfp410ep_init( vpout, vpout_draw, DISPLAY_PORT_INDEX( display ), hz_to_ps( settings->pixel_clock * 1000 ) ) )
tfp410ep_encoder_mode_set( vpout, vpout_draw, DISPLAY_PORT_INDEX( display ), settings );
else
return (-1);
}
}
return (0);
}
int vpout_hw_read_edid( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, int dispno, uint8_t *buf, int size )
{
vpout_display_conf_t display = vpout->display[dispno];
if ( DISPLAY_PORT( display ) == DISPLAY_PORT_TYPE_HDMI )
{
/* IT66121 HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( display )].transmitter, VPOUT_OPT_HDMI_IT66121 ) == 0 )
goto fail;
/* TDA998x HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( display )].transmitter, VPOUT_OPT_HDMI_TDA998x ) == 0 )
return tda998x_read_edid( vpout, vpout_draw, DISPLAY_PORT_INDEX( display ), buf, size );
/* TFP410EP HDMI transmitter */
if ( strcmp( vpout->hdmi[DISPLAY_PORT_INDEX( display )].transmitter, VPOUT_OPT_HDMI_TFP410EP ) == 0 )
return tfp410ep_read_edid( vpout, vpout_draw, DISPLAY_PORT_INDEX( display ), buf, size );
}
fail:
/* EDID reading not supported */
return (-1);
}

196
devg/vpoutfb/vpout_regs.h Обычный файл
Просмотреть файл

@ -0,0 +1,196 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* COMMON REGISTERS */
/* Elvees 1892VM14YA ARMv7 SoC (VPOUT DC) */
/*************************************************/
/*************************************************/
/* Registers base */
/*************************************************/
/* Synchronization interface controller (CMCTR) */
#define CMCTR_REGISTERS_BASE 0x38094000
#define CMCTR_REGISTERS_SIZE 0x1000
/* GPIO interface */
#define GPIO_REGISTERS_SIZE 0x1000
/*************************************************/
/* Registers interface */
/*************************************************/
/* Common registers interface */
#define MMIO64( offset ) ((volatile uint64_t *)(vpout_draw->registers + (offset)))
#define MMIO32( offset ) ((volatile uint32_t *)(vpout_draw->registers + (offset)))
/* CMCTR registers interface */
#define CMCTR_MMIO64( offset ) ((uint64_t *)(vpout->cmctr_registers + (offset)))
#define CMCTR_MMIO32( offset ) ((uint32_t *)(vpout->cmctr_registers + (offset)))
/* GPIO registers interface */
#define GPIO_MMIO64( base, offset ) ((uint64_t *)(base + (offset)))
#define GPIO_MMIO32( base, offset ) ((uint32_t *)(base + (offset)))
/*************************************************/
/* Display (LCD) controller registers */
/*************************************************/
#define LCDCSR (0x00) /* LCD control and status */
#define CSR_CLR (1 << 3)
#define CSR_INIT (1 << 2)
#define CSR_RUN (1 << 1)
#define CSR_EN (1 << 0)
#define LCDDIV (0x04) /* ACLK pixel clock divider */
#define LCDMODE (0x08)
#define LCDMODE_CLK_ON (1 << 17)
#define LCDMODE_VDEF (1 << 16)
#define LCDMODE_HDEF (1 << 15)
#define LCDMODE_DEN_EN (1 << 14)
#define LCDMODE_INSYNC (1 << 13)
#define LCDMODE_CCM (1 << 12)
#define LCDMODE_PINV (1 << 11)
#define LCDMODE_DINV (1 << 10)
#define LCDMODE_VINV (1 << 9)
#define LCDMODE_HINV (1 << 8)
#define LCDMODE_BUF_NUMB (1 << 7)
#define LCDMODE_BUF_MODE (1 << 6)
#define LCDMODE_HWC_MODE (1 << 5) /* Hardware cursor mode */
#define LCDMODE_HWC_MODE_32x32 (0 << 5)
#define LCDMODE_HWC_MODE_64x64 (1 << 5)
#define LCDMODE_HWCEN (1 << 4) /* Enable hardware cursor */
#define LCDMODE_INSIZE (0xf << 0)
#define LCDMODE_INSIZE_RGB332 (0 << 0)
#define LCDMODE_INSIZE_RGB444 (1 << 0)
#define LCDMODE_INSIZE_ARGB1555 (2 << 0)
#define LCDMODE_INSIZE_RGB565 (3 << 0)
#define LCDMODE_INSIZE_18bpp (4 << 0)
#define LCDMODE_INSIZE_RGB888 (5 << 0)
#define LCDMODE_INSIZE_ARGB8888 (6 << 0)
#define LCDMODE_INSIZE_INDEXED_1BIT (8 << 0)
#define LCDMODE_INSIZE_INDEXED_2BIT (9 << 0)
#define LCDMODE_INSIZE_INDEXED_4BIT (10 << 0)
#define LCDMODE_INSIZE_INDEXED_8BIT (11 << 0)
#define LCDHT0 (0x0c) /* LCD horizontal timings */
#define LCDHT0_HGDEL_MASK (0xffff << 16)
#define LCDHT0_HGDEL_SHIFT (16)
#define LCDHT0_HSW_MASK (0xffff << 0)
#define LCDHT0_HSW_SHIFT (0)
#define LCDHT1 (0x10) /* LCD horizontal timings */
#define LCDHT1_HLEN_MASK (0xffff << 16)
#define LCDHT1_HLEN_SHIFT (16)
#define LCDHT1_HGATE_MASK (0xffff << 0)
#define LCDHT1_HGATE_SHIFT (0)
#define LCDVT0 (0x14) /* LCD vertical timings */
#define LCDHT1_VGDEL_MASK (0xffff << 16)
#define LCDHT1_VGDEL_SHIFT (16)
#define LCDHT1_VSW_MASK (0xffff << 0)
#define LCDHT1_VSW_SHIFT (0)
#define LCDVT1 (0x18) /* LCD vertical timings */
#define LCDHT1_VLEN_MASK (0xffff << 16)
#define LCDHT1_VLEN_SHIFT (16)
#define LCDHT1_VGATE_MASK (0xffff << 0)
#define LCDHT1_VGATE_SHIFT (0)
#define LCDXY (0x1c)
#define LCDXYP (0x20)
#define LCDCOLOR0 (0x24)
#define LCDCOLOR1 (0x28)
#define LCDAB0 (0x2c) /* LCD primary buffer address */
#define LCDAB1 (0x30) /* LCD secondary buffer address */
#define LCDOF0 (0x34) /* LCD primary buffer stride (64b aligned) */
#define LCDOF1 (0x38) /* LCD secondary buffer stride (64b aligned) */
#define LCDINT (0x44) /* LCD interrupt control */
#define LCDINTMASK (0x48) /* LCD interrupt mask */
#define INTERRUPT_SYNC_DONE (1 << 5) /* VSYNC IRQ */
#define INTERRUPT_OUT_FIFO_EMPTY (1 << 3)
#define INTERRUPT_OUT_FIFO (1 << 2)
#define INTERRUPT_DMA_FIFO_EMPTY (1 << 1)
#define INTERRUPT_DMA_DONE (1 << 0)
#define HWC_MEM (0x400)
#define PAL_MEM (0x800) /* Palette memory offset */
/*************************************************/
/* CMCTR registers */
/*************************************************/
#define GATE_CORE_CTR (0x48) /* Frequency disable register for CMCTR_CORE */
#define VPOUT_EN (1 << 4) /* Frequency enable bit for VPOUT, VPOUT_PCLK, VPOUT_ACLK */
#define SEL_CPLL (0x104) /* CPLL control register */
#define SEL_CPLL_LOCK (1 << 31)
#define SEL_CPLL_SEL (0xff << 0)
#define SEL_SPLL (0x10c) /* SPLL control register */
#define SEL_SPLL_LOCK (1 << 31)
#define SEL_SPLL_SEL (0xff << 0)
/*************************************************/
/* GPIO registers */
/*************************************************/
#define GPIO_SWPORTA_DR (0x00)
#define GPIO_SWPORTB_DR (0x0C)
#define GPIO_SWPORTC_DR (0x18)
#define GPIO_SWPORTD_DR (0x24)
#define GPIO_SWPORTA_DDR (0x04)
#define GPIO_SWPORTB_DDR (0x10)
#define GPIO_SWPORTC_DDR (0x1C)
#define GPIO_SWPORTD_DDR (0x28)
#define GPIO_SWPORTA_CTL (0x08)
#define GPIO_SWPORTB_CTL (0x14)
#define GPIO_SWPORTC_CTL (0x20)
#define GPIO_SWPORTD_CTL (0x2C)
/*************************************************/
/* ITE IT66121 I2C HDMI controller registers */
/*************************************************/
#define REG_RESET (0x04)
#define RESET_RCLK_MASK (1 << 5)
#define RESET_AUDIO_MASK (1 << 4)
#define RESET_VIDEO_MASK (1 << 3)
#define RESET_AFIFO_MASK (1 << 2)
#define RESET_HDCP_MASK (1 << 0)
#define REG_IRQ_FIRST (0x09)
#define REG_IRQ_LAST (0x0B)
#define REG_BANK_SW (0x0F)
#define REG_TX_RESET (0x61)
#define REG_CLK1 (0x62)
#define REG_CLK2 (0x63)
#define REG_CLK3 (0x64)
#define REG_TXFIFO_SET (0x71)
#define REG_AVMUTE (0xC1)

313
devg/vpoutfb/vpoutfb.h Обычный файл
Просмотреть файл

@ -0,0 +1,313 @@
/*
* (c) 2020, SWD Embedded Systems Limited, http://www.kpda.ru
*/
/*************************************************/
/* HEADERS */
/*************************************************/
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <graphics/vbios.h>
#include <graphics/display.h>
#include <graphics/disputil.h>
#include <graphics/extra/devctl.h>
#include <graphics/ffb.h>
#include <graphics/rop.h>
#include <sys/time.h>
#include <hw/inout.h>
#include <drm/drm_edid.h>
/*************************************************/
/* REGISTERS */
/*************************************************/
#include "vpout_regs.h"
/*************************************************/
/* DEBUG DEFINITIONS */
/*************************************************/
#define VPOUT_SLOG_LEVEL_0 0
#define VPOUT_SLOG_LEVEL_INFO 1
#define VPOUT_SLOG_LEVEL_WARNING 2
#define VPOUT_SLOG_LEVEL_DEBUG 3
extern int verbose;
#ifdef disp_printf_debug
#undef disp_printf_debug
#endif
#define disp_printf_debug if ( verbose >= VPOUT_SLOG_LEVEL_DEBUG ) disp_printf
#define disp_printf_info if ( verbose >= VPOUT_SLOG_LEVEL_INFO ) disp_printf
#define disp_printf_warning if ( verbose >= VPOUT_SLOG_LEVEL_WARNING ) disp_printf
#define DEBUG ( verbose >= VPOUT_SLOG_LEVEL_DEBUG )
#define INFO ( verbose >= VPOUT_SLOG_LEVEL_INFO )
#define WARNING ( verbose >= VPOUT_SLOG_LEVEL_WARNING )
/*************************************************/
/* COMPILE OPTIONS */
/*************************************************/
/* Enable IRQs support */
#define ENABLE_IRQ
/* Compile with hw-cursor support */
#define ENABLE_HW_CURSOR
/* Compile with DDC support */
#define ENABLE_DDC
/* Compile with "display-info" utility support */
#define ENABLE_DISPLAY_INFO
/*************************************************/
/* HW DEFINITIONS */
/*************************************************/
#define VPOUT_GPU_PIPES 1
#define VPOUT_GPU_LAYERS 1
#define VPOUT_HDMI_PORTS 1
#define VPOUT_DSI_PORTS 1
#define VPOUT_PORTS 2
#define VPOUT_HW_PAGESIZE 4096
#define VPOUT_HW_PRIMARY_SURFACE_SIZE 0x4000000
#define VPOUT_HW_CURSOR_64x64x2_SIZE (64 * 64 * 2) /* 2 pages (64x64 2bpp) */
#define VPOUT_HW_CURSOR_SIZE VPOUT_HW_CURSOR_64x64x2_SIZE
#define ALIGN_64BIT( x ) (((x) + 0x3f) & ~0x3f)
#define VPOUT_XTI_FREQUENCY 24 /* MHz */
/*************************************************/
/* CONFIGURATION */
/*************************************************/
/* vpoutfb.conf::dispmode */
#define VPOUT_DISPMODE_BAD_PIPE( pipe ) (pipe > 0)
#define VPOUT_DISPMODE_LAST_PIPE( pipe ) (pipe == 0)
/* vpoutfb.conf::hdmi */
#define CONFIG_DISPLAY_PORT_TYPE_MASK (0xf)
#define CONFIG_DISPLAY_PORT_TYPE_SHIFT (0)
#define DISPLAY_PORT_TYPE_DSI (0)
#define DISPLAY_PORT_TYPE_HDMI (1)
#define CONFIG_DISPLAY_PORT_TYPE_DSI (DISPLAY_PORT_TYPE_DSI << CONFIG_DISPLAY_PORT_TYPE_SHIFT)
#define CONFIG_DISPLAY_PORT_TYPE_HDMI (DISPLAY_PORT_TYPE_HDMI << CONFIG_DISPLAY_PORT_TYPE_SHIFT)
#define DISPLAY_PORT( config ) ((config & CONFIG_DISPLAY_PORT_TYPE_MASK) >> CONFIG_DISPLAY_PORT_TYPE_SHIFT)
#define DISPLAY_PORT_NAME( config ) ((config & CONFIG_DISPLAY_PORT_TYPE_MASK) == DISPLAY_PORT_TYPE_HDMI ? "HDMI" : "DSI")
#define CONFIG_DISPLAY_PORT_INDEX_MASK (0xf0)
#define CONFIG_DISPLAY_PORT_INDEX_SHIFT (4)
#define DISPLAY_PORT_INDEX_0 (0)
#define DISPLAY_PORT_INDEX_1 (1)
#define CONFIG_DISPLAY_PORT_INDEX_0 (DISPLAY_PORT_INDEX_0 << CONFIG_DISPLAY_PORT_INDEX_SHIFT)
#define CONFIG_DISPLAY_PORT_INDEX_1 (DISPLAY_PORT_INDEX_1 << CONFIG_DISPLAY_PORT_INDEX_SHIFT)
#define DISPLAY_PORT_INDEX( config ) ((config & CONFIG_DISPLAY_PORT_INDEX_MASK) >> CONFIG_DISPLAY_PORT_INDEX_SHIFT)
/* vpoutfb.conf::hdmi display configurations */
#define CONFIG_DISPLAY_PORT_HDMI0 (CONFIG_DISPLAY_PORT_TYPE_HDMI | CONFIG_DISPLAY_PORT_INDEX_0)
/* vpoutfb.conf::enable */
#define CONFIG_ENABLE_LCD_SYNC_FIX (1)
#define VPOUT_LCD_SYNC_FIX( vpout ) (vpout->enabled & CONFIG_ENABLE_LCD_SYNC_FIX)
/*************************************************/
/* TYPES */
/*************************************************/
/* Display configuration mask: 0xff
|`-- display port type [HDMI, DSI]
`--- display port index [0, 1] */
typedef uint32_t vpout_display_conf_t;
typedef struct vpout_context
{
/* GPU adapter descriptor */
disp_adapter_t *adapter;
/* Hardware configuration */
uint16_t gpu_supported_pipes;
struct vpout_hdmi_transmitter
{
uint8_t assigned; /* Initialization flag */
char transmitter[64]; /* Transmitter name */
union vpout_hdmi_device
{
#define VPOUT_OPT_HDMI_IT66121 "IT66121"
struct vpout_hdmi_it66121
{
/* I2C */
uint8_t bus;
uint16_t address;
uint32_t speed;
/* GPIO */
uint8_t *registers;
uint64_t base;
uint8_t reg;
uint8_t pin;
} it66121;
#define VPOUT_OPT_HDMI_TDA998x "TDA998x"
struct vpout_hdmi_tda998x
{
/* I2C */
uint8_t bus;
uint16_t address;
uint32_t speed;
/* Private device data */
uint16_t revision;
bool is_hdmi_sink;
uint8_t current_page;
uint32_t video_ports;
uint8_t vip_cntrl_0;
uint8_t vip_cntrl_1;
uint8_t vip_cntrl_2;
} tda998x;
#define VPOUT_OPT_HDMI_TFP410EP "TFP410EP"
struct vpout_hdmi_tfp410ep
{
/* I2C */
uint8_t bus;
uint16_t address;
uint32_t speed;
/* DDC */
uint8_t ddc_bus;
uint16_t ddc_slave;
} tfp410ep;
} device;
} hdmi[VPOUT_HDMI_PORTS];
uint8_t hdmi_count; /* Current assigned HDMI ports count (see vpoutfb.conf::hdmi option) */
/* Driver configuration */
uint32_t enabled;
uint8_t display_count; /* Displays configuration (see vpoutfb.conf) */
vpout_display_conf_t display[VPOUT_PORTS]; /* Display port configuration (see vpoutfb.conf) */
/* [video ptr] MMIO registers */
uint8_t *registers;
uint64_t registers_base;
uint64_t registers_size;
uint8_t *cmctr_registers;
/* Custom mode switcher */
int xres;
int yres;
int bpp;
int refresh;
uint64_t display_paddr;
unsigned display_stride;
unsigned display_format;
/* IRQ processing */
uint8_t irq_polling;
uint32_t irq;
int irq_iid;
int irq_chid;
int irq_coid;
#define VBLANK_PULSE 0x5b /* VBLANK IRQ pulse code */
struct sigevent irq_event;
volatile uint32_t vsync_counter[VPOUT_GPU_PIPES]; /* VSYNC counter */
volatile uint32_t error_counter; /* Interrupt INTERRUPT_OUT_FIFO counter */
volatile uint32_t error_reset_counter; /* Sisplay controller failed reset counter */
/* Misc */
int context_allocated;
} vpout_context_t;
typedef struct vpout_draw_context
{
/* GPU context */
vpout_context_t *vpout;
/* [video ptr] MMIO registers */
uint8_t *registers; /* Device registers base pointer */
/* External attached process flag */
int external_process;
} vpout_draw_context_t;
/*************************************************/
/* PROTOTYPES */
/*************************************************/
/* init.c */
int vpout_init( disp_adapter_t *adapter, char *optstring );
void vpout_fini( disp_adapter_t *adapter );
/* misc.c */
int vpout_misc_wait_idle( disp_adapter_t *adapter );
int vpout_draw_init( disp_adapter_t *adapter, char *opt );
void vpout_draw_fini( disp_adapter_t *adapter );
void vpout_module_info( disp_adapter_t *adapter, disp_module_info_t *info );
int vpout_attach_external( disp_adapter_t *adapter, disp_aperture_t aper[] );
int vpout_detach_external( disp_adapter_t *adapter );
/* cursor.c */
void vpout_enable_hw_cursor( disp_adapter_t *adapter, int dispno );
void vpout_disable_hw_cursor( disp_adapter_t *adapter, int dispno );
void vpout_set_hw_cursor_pos( disp_adapter_t *adapter, int dispno, int x, int y );
int vpout_set_hw_cursor( disp_adapter_t *adapter, int dispno, uint8_t *bmp0, uint8_t *bmp1, unsigned color0, unsigned color1,
int hotspot_x, int hotspot_y, int size_x, int size_y, int bmp_stride );
/* vpout.c */
struct sigevent * vpout_hw_isr( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw );
void vpout_hw_pipe_wait_for_vblank( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, int pipe );
void vpout_hw_disable( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw );
void vpout_hw_pipe_set_display_offset( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, int pipe, uint32_t offset );
int vpout_hw_configure_display( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, disp_crtc_settings_t *settings,
vpout_display_conf_t display, int pipe, disp_surface_t *surface, disp_mode_t mode );
int vpout_hw_read_edid( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, int dispno, uint8_t *buf, int size );
/* i2c.c */
int i2c_read( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t bus, uint32_t speed, uint8_t addr, unsigned short offset, uint8_t *buf,
unsigned count );
int i2c_write( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port, uint8_t bus, uint32_t speed, uint8_t addr, unsigned short offset, uint8_t *buf,
unsigned count );
int i2c_init( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t bus_, uint8_t port );
void i2c_fini( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port );
/* it66121.c */
void it66121_probe( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index );
void it66121_reset( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index );
void it66121_remove( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index );
int it66121_init( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, uint32_t pixel_clock );
/* tda998x.c */
void tda998x_probe( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index );
void tda998x_reset( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index );
void tda998x_remove( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index );
int tda998x_init( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, uint32_t pixel_clock );
void tda998x_encoder_mode_set( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, disp_crtc_settings_t *settings );
int tda998x_read_edid( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, uint8_t *buf, int size );
/* tfp410ep.c */
void tfp410ep_probe( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index );
void tfp410ep_reset( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index );
void tfp410ep_remove( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index );
int tfp410ep_init( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, uint32_t pixel_clock );
void tfp410ep_encoder_mode_set( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, disp_crtc_settings_t *settings );
int tfp410ep_read_edid( vpout_context_t *vpout, vpout_draw_context_t *vpout_draw, uint8_t port_index, uint8_t *buf, int size );
/* options.c */
int parse_options( disp_adapter_t *adapter, vpout_context_t *vpout, char *filename );

11
devg/vpoutfb/vpoutfb.use Обычный файл
Просмотреть файл

@ -0,0 +1,11 @@
Graphics driver for Elvees 1892VM14YA ARMv7 SoC
Supported controllers: VPOUT display controller
Multiple displays support: no
Layers support: -
Acceleration support: -
Color depths support: 15, 16, 24, 32 (supported by the Mali-300 GPU)
Supported interfaces: HDMI (ITE-IT66121/NXP-TDA998x I2C HDMI controllers)
Compatibility: display-info, display-screenshot, ddc, umc