123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Copyright (C) 2019-2022 Bootlin
- * Author: Paul Kocialkowski <[email protected]>
- */
- #include <drm/drm_print.h>
- #include "logicvc_drm.h"
- #include "logicvc_layer.h"
- #include "logicvc_of.h"
- static struct logicvc_of_property_sv logicvc_of_display_interface_sv[] = {
- { "lvds-4bits", LOGICVC_DISPLAY_INTERFACE_LVDS_4BITS },
- { "lvds-3bits", LOGICVC_DISPLAY_INTERFACE_LVDS_3BITS },
- { },
- };
- static struct logicvc_of_property_sv logicvc_of_display_colorspace_sv[] = {
- { "rgb", LOGICVC_DISPLAY_COLORSPACE_RGB },
- { "yuv422", LOGICVC_DISPLAY_COLORSPACE_YUV422 },
- { "yuv444", LOGICVC_DISPLAY_COLORSPACE_YUV444 },
- { },
- };
- static struct logicvc_of_property_sv logicvc_of_layer_colorspace_sv[] = {
- { "rgb", LOGICVC_LAYER_COLORSPACE_RGB },
- { "yuv", LOGICVC_LAYER_COLORSPACE_YUV },
- { },
- };
- static struct logicvc_of_property_sv logicvc_of_layer_alpha_mode_sv[] = {
- { "layer", LOGICVC_LAYER_ALPHA_LAYER },
- { "pixel", LOGICVC_LAYER_ALPHA_PIXEL },
- { },
- };
- static struct logicvc_of_property logicvc_of_properties[] = {
- [LOGICVC_OF_PROPERTY_DISPLAY_INTERFACE] = {
- .name = "xylon,display-interface",
- .sv = logicvc_of_display_interface_sv,
- .range = {
- LOGICVC_DISPLAY_INTERFACE_LVDS_4BITS,
- LOGICVC_DISPLAY_INTERFACE_LVDS_3BITS,
- },
- },
- [LOGICVC_OF_PROPERTY_DISPLAY_COLORSPACE] = {
- .name = "xylon,display-colorspace",
- .sv = logicvc_of_display_colorspace_sv,
- .range = {
- LOGICVC_DISPLAY_COLORSPACE_RGB,
- LOGICVC_DISPLAY_COLORSPACE_YUV444,
- },
- },
- [LOGICVC_OF_PROPERTY_DISPLAY_DEPTH] = {
- .name = "xylon,display-depth",
- .range = { 8, 24 },
- },
- [LOGICVC_OF_PROPERTY_ROW_STRIDE] = {
- .name = "xylon,row-stride",
- },
- [LOGICVC_OF_PROPERTY_DITHERING] = {
- .name = "xylon,dithering",
- .optional = true,
- },
- [LOGICVC_OF_PROPERTY_BACKGROUND_LAYER] = {
- .name = "xylon,background-layer",
- .optional = true,
- },
- [LOGICVC_OF_PROPERTY_LAYERS_CONFIGURABLE] = {
- .name = "xylon,layers-configurable",
- .optional = true,
- },
- [LOGICVC_OF_PROPERTY_LAYERS_COUNT] = {
- .name = "xylon,layers-count",
- },
- [LOGICVC_OF_PROPERTY_LAYER_DEPTH] = {
- .name = "xylon,layer-depth",
- .range = { 8, 24 },
- },
- [LOGICVC_OF_PROPERTY_LAYER_COLORSPACE] = {
- .name = "xylon,layer-colorspace",
- .sv = logicvc_of_layer_colorspace_sv,
- .range = {
- LOGICVC_LAYER_COLORSPACE_RGB,
- LOGICVC_LAYER_COLORSPACE_RGB,
- },
- },
- [LOGICVC_OF_PROPERTY_LAYER_ALPHA_MODE] = {
- .name = "xylon,layer-alpha-mode",
- .sv = logicvc_of_layer_alpha_mode_sv,
- .range = {
- LOGICVC_LAYER_ALPHA_LAYER,
- LOGICVC_LAYER_ALPHA_PIXEL,
- },
- },
- [LOGICVC_OF_PROPERTY_LAYER_BASE_OFFSET] = {
- .name = "xylon,layer-base-offset",
- },
- [LOGICVC_OF_PROPERTY_LAYER_BUFFER_OFFSET] = {
- .name = "xylon,layer-buffer-offset",
- },
- [LOGICVC_OF_PROPERTY_LAYER_PRIMARY] = {
- .name = "xylon,layer-primary",
- .optional = true,
- },
- };
- static int logicvc_of_property_sv_value(struct logicvc_of_property_sv *sv,
- const char *string, u32 *value)
- {
- unsigned int i = 0;
- while (sv[i].string) {
- if (!strcmp(sv[i].string, string)) {
- *value = sv[i].value;
- return 0;
- }
- i++;
- }
- return -EINVAL;
- }
- int logicvc_of_property_parse_u32(struct device_node *of_node,
- unsigned int index, u32 *target)
- {
- struct logicvc_of_property *property;
- const char *string;
- u32 value;
- int ret;
- if (index >= LOGICVC_OF_PROPERTY_MAXIMUM)
- return -EINVAL;
- property = &logicvc_of_properties[index];
- if (!property->optional &&
- !of_property_read_bool(of_node, property->name))
- return -ENODEV;
- if (property->sv) {
- ret = of_property_read_string(of_node, property->name, &string);
- if (ret)
- return ret;
- ret = logicvc_of_property_sv_value(property->sv, string,
- &value);
- if (ret)
- return ret;
- } else {
- ret = of_property_read_u32(of_node, property->name, &value);
- if (ret)
- return ret;
- }
- if (property->range[0] || property->range[1])
- if (value < property->range[0] || value > property->range[1])
- return -ERANGE;
- *target = value;
- return 0;
- }
- void logicvc_of_property_parse_bool(struct device_node *of_node,
- unsigned int index, bool *target)
- {
- struct logicvc_of_property *property;
- if (index >= LOGICVC_OF_PROPERTY_MAXIMUM) {
- /* Fallback. */
- *target = false;
- return;
- }
- property = &logicvc_of_properties[index];
- *target = of_property_read_bool(of_node, property->name);
- }
- bool logicvc_of_node_is_layer(struct device_node *of_node)
- {
- return !of_node_cmp(of_node->name, "layer");
- }
|