Other pixel formats have similar conversions to the one implemented in
the RGB565 helper.

Add a channels_to_argb_u16() helper to convert individual channels into
the internal representation, and use it in argb_u16_from_BGR565() and
argb_u16_from_RGB565().

Signed-off-by: Matheus Alves de Almeida <[email protected]>
---
 drivers/gpu/drm/vkms/vkms_formats.c | 50 +++++++++++++++++------------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index b44900761..6e4f58207 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -229,24 +229,42 @@ static struct pixel_argb_u16 
argb_u16_from_le16161616(__le16 a, __le16 r, __le16
                                       le16_to_cpu(b));
 }
 
-static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
+static u16 channel_to_u16(unsigned int size, u16 in)
+{
+       s64 fp_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp((1 << 
size) - 1));
+       s64 fp_channel = drm_int2fixp(in);
+
+       return drm_fixp2int_round(drm_fixp_mul(fp_channel, fp_ratio));
+}
+
+static struct pixel_argb_u16 channels_to_argb_u16(u16 in_r, u16 in_g, u16 
in_b, u16 in_a,
+                                                 unsigned int size_r, unsigned 
int size_g,
+                                                 unsigned int size_b, unsigned 
int size_a)
 {
        struct pixel_argb_u16 out_pixel;
 
-       s64 fp_rb_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(31));
-       s64 fp_g_ratio = drm_fixp_div(drm_int2fixp(65535), drm_int2fixp(63));
+       out_pixel.r = size_r ? channel_to_u16(size_r, in_r) : in_r;
+       out_pixel.g = size_g ? channel_to_u16(size_g, in_g) : in_g;
+       out_pixel.b = size_b ? channel_to_u16(size_b, in_b) : in_b;
+       out_pixel.a = size_a ? channel_to_u16(size_a, in_a) : in_a;
 
+       return out_pixel;
+}
+
+static struct pixel_argb_u16 argb_u16_from_RGB565(const __le16 *pixel)
+{
        u16 rgb_565 = le16_to_cpu(*pixel);
-       s64 fp_r = drm_int2fixp((rgb_565 >> 11) & 0x1f);
-       s64 fp_g = drm_int2fixp((rgb_565 >> 5) & 0x3f);
-       s64 fp_b = drm_int2fixp(rgb_565 & 0x1f);
 
-       out_pixel.a = (u16)0xffff;
-       out_pixel.r = drm_fixp2int_round(drm_fixp_mul(fp_r, fp_rb_ratio));
-       out_pixel.g = drm_fixp2int_round(drm_fixp_mul(fp_g, fp_g_ratio));
-       out_pixel.b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
+       return channels_to_argb_u16((rgb_565 >> 11) & 0x1f, (rgb_565 >> 5) & 
0x3f,
+                                   rgb_565 & 0x1f, 0xffff, 5, 6, 5, 0);
+}
 
-       return out_pixel;
+static struct pixel_argb_u16 argb_u16_from_BGR565(const __le16 *pixel)
+{
+       u16 bgr_565 = le16_to_cpu(*pixel);
+
+       return channels_to_argb_u16(bgr_565 & 0x1f, (bgr_565 >> 5) & 0x3f,
+                                   (bgr_565 >> 11) & 0x1f, 0xffff, 5, 6, 5, 0);
 }
 
 static struct pixel_argb_u16 argb_u16_from_gray8(u8 gray)
@@ -259,16 +277,6 @@ static struct pixel_argb_u16 argb_u16_from_grayu16(u16 
gray)
        return argb_u16_from_u16161616(0xFFFF, gray, gray, gray);
 }
 
-static struct pixel_argb_u16 argb_u16_from_BGR565(const __le16 *pixel)
-{
-       struct pixel_argb_u16 out_pixel;
-
-       out_pixel = argb_u16_from_RGB565(pixel);
-       swap(out_pixel.r, out_pixel.b);
-
-       return out_pixel;
-}
-
 VISIBLE_IF_KUNIT
 struct pixel_argb_u16 argb_u16_from_yuv161616(const struct conversion_matrix 
*matrix,
                                              u16 y, u16 channel_1, u16 
channel_2)
-- 
2.43.0

Reply via email to