logicvc_layer.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2019-2022 Bootlin
  4. * Author: Paul Kocialkowski <[email protected]>
  5. */
  6. #include <linux/of.h>
  7. #include <linux/types.h>
  8. #include <drm/drm_atomic.h>
  9. #include <drm/drm_atomic_helper.h>
  10. #include <drm/drm_blend.h>
  11. #include <drm/drm_fb_dma_helper.h>
  12. #include <drm/drm_fourcc.h>
  13. #include <drm/drm_framebuffer.h>
  14. #include <drm/drm_plane.h>
  15. #include <drm/drm_print.h>
  16. #include "logicvc_crtc.h"
  17. #include "logicvc_drm.h"
  18. #include "logicvc_layer.h"
  19. #include "logicvc_of.h"
  20. #include "logicvc_regs.h"
  21. #define logicvc_layer(p) \
  22. container_of(p, struct logicvc_layer, drm_plane)
  23. static uint32_t logicvc_layer_formats_rgb16[] = {
  24. DRM_FORMAT_RGB565,
  25. DRM_FORMAT_BGR565,
  26. DRM_FORMAT_INVALID,
  27. };
  28. static uint32_t logicvc_layer_formats_rgb24[] = {
  29. DRM_FORMAT_XRGB8888,
  30. DRM_FORMAT_XBGR8888,
  31. DRM_FORMAT_INVALID,
  32. };
  33. /*
  34. * What we call depth in this driver only counts color components, not alpha.
  35. * This allows us to stay compatible with the LogiCVC bistream definitions.
  36. */
  37. static uint32_t logicvc_layer_formats_rgb24_alpha[] = {
  38. DRM_FORMAT_ARGB8888,
  39. DRM_FORMAT_ABGR8888,
  40. DRM_FORMAT_INVALID,
  41. };
  42. static struct logicvc_layer_formats logicvc_layer_formats[] = {
  43. {
  44. .colorspace = LOGICVC_LAYER_COLORSPACE_RGB,
  45. .depth = 16,
  46. .formats = logicvc_layer_formats_rgb16,
  47. },
  48. {
  49. .colorspace = LOGICVC_LAYER_COLORSPACE_RGB,
  50. .depth = 24,
  51. .formats = logicvc_layer_formats_rgb24,
  52. },
  53. {
  54. .colorspace = LOGICVC_LAYER_COLORSPACE_RGB,
  55. .depth = 24,
  56. .alpha = true,
  57. .formats = logicvc_layer_formats_rgb24_alpha,
  58. },
  59. { }
  60. };
  61. static bool logicvc_layer_format_inverted(uint32_t format)
  62. {
  63. switch (format) {
  64. case DRM_FORMAT_BGR565:
  65. case DRM_FORMAT_BGR888:
  66. case DRM_FORMAT_XBGR8888:
  67. case DRM_FORMAT_ABGR8888:
  68. return true;
  69. default:
  70. return false;
  71. }
  72. }
  73. static int logicvc_plane_atomic_check(struct drm_plane *drm_plane,
  74. struct drm_atomic_state *state)
  75. {
  76. struct drm_device *drm_dev = drm_plane->dev;
  77. struct logicvc_layer *layer = logicvc_layer(drm_plane);
  78. struct logicvc_drm *logicvc = logicvc_drm(drm_dev);
  79. struct drm_plane_state *new_state =
  80. drm_atomic_get_new_plane_state(state, drm_plane);
  81. struct drm_crtc_state *crtc_state;
  82. int min_scale, max_scale;
  83. bool can_position;
  84. int ret;
  85. if (!new_state->crtc)
  86. return 0;
  87. crtc_state = drm_atomic_get_existing_crtc_state(new_state->state,
  88. new_state->crtc);
  89. if (WARN_ON(!crtc_state))
  90. return -EINVAL;
  91. if (new_state->crtc_x < 0 || new_state->crtc_y < 0) {
  92. drm_err(drm_dev,
  93. "Negative on-CRTC positions are not supported.\n");
  94. return -EINVAL;
  95. }
  96. if (!logicvc->caps->layer_address) {
  97. ret = logicvc_layer_buffer_find_setup(logicvc, layer, new_state,
  98. NULL);
  99. if (ret) {
  100. drm_err(drm_dev, "No viable setup for buffer found.\n");
  101. return ret;
  102. }
  103. }
  104. min_scale = DRM_PLANE_NO_SCALING;
  105. max_scale = DRM_PLANE_NO_SCALING;
  106. can_position = (drm_plane->type == DRM_PLANE_TYPE_OVERLAY &&
  107. layer->index != (logicvc->config.layers_count - 1) &&
  108. logicvc->config.layers_configurable);
  109. ret = drm_atomic_helper_check_plane_state(new_state, crtc_state,
  110. min_scale, max_scale,
  111. can_position, true);
  112. if (ret) {
  113. drm_err(drm_dev, "Invalid plane state\n\n");
  114. return ret;
  115. }
  116. return 0;
  117. }
  118. static void logicvc_plane_atomic_update(struct drm_plane *drm_plane,
  119. struct drm_atomic_state *state)
  120. {
  121. struct logicvc_layer *layer = logicvc_layer(drm_plane);
  122. struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev);
  123. struct drm_device *drm_dev = &logicvc->drm_dev;
  124. struct drm_plane_state *new_state =
  125. drm_atomic_get_new_plane_state(state, drm_plane);
  126. struct drm_crtc *drm_crtc = &logicvc->crtc->drm_crtc;
  127. struct drm_display_mode *mode = &drm_crtc->state->adjusted_mode;
  128. struct drm_framebuffer *fb = new_state->fb;
  129. struct logicvc_layer_buffer_setup setup = {};
  130. u32 index = layer->index;
  131. u32 reg;
  132. /* Layer dimensions */
  133. regmap_write(logicvc->regmap, LOGICVC_LAYER_WIDTH_REG(index),
  134. new_state->crtc_w - 1);
  135. regmap_write(logicvc->regmap, LOGICVC_LAYER_HEIGHT_REG(index),
  136. new_state->crtc_h - 1);
  137. if (logicvc->caps->layer_address) {
  138. phys_addr_t fb_addr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
  139. regmap_write(logicvc->regmap, LOGICVC_LAYER_ADDRESS_REG(index),
  140. fb_addr);
  141. } else {
  142. /* Rely on offsets to configure the address. */
  143. logicvc_layer_buffer_find_setup(logicvc, layer, new_state,
  144. &setup);
  145. /* Layer memory offsets */
  146. regmap_write(logicvc->regmap, LOGICVC_BUFFER_SEL_REG,
  147. LOGICVC_BUFFER_SEL_VALUE(index, setup.buffer_sel));
  148. regmap_write(logicvc->regmap, LOGICVC_LAYER_HOFFSET_REG(index),
  149. setup.hoffset);
  150. regmap_write(logicvc->regmap, LOGICVC_LAYER_VOFFSET_REG(index),
  151. setup.voffset);
  152. }
  153. /* Layer position */
  154. regmap_write(logicvc->regmap, LOGICVC_LAYER_HPOSITION_REG(index),
  155. mode->hdisplay - 1 - new_state->crtc_x);
  156. /* Vertical position must be set last to sync layer register changes. */
  157. regmap_write(logicvc->regmap, LOGICVC_LAYER_VPOSITION_REG(index),
  158. mode->vdisplay - 1 - new_state->crtc_y);
  159. /* Layer alpha */
  160. if (layer->config.alpha_mode == LOGICVC_LAYER_ALPHA_LAYER) {
  161. u32 alpha_bits;
  162. u32 alpha_max;
  163. u32 alpha;
  164. switch (layer->config.depth) {
  165. case 8:
  166. alpha_bits = 3;
  167. break;
  168. case 16:
  169. if (layer->config.colorspace ==
  170. LOGICVC_LAYER_COLORSPACE_YUV)
  171. alpha_bits = 8;
  172. else
  173. alpha_bits = 6;
  174. break;
  175. default:
  176. alpha_bits = 8;
  177. break;
  178. }
  179. alpha_max = BIT(alpha_bits) - 1;
  180. alpha = new_state->alpha * alpha_max / DRM_BLEND_ALPHA_OPAQUE;
  181. drm_dbg_kms(drm_dev, "Setting layer %d alpha to %d/%d\n", index,
  182. alpha, alpha_max);
  183. regmap_write(logicvc->regmap, LOGICVC_LAYER_ALPHA_REG(index),
  184. alpha);
  185. }
  186. /* Layer control */
  187. reg = LOGICVC_LAYER_CTRL_ENABLE;
  188. if (logicvc_layer_format_inverted(fb->format->format))
  189. reg |= LOGICVC_LAYER_CTRL_PIXEL_FORMAT_INVERT;
  190. reg |= LOGICVC_LAYER_CTRL_COLOR_KEY_DISABLE;
  191. regmap_write(logicvc->regmap, LOGICVC_LAYER_CTRL_REG(index), reg);
  192. }
  193. static void logicvc_plane_atomic_disable(struct drm_plane *drm_plane,
  194. struct drm_atomic_state *state)
  195. {
  196. struct logicvc_layer *layer = logicvc_layer(drm_plane);
  197. struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev);
  198. u32 index = layer->index;
  199. regmap_write(logicvc->regmap, LOGICVC_LAYER_CTRL_REG(index), 0);
  200. }
  201. static struct drm_plane_helper_funcs logicvc_plane_helper_funcs = {
  202. .atomic_check = logicvc_plane_atomic_check,
  203. .atomic_update = logicvc_plane_atomic_update,
  204. .atomic_disable = logicvc_plane_atomic_disable,
  205. };
  206. static const struct drm_plane_funcs logicvc_plane_funcs = {
  207. .update_plane = drm_atomic_helper_update_plane,
  208. .disable_plane = drm_atomic_helper_disable_plane,
  209. .destroy = drm_plane_cleanup,
  210. .reset = drm_atomic_helper_plane_reset,
  211. .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
  212. .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
  213. };
  214. int logicvc_layer_buffer_find_setup(struct logicvc_drm *logicvc,
  215. struct logicvc_layer *layer,
  216. struct drm_plane_state *state,
  217. struct logicvc_layer_buffer_setup *setup)
  218. {
  219. struct drm_device *drm_dev = &logicvc->drm_dev;
  220. struct drm_framebuffer *fb = state->fb;
  221. /* All the supported formats have a single data plane. */
  222. u32 layer_bytespp = fb->format->cpp[0];
  223. u32 layer_stride = layer_bytespp * logicvc->config.row_stride;
  224. u32 base_offset = layer->config.base_offset * layer_stride;
  225. u32 buffer_offset = layer->config.buffer_offset * layer_stride;
  226. u8 buffer_sel = 0;
  227. u16 voffset = 0;
  228. u16 hoffset = 0;
  229. phys_addr_t fb_addr;
  230. u32 fb_offset;
  231. u32 gap;
  232. if (!logicvc->reserved_mem_base) {
  233. drm_err(drm_dev, "No reserved memory base was registered!\n");
  234. return -ENOMEM;
  235. }
  236. fb_addr = drm_fb_dma_get_gem_addr(fb, state, 0);
  237. if (fb_addr < logicvc->reserved_mem_base) {
  238. drm_err(drm_dev,
  239. "Framebuffer memory below reserved memory base!\n");
  240. return -EINVAL;
  241. }
  242. fb_offset = (u32) (fb_addr - logicvc->reserved_mem_base);
  243. if (fb_offset < base_offset) {
  244. drm_err(drm_dev,
  245. "Framebuffer offset below layer base offset!\n");
  246. return -EINVAL;
  247. }
  248. gap = fb_offset - base_offset;
  249. /* Use the possible video buffers selection. */
  250. if (gap && buffer_offset) {
  251. buffer_sel = gap / buffer_offset;
  252. if (buffer_sel > LOGICVC_BUFFER_SEL_MAX)
  253. buffer_sel = LOGICVC_BUFFER_SEL_MAX;
  254. gap -= buffer_sel * buffer_offset;
  255. }
  256. /* Use the vertical offset. */
  257. if (gap && layer_stride && logicvc->config.layers_configurable) {
  258. voffset = gap / layer_stride;
  259. if (voffset > LOGICVC_LAYER_VOFFSET_MAX)
  260. voffset = LOGICVC_LAYER_VOFFSET_MAX;
  261. gap -= voffset * layer_stride;
  262. }
  263. /* Use the horizontal offset. */
  264. if (gap && layer_bytespp && logicvc->config.layers_configurable) {
  265. hoffset = gap / layer_bytespp;
  266. if (hoffset > LOGICVC_DIMENSIONS_MAX)
  267. hoffset = LOGICVC_DIMENSIONS_MAX;
  268. gap -= hoffset * layer_bytespp;
  269. }
  270. if (gap) {
  271. drm_err(drm_dev,
  272. "Unable to find layer %d buffer setup for 0x%x byte gap\n",
  273. layer->index, fb_offset - base_offset);
  274. return -EINVAL;
  275. }
  276. drm_dbg_kms(drm_dev, "Found layer %d buffer setup for 0x%x byte gap:\n",
  277. layer->index, fb_offset - base_offset);
  278. drm_dbg_kms(drm_dev, "- buffer_sel = 0x%x chunks of 0x%x bytes\n",
  279. buffer_sel, buffer_offset);
  280. drm_dbg_kms(drm_dev, "- voffset = 0x%x chunks of 0x%x bytes\n", voffset,
  281. layer_stride);
  282. drm_dbg_kms(drm_dev, "- hoffset = 0x%x chunks of 0x%x bytes\n", hoffset,
  283. layer_bytespp);
  284. if (setup) {
  285. setup->buffer_sel = buffer_sel;
  286. setup->voffset = voffset;
  287. setup->hoffset = hoffset;
  288. }
  289. return 0;
  290. }
  291. static struct logicvc_layer_formats *logicvc_layer_formats_lookup(struct logicvc_layer *layer)
  292. {
  293. bool alpha;
  294. unsigned int i = 0;
  295. alpha = (layer->config.alpha_mode == LOGICVC_LAYER_ALPHA_PIXEL);
  296. while (logicvc_layer_formats[i].formats) {
  297. if (logicvc_layer_formats[i].colorspace == layer->config.colorspace &&
  298. logicvc_layer_formats[i].depth == layer->config.depth &&
  299. logicvc_layer_formats[i].alpha == alpha)
  300. return &logicvc_layer_formats[i];
  301. i++;
  302. }
  303. return NULL;
  304. }
  305. static unsigned int logicvc_layer_formats_count(struct logicvc_layer_formats *formats)
  306. {
  307. unsigned int count = 0;
  308. while (formats->formats[count] != DRM_FORMAT_INVALID)
  309. count++;
  310. return count;
  311. }
  312. static int logicvc_layer_config_parse(struct logicvc_drm *logicvc,
  313. struct logicvc_layer *layer)
  314. {
  315. struct device_node *of_node = layer->of_node;
  316. struct logicvc_layer_config *config = &layer->config;
  317. int ret;
  318. logicvc_of_property_parse_bool(of_node,
  319. LOGICVC_OF_PROPERTY_LAYER_PRIMARY,
  320. &config->primary);
  321. ret = logicvc_of_property_parse_u32(of_node,
  322. LOGICVC_OF_PROPERTY_LAYER_COLORSPACE,
  323. &config->colorspace);
  324. if (ret)
  325. return ret;
  326. ret = logicvc_of_property_parse_u32(of_node,
  327. LOGICVC_OF_PROPERTY_LAYER_DEPTH,
  328. &config->depth);
  329. if (ret)
  330. return ret;
  331. ret = logicvc_of_property_parse_u32(of_node,
  332. LOGICVC_OF_PROPERTY_LAYER_ALPHA_MODE,
  333. &config->alpha_mode);
  334. if (ret)
  335. return ret;
  336. /*
  337. * Memory offset is only relevant without layer address configuration.
  338. */
  339. if (logicvc->caps->layer_address)
  340. return 0;
  341. ret = logicvc_of_property_parse_u32(of_node,
  342. LOGICVC_OF_PROPERTY_LAYER_BASE_OFFSET,
  343. &config->base_offset);
  344. if (ret)
  345. return ret;
  346. ret = logicvc_of_property_parse_u32(of_node,
  347. LOGICVC_OF_PROPERTY_LAYER_BUFFER_OFFSET,
  348. &config->buffer_offset);
  349. if (ret)
  350. return ret;
  351. return 0;
  352. }
  353. struct logicvc_layer *logicvc_layer_get_from_index(struct logicvc_drm *logicvc,
  354. u32 index)
  355. {
  356. struct logicvc_layer *layer;
  357. list_for_each_entry(layer, &logicvc->layers_list, list)
  358. if (layer->index == index)
  359. return layer;
  360. return NULL;
  361. }
  362. struct logicvc_layer *logicvc_layer_get_from_type(struct logicvc_drm *logicvc,
  363. enum drm_plane_type type)
  364. {
  365. struct logicvc_layer *layer;
  366. list_for_each_entry(layer, &logicvc->layers_list, list)
  367. if (layer->drm_plane.type == type)
  368. return layer;
  369. return NULL;
  370. }
  371. struct logicvc_layer *logicvc_layer_get_primary(struct logicvc_drm *logicvc)
  372. {
  373. return logicvc_layer_get_from_type(logicvc, DRM_PLANE_TYPE_PRIMARY);
  374. }
  375. static int logicvc_layer_init(struct logicvc_drm *logicvc,
  376. struct device_node *of_node, u32 index)
  377. {
  378. struct drm_device *drm_dev = &logicvc->drm_dev;
  379. struct device *dev = drm_dev->dev;
  380. struct logicvc_layer *layer = NULL;
  381. struct logicvc_layer_formats *formats;
  382. unsigned int formats_count;
  383. enum drm_plane_type type;
  384. unsigned int zpos;
  385. int ret;
  386. layer = devm_kzalloc(dev, sizeof(*layer), GFP_KERNEL);
  387. if (!layer) {
  388. ret = -ENOMEM;
  389. goto error;
  390. }
  391. layer->of_node = of_node;
  392. layer->index = index;
  393. ret = logicvc_layer_config_parse(logicvc, layer);
  394. if (ret) {
  395. drm_err(drm_dev, "Failed to parse config for layer #%d\n",
  396. index);
  397. goto error;
  398. }
  399. formats = logicvc_layer_formats_lookup(layer);
  400. if (!formats) {
  401. drm_err(drm_dev, "Failed to lookup formats for layer #%d\n",
  402. index);
  403. ret = -EINVAL;
  404. goto error;
  405. }
  406. formats_count = logicvc_layer_formats_count(formats);
  407. /* The final layer can be configured as a background layer. */
  408. if (logicvc->config.background_layer &&
  409. index == (logicvc->config.layers_count - 1)) {
  410. /*
  411. * A zero value for black is only valid for RGB, not for YUV,
  412. * so this will need to take the format in account for YUV.
  413. */
  414. u32 background = 0;
  415. drm_dbg_kms(drm_dev, "Using layer #%d as background layer\n",
  416. index);
  417. regmap_write(logicvc->regmap, LOGICVC_BACKGROUND_COLOR_REG,
  418. background);
  419. devm_kfree(dev, layer);
  420. return 0;
  421. }
  422. if (layer->config.primary)
  423. type = DRM_PLANE_TYPE_PRIMARY;
  424. else
  425. type = DRM_PLANE_TYPE_OVERLAY;
  426. ret = drm_universal_plane_init(drm_dev, &layer->drm_plane, 0,
  427. &logicvc_plane_funcs, formats->formats,
  428. formats_count, NULL, type, NULL);
  429. if (ret) {
  430. drm_err(drm_dev, "Failed to initialize layer plane\n");
  431. return ret;
  432. }
  433. drm_plane_helper_add(&layer->drm_plane, &logicvc_plane_helper_funcs);
  434. zpos = logicvc->config.layers_count - index - 1;
  435. drm_dbg_kms(drm_dev, "Giving layer #%d zpos %d\n", index, zpos);
  436. if (layer->config.alpha_mode == LOGICVC_LAYER_ALPHA_LAYER)
  437. drm_plane_create_alpha_property(&layer->drm_plane);
  438. drm_plane_create_zpos_immutable_property(&layer->drm_plane, zpos);
  439. drm_dbg_kms(drm_dev, "Registering layer #%d\n", index);
  440. layer->formats = formats;
  441. list_add_tail(&layer->list, &logicvc->layers_list);
  442. return 0;
  443. error:
  444. if (layer)
  445. devm_kfree(dev, layer);
  446. return ret;
  447. }
  448. static void logicvc_layer_fini(struct logicvc_drm *logicvc,
  449. struct logicvc_layer *layer)
  450. {
  451. struct device *dev = logicvc->drm_dev.dev;
  452. list_del(&layer->list);
  453. devm_kfree(dev, layer);
  454. }
  455. void logicvc_layers_attach_crtc(struct logicvc_drm *logicvc)
  456. {
  457. uint32_t possible_crtcs = drm_crtc_mask(&logicvc->crtc->drm_crtc);
  458. struct logicvc_layer *layer;
  459. list_for_each_entry(layer, &logicvc->layers_list, list) {
  460. if (layer->drm_plane.type != DRM_PLANE_TYPE_OVERLAY)
  461. continue;
  462. layer->drm_plane.possible_crtcs = possible_crtcs;
  463. }
  464. }
  465. int logicvc_layers_init(struct logicvc_drm *logicvc)
  466. {
  467. struct drm_device *drm_dev = &logicvc->drm_dev;
  468. struct device *dev = drm_dev->dev;
  469. struct device_node *of_node = dev->of_node;
  470. struct device_node *layer_node = NULL;
  471. struct device_node *layers_node;
  472. struct logicvc_layer *layer;
  473. struct logicvc_layer *next;
  474. int ret = 0;
  475. layers_node = of_get_child_by_name(of_node, "layers");
  476. if (!layers_node) {
  477. drm_err(drm_dev, "No layers node found in the description\n");
  478. ret = -ENODEV;
  479. goto error;
  480. }
  481. for_each_child_of_node(layers_node, layer_node) {
  482. u32 index = 0;
  483. if (!logicvc_of_node_is_layer(layer_node))
  484. continue;
  485. ret = of_property_read_u32(layer_node, "reg", &index);
  486. if (ret)
  487. continue;
  488. layer = logicvc_layer_get_from_index(logicvc, index);
  489. if (layer) {
  490. drm_err(drm_dev, "Duplicated entry for layer #%d\n",
  491. index);
  492. continue;
  493. }
  494. ret = logicvc_layer_init(logicvc, layer_node, index);
  495. if (ret) {
  496. of_node_put(layers_node);
  497. goto error;
  498. }
  499. }
  500. of_node_put(layers_node);
  501. return 0;
  502. error:
  503. list_for_each_entry_safe(layer, next, &logicvc->layers_list, list)
  504. logicvc_layer_fini(logicvc, layer);
  505. return ret;
  506. }