// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019-2022 Bootlin
* Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
*/
#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" );
}
Messung V0.5 C=92 H=96 G=93
¤ Dauer der Verarbeitung: 0.2 Sekunden
¤
*© Formatika GbR, Deutschland