blob: 837920bd3a33fe939426d614fa7cbecd4fb2c009 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Nikita Kiryanov033167c2015-02-03 13:32:31 +02002/*
3 * Simplefb device tree support
4 *
5 * (C) Copyright 2015
6 * Stephen Warren <swarren@wwwdotorg.org>
Nikita Kiryanov033167c2015-02-03 13:32:31 +02007 */
8
Tom Rinid678a592024-05-18 20:20:43 -06009#include <common.h>
Simon Glassd08e42a2017-04-05 16:23:43 -060010#include <dm.h>
Nikita Kiryanov033167c2015-02-03 13:32:31 +020011#include <fdt_support.h>
Simon Glass401d1c42020-10-30 21:38:53 -060012#include <asm/global_data.h>
Masahiro Yamadab08c8c42018-03-05 01:20:11 +090013#include <linux/libfdt.h>
Simon Glassd08e42a2017-04-05 16:23:43 -060014#include <video.h>
Devarsh Thakkar86281e42024-02-22 18:38:08 +053015#include <spl.h>
16#include <bloblist.h>
Nikita Kiryanov033167c2015-02-03 13:32:31 +020017
18DECLARE_GLOBAL_DATA_PTR;
19
Patrick Delaunayfded97a2021-11-15 16:32:19 +010020static int fdt_simplefb_configure_node(void *blob, int off)
Nikita Kiryanov033167c2015-02-03 13:32:31 +020021{
Simon Glass45261452017-04-05 16:23:42 -060022 int xsize, ysize;
23 int bpix; /* log2 of bits per pixel */
24 const char *name;
25 ulong fb_base;
Simon Glass8a8d24b2020-12-03 16:55:23 -070026 struct video_uc_plat *plat;
Simon Glassd08e42a2017-04-05 16:23:43 -060027 struct video_priv *uc_priv;
28 struct udevice *dev;
29 int ret;
Simon Glass45261452017-04-05 16:23:42 -060030
Devarsh Thakkar86281e42024-02-22 18:38:08 +053031 if (IS_ENABLED(CONFIG_SPL_VIDEO_HANDOFF) && spl_phase() > PHASE_SPL) {
32 struct video_handoff *ho;
33
34 ho = bloblist_find(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho));
35 if (!ho)
36 return log_msg_ret("Missing video bloblist", -ENOENT);
37
38 xsize = ho->xsize;
39 ysize = ho->ysize;
40 bpix = ho->bpix;
41 fb_base = ho->fb;
42 } else {
43 ret = uclass_first_device_err(UCLASS_VIDEO, &dev);
44 if (ret)
45 return ret;
46 uc_priv = dev_get_uclass_priv(dev);
47 plat = dev_get_uclass_plat(dev);
48 xsize = uc_priv->xsize;
49 ysize = uc_priv->ysize;
50 bpix = uc_priv->bpix;
51 fb_base = plat->base;
52 }
53
Simon Glass45261452017-04-05 16:23:42 -060054 switch (bpix) {
55 case 4: /* VIDEO_BPP16 */
56 name = "r5g6b5";
57 break;
58 case 5: /* VIDEO_BPP32 */
59 name = "a8r8g8b8";
60 break;
61 default:
62 return -EINVAL;
63 }
64
65 return fdt_setup_simplefb_node(blob, off, fb_base, xsize, ysize,
66 xsize * (1 << bpix) / 8, name);
Nikita Kiryanov033167c2015-02-03 13:32:31 +020067}
68
Patrick Delaunayfded97a2021-11-15 16:32:19 +010069int fdt_simplefb_add_node(void *blob)
Nikita Kiryanov033167c2015-02-03 13:32:31 +020070{
71 static const char compat[] = "simple-framebuffer";
72 static const char disabled[] = "disabled";
73 int off, ret;
74
75 off = fdt_add_subnode(blob, 0, "framebuffer");
76 if (off < 0)
77 return -1;
78
79 ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled));
80 if (ret < 0)
81 return -1;
82
83 ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat));
84 if (ret < 0)
85 return -1;
86
Patrick Delaunayfded97a2021-11-15 16:32:19 +010087 return fdt_simplefb_configure_node(blob, off);
Nikita Kiryanov033167c2015-02-03 13:32:31 +020088}
89
Heinrich Schuchardtb52d6de2023-04-03 20:46:50 +020090/**
91 * fdt_simplefb_enable_existing_node() - enable simple-framebuffer DT node
92 *
93 * @blob: device-tree
94 * Return: 0 on success, non-zero otherwise
95 */
96static int fdt_simplefb_enable_existing_node(void *blob)
Nikita Kiryanov033167c2015-02-03 13:32:31 +020097{
98 int off;
99
100 off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer");
101 if (off < 0)
102 return -1;
103
Patrick Delaunayfded97a2021-11-15 16:32:19 +0100104 return fdt_simplefb_configure_node(blob, off);
Nikita Kiryanov033167c2015-02-03 13:32:31 +0200105}
Patrick Delaunay77debf62021-11-15 16:32:21 +0100106
Simon Glass1f69cbe2023-02-05 15:44:27 -0700107#if IS_ENABLED(CONFIG_VIDEO)
Patrick Delaunay77debf62021-11-15 16:32:21 +0100108int fdt_simplefb_enable_and_mem_rsv(void *blob)
109{
Patrick Delaunay77debf62021-11-15 16:32:21 +0100110 int ret;
111
112 /* nothing to do when video is not active */
113 if (!video_is_active())
114 return 0;
115
116 ret = fdt_simplefb_enable_existing_node(blob);
117 if (ret)
118 return ret;
119
Devarsh Thakkarefe1cee2024-02-22 18:38:10 +0530120 return fdt_add_fb_mem_rsv(blob);
Patrick Delaunay77debf62021-11-15 16:32:21 +0100121}
122#endif