logicvc_of.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2019-2022 Bootlin
  4. * Author: Paul Kocialkowski <[email protected]>
  5. */
  6. #include <drm/drm_print.h>
  7. #include "logicvc_drm.h"
  8. #include "logicvc_layer.h"
  9. #include "logicvc_of.h"
  10. static struct logicvc_of_property_sv logicvc_of_display_interface_sv[] = {
  11. { "lvds-4bits", LOGICVC_DISPLAY_INTERFACE_LVDS_4BITS },
  12. { "lvds-3bits", LOGICVC_DISPLAY_INTERFACE_LVDS_3BITS },
  13. { },
  14. };
  15. static struct logicvc_of_property_sv logicvc_of_display_colorspace_sv[] = {
  16. { "rgb", LOGICVC_DISPLAY_COLORSPACE_RGB },
  17. { "yuv422", LOGICVC_DISPLAY_COLORSPACE_YUV422 },
  18. { "yuv444", LOGICVC_DISPLAY_COLORSPACE_YUV444 },
  19. { },
  20. };
  21. static struct logicvc_of_property_sv logicvc_of_layer_colorspace_sv[] = {
  22. { "rgb", LOGICVC_LAYER_COLORSPACE_RGB },
  23. { "yuv", LOGICVC_LAYER_COLORSPACE_YUV },
  24. { },
  25. };
  26. static struct logicvc_of_property_sv logicvc_of_layer_alpha_mode_sv[] = {
  27. { "layer", LOGICVC_LAYER_ALPHA_LAYER },
  28. { "pixel", LOGICVC_LAYER_ALPHA_PIXEL },
  29. { },
  30. };
  31. static struct logicvc_of_property logicvc_of_properties[] = {
  32. [LOGICVC_OF_PROPERTY_DISPLAY_INTERFACE] = {
  33. .name = "xylon,display-interface",
  34. .sv = logicvc_of_display_interface_sv,
  35. .range = {
  36. LOGICVC_DISPLAY_INTERFACE_LVDS_4BITS,
  37. LOGICVC_DISPLAY_INTERFACE_LVDS_3BITS,
  38. },
  39. },
  40. [LOGICVC_OF_PROPERTY_DISPLAY_COLORSPACE] = {
  41. .name = "xylon,display-colorspace",
  42. .sv = logicvc_of_display_colorspace_sv,
  43. .range = {
  44. LOGICVC_DISPLAY_COLORSPACE_RGB,
  45. LOGICVC_DISPLAY_COLORSPACE_YUV444,
  46. },
  47. },
  48. [LOGICVC_OF_PROPERTY_DISPLAY_DEPTH] = {
  49. .name = "xylon,display-depth",
  50. .range = { 8, 24 },
  51. },
  52. [LOGICVC_OF_PROPERTY_ROW_STRIDE] = {
  53. .name = "xylon,row-stride",
  54. },
  55. [LOGICVC_OF_PROPERTY_DITHERING] = {
  56. .name = "xylon,dithering",
  57. .optional = true,
  58. },
  59. [LOGICVC_OF_PROPERTY_BACKGROUND_LAYER] = {
  60. .name = "xylon,background-layer",
  61. .optional = true,
  62. },
  63. [LOGICVC_OF_PROPERTY_LAYERS_CONFIGURABLE] = {
  64. .name = "xylon,layers-configurable",
  65. .optional = true,
  66. },
  67. [LOGICVC_OF_PROPERTY_LAYERS_COUNT] = {
  68. .name = "xylon,layers-count",
  69. },
  70. [LOGICVC_OF_PROPERTY_LAYER_DEPTH] = {
  71. .name = "xylon,layer-depth",
  72. .range = { 8, 24 },
  73. },
  74. [LOGICVC_OF_PROPERTY_LAYER_COLORSPACE] = {
  75. .name = "xylon,layer-colorspace",
  76. .sv = logicvc_of_layer_colorspace_sv,
  77. .range = {
  78. LOGICVC_LAYER_COLORSPACE_RGB,
  79. LOGICVC_LAYER_COLORSPACE_RGB,
  80. },
  81. },
  82. [LOGICVC_OF_PROPERTY_LAYER_ALPHA_MODE] = {
  83. .name = "xylon,layer-alpha-mode",
  84. .sv = logicvc_of_layer_alpha_mode_sv,
  85. .range = {
  86. LOGICVC_LAYER_ALPHA_LAYER,
  87. LOGICVC_LAYER_ALPHA_PIXEL,
  88. },
  89. },
  90. [LOGICVC_OF_PROPERTY_LAYER_BASE_OFFSET] = {
  91. .name = "xylon,layer-base-offset",
  92. },
  93. [LOGICVC_OF_PROPERTY_LAYER_BUFFER_OFFSET] = {
  94. .name = "xylon,layer-buffer-offset",
  95. },
  96. [LOGICVC_OF_PROPERTY_LAYER_PRIMARY] = {
  97. .name = "xylon,layer-primary",
  98. .optional = true,
  99. },
  100. };
  101. static int logicvc_of_property_sv_value(struct logicvc_of_property_sv *sv,
  102. const char *string, u32 *value)
  103. {
  104. unsigned int i = 0;
  105. while (sv[i].string) {
  106. if (!strcmp(sv[i].string, string)) {
  107. *value = sv[i].value;
  108. return 0;
  109. }
  110. i++;
  111. }
  112. return -EINVAL;
  113. }
  114. int logicvc_of_property_parse_u32(struct device_node *of_node,
  115. unsigned int index, u32 *target)
  116. {
  117. struct logicvc_of_property *property;
  118. const char *string;
  119. u32 value;
  120. int ret;
  121. if (index >= LOGICVC_OF_PROPERTY_MAXIMUM)
  122. return -EINVAL;
  123. property = &logicvc_of_properties[index];
  124. if (!property->optional &&
  125. !of_property_read_bool(of_node, property->name))
  126. return -ENODEV;
  127. if (property->sv) {
  128. ret = of_property_read_string(of_node, property->name, &string);
  129. if (ret)
  130. return ret;
  131. ret = logicvc_of_property_sv_value(property->sv, string,
  132. &value);
  133. if (ret)
  134. return ret;
  135. } else {
  136. ret = of_property_read_u32(of_node, property->name, &value);
  137. if (ret)
  138. return ret;
  139. }
  140. if (property->range[0] || property->range[1])
  141. if (value < property->range[0] || value > property->range[1])
  142. return -ERANGE;
  143. *target = value;
  144. return 0;
  145. }
  146. void logicvc_of_property_parse_bool(struct device_node *of_node,
  147. unsigned int index, bool *target)
  148. {
  149. struct logicvc_of_property *property;
  150. if (index >= LOGICVC_OF_PROPERTY_MAXIMUM) {
  151. /* Fallback. */
  152. *target = false;
  153. return;
  154. }
  155. property = &logicvc_of_properties[index];
  156. *target = of_property_read_bool(of_node, property->name);
  157. }
  158. bool logicvc_of_node_is_layer(struct device_node *of_node)
  159. {
  160. return !of_node_cmp(of_node->name, "layer");
  161. }