brcm2708-gpu-fw: update to latest version
[oweals/openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0374-BCM2835-V4L2-Correct-handling-for-BGR24-vs-RGB24.patch
1 From 1fa221e0909bc0052bdc8b458fb31e8a088e7723 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <6by9@users.noreply.github.com>
3 Date: Wed, 25 May 2016 23:25:36 +0100
4 Subject: [PATCH] BCM2835-V4L2: Correct handling for BGR24 vs RGB24.
5
6 There was a bug in the GPU firmware that had reversed these
7 two formats.
8 Detect the old firmware, and reverse the formats if necessary.
9
10 Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
11 ---
12  drivers/media/platform/bcm2835/bcm2835-camera.c | 69 ++++++++++++++++++-------
13  drivers/media/platform/bcm2835/bcm2835-camera.h |  1 +
14  2 files changed, 52 insertions(+), 18 deletions(-)
15
16 --- a/drivers/media/platform/bcm2835/bcm2835-camera.c
17 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
18 @@ -115,7 +115,7 @@ static struct mmal_fmt formats[] = {
19          .name = "RGB24 (LE)",
20          .fourcc = V4L2_PIX_FMT_RGB24,
21          .flags = 0,
22 -        .mmal = MMAL_ENCODING_BGR24,
23 +        .mmal = MMAL_ENCODING_RGB24,
24          .depth = 24,
25          .mmal_component = MMAL_COMPONENT_CAMERA,
26          .ybbp = 3,
27 @@ -187,7 +187,7 @@ static struct mmal_fmt formats[] = {
28          .name = "RGB24 (BE)",
29          .fourcc = V4L2_PIX_FMT_BGR24,
30          .flags = 0,
31 -        .mmal = MMAL_ENCODING_RGB24,
32 +        .mmal = MMAL_ENCODING_BGR24,
33          .depth = 24,
34          .mmal_component = MMAL_COMPONENT_CAMERA,
35          .ybbp = 3,
36 @@ -1059,6 +1059,13 @@ static int mmal_setup_components(struct
37         else
38                 camera_port->format.encoding = mfmt->mmal;
39  
40 +       if (dev->rgb_bgr_swapped) {
41 +               if (camera_port->format.encoding == MMAL_ENCODING_RGB24)
42 +                       camera_port->format.encoding = MMAL_ENCODING_BGR24;
43 +               else if (camera_port->format.encoding == MMAL_ENCODING_BGR24)
44 +                       camera_port->format.encoding = MMAL_ENCODING_RGB24;
45 +       }
46 +
47         camera_port->format.encoding_variant = 0;
48         camera_port->es.video.width = f->fmt.pix.width;
49         camera_port->es.video.height = f->fmt.pix.height;
50 @@ -1569,12 +1576,17 @@ static int set_camera_parameters(struct
51         return ret;
52  }
53  
54 +#define MAX_SUPPORTED_ENCODINGS 20
55 +
56  /* MMAL instance and component init */
57  static int __init mmal_init(struct bm2835_mmal_dev *dev)
58  {
59         int ret;
60         struct mmal_es_format *format;
61         u32 bool_true = 1;
62 +       u32 supported_encodings[MAX_SUPPORTED_ENCODINGS];
63 +       int param_size;
64 +       struct vchiq_mmal_component  *camera;
65  
66         ret = vchiq_mmal_init(&dev->instance);
67         if (ret < 0)
68 @@ -1586,21 +1598,48 @@ static int __init mmal_init(struct bm283
69         if (ret < 0)
70                 goto unreg_mmal;
71  
72 -       if (dev->component[MMAL_COMPONENT_CAMERA]->outputs <
73 -           MMAL_CAMERA_PORT_COUNT) {
74 +       camera = dev->component[MMAL_COMPONENT_CAMERA];
75 +       if (camera->outputs <  MMAL_CAMERA_PORT_COUNT) {
76                 ret = -EINVAL;
77                 goto unreg_camera;
78         }
79  
80         ret = set_camera_parameters(dev->instance,
81 -                                   dev->component[MMAL_COMPONENT_CAMERA],
82 +                                   camera,
83                                     dev);
84         if (ret < 0)
85                 goto unreg_camera;
86  
87 -       format =
88 -           &dev->component[MMAL_COMPONENT_CAMERA]->
89 -           output[MMAL_CAMERA_PORT_PREVIEW].format;
90 +       /* There was an error in the firmware that meant the camera component
91 +        * produced BGR instead of RGB.
92 +        * This is now fixed, but in order to support the old firmwares, we
93 +        * have to check.
94 +        */
95 +       dev->rgb_bgr_swapped = true;
96 +       param_size = sizeof(supported_encodings);
97 +       ret = vchiq_mmal_port_parameter_get(dev->instance,
98 +               &camera->output[MMAL_CAMERA_PORT_CAPTURE],
99 +               MMAL_PARAMETER_SUPPORTED_ENCODINGS,
100 +               &supported_encodings,
101 +               &param_size);
102 +       if (ret == 0) {
103 +               int i;
104 +
105 +               for (i = 0; i < param_size/sizeof(u32); i++) {
106 +                       if (supported_encodings[i] == MMAL_ENCODING_BGR24) {
107 +                               /* Found BGR24 first - old firmware. */
108 +                               break;
109 +                       }
110 +                       if (supported_encodings[i] == MMAL_ENCODING_RGB24) {
111 +                               /* Found RGB24 first
112 +                                * new firmware, so use RGB24.
113 +                                */
114 +                               dev->rgb_bgr_swapped = false;
115 +                       break;
116 +                       }
117 +               }
118 +       }
119 +       format = &camera->output[MMAL_CAMERA_PORT_PREVIEW].format;
120  
121         format->encoding = MMAL_ENCODING_OPAQUE;
122         format->encoding_variant = MMAL_ENCODING_I420;
123 @@ -1614,9 +1653,7 @@ static int __init mmal_init(struct bm283
124         format->es->video.frame_rate.num = 0; /* Rely on fps_range */
125         format->es->video.frame_rate.den = 1;
126  
127 -       format =
128 -           &dev->component[MMAL_COMPONENT_CAMERA]->
129 -           output[MMAL_CAMERA_PORT_VIDEO].format;
130 +       format = &camera->output[MMAL_CAMERA_PORT_VIDEO].format;
131  
132         format->encoding = MMAL_ENCODING_OPAQUE;
133         format->encoding_variant = MMAL_ENCODING_I420;
134 @@ -1631,14 +1668,11 @@ static int __init mmal_init(struct bm283
135         format->es->video.frame_rate.den = 1;
136  
137         vchiq_mmal_port_parameter_set(dev->instance,
138 -               &dev->component[MMAL_COMPONENT_CAMERA]->
139 -                               output[MMAL_CAMERA_PORT_VIDEO],
140 +               &camera->output[MMAL_CAMERA_PORT_VIDEO],
141                 MMAL_PARAMETER_NO_IMAGE_PADDING,
142                 &bool_true, sizeof(bool_true));
143  
144 -       format =
145 -           &dev->component[MMAL_COMPONENT_CAMERA]->
146 -           output[MMAL_CAMERA_PORT_CAPTURE].format;
147 +       format = &camera->output[MMAL_CAMERA_PORT_CAPTURE].format;
148  
149         format->encoding = MMAL_ENCODING_OPAQUE;
150  
151 @@ -1660,8 +1694,7 @@ static int __init mmal_init(struct bm283
152         dev->capture.enc_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
153  
154         vchiq_mmal_port_parameter_set(dev->instance,
155 -               &dev->component[MMAL_COMPONENT_CAMERA]->
156 -                       output[MMAL_CAMERA_PORT_CAPTURE],
157 +               &camera->output[MMAL_CAMERA_PORT_CAPTURE],
158                 MMAL_PARAMETER_NO_IMAGE_PADDING,
159                 &bool_true, sizeof(bool_true));
160  
161 --- a/drivers/media/platform/bcm2835/bcm2835-camera.h
162 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
163 @@ -109,6 +109,7 @@ struct bm2835_mmal_dev {
164         unsigned int camera_num;
165         unsigned int max_width;
166         unsigned int max_height;
167 +       unsigned int rgb_bgr_swapped;
168  };
169  
170  int bm2835_mmal_init_controls(