11ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2bbbe775eSNeil Armstrong /* 3bbbe775eSNeil Armstrong * Copyright (C) 2016 BayLibre, SAS 4bbbe775eSNeil Armstrong * Author: Neil Armstrong <narmstrong@baylibre.com> 5bbbe775eSNeil Armstrong * Copyright (C) 2015 Amlogic, Inc. All rights reserved. 6bbbe775eSNeil Armstrong * Copyright (C) 2014 Endless Mobile 7bbbe775eSNeil Armstrong */ 8bbbe775eSNeil Armstrong 966620f48SSam Ravnborg #include <linux/export.h> 1066620f48SSam Ravnborg 11bbbe775eSNeil Armstrong #include "meson_drv.h" 12bbbe775eSNeil Armstrong #include "meson_viu.h" 13bbbe775eSNeil Armstrong #include "meson_registers.h" 14bbbe775eSNeil Armstrong 152021d5b7SNeil Armstrong /** 162021d5b7SNeil Armstrong * DOC: Video Input Unit 172021d5b7SNeil Armstrong * 18bbbe775eSNeil Armstrong * VIU Handles the Pixel scanout and the basic Colorspace conversions 19bbbe775eSNeil Armstrong * We handle the following features : 202021d5b7SNeil Armstrong * 21bbbe775eSNeil Armstrong * - OSD1 RGB565/RGB888/xRGB8888 scanout 22bbbe775eSNeil Armstrong * - RGB conversion to x/cb/cr 23bbbe775eSNeil Armstrong * - Progressive or Interlace buffer scanout 24bbbe775eSNeil Armstrong * - OSD1 Commit on Vsync 25bbbe775eSNeil Armstrong * - HDR OSD matrix for GXL/GXM 26bbbe775eSNeil Armstrong * 27bbbe775eSNeil Armstrong * What is missing : 282021d5b7SNeil Armstrong * 29bbbe775eSNeil Armstrong * - BGR888/xBGR8888/BGRx8888/BGRx8888 modes 30bbbe775eSNeil Armstrong * - YUV4:2:2 Y0CbY1Cr scanout 31bbbe775eSNeil Armstrong * - Conversion to YUV 4:4:4 from 4:2:2 input 32bbbe775eSNeil Armstrong * - Colorkey Alpha matching 33bbbe775eSNeil Armstrong * - Big endian scanout 34bbbe775eSNeil Armstrong * - X/Y reverse scanout 35bbbe775eSNeil Armstrong * - Global alpha setup 36bbbe775eSNeil Armstrong * - OSD2 support, would need interlace switching on vsync 37bbbe775eSNeil Armstrong * - OSD1 full scaling to support TV overscan 38bbbe775eSNeil Armstrong */ 39bbbe775eSNeil Armstrong 40bbbe775eSNeil Armstrong /* OSD csc defines */ 41bbbe775eSNeil Armstrong 42bbbe775eSNeil Armstrong enum viu_matrix_sel_e { 43bbbe775eSNeil Armstrong VIU_MATRIX_OSD_EOTF = 0, 44bbbe775eSNeil Armstrong VIU_MATRIX_OSD, 45bbbe775eSNeil Armstrong }; 46bbbe775eSNeil Armstrong 47bbbe775eSNeil Armstrong enum viu_lut_sel_e { 48bbbe775eSNeil Armstrong VIU_LUT_OSD_EOTF = 0, 49bbbe775eSNeil Armstrong VIU_LUT_OSD_OETF, 50bbbe775eSNeil Armstrong }; 51bbbe775eSNeil Armstrong 52bbbe775eSNeil Armstrong #define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2)) 53bbbe775eSNeil Armstrong #define MATRIX_5X3_COEF_SIZE 24 54bbbe775eSNeil Armstrong 55bbbe775eSNeil Armstrong #define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2)) 56bbbe775eSNeil Armstrong #define EOTF_COEFF_SIZE 10 57bbbe775eSNeil Armstrong #define EOTF_COEFF_RIGHTSHIFT 1 58bbbe775eSNeil Armstrong 59bbbe775eSNeil Armstrong static int RGB709_to_YUV709l_coeff[MATRIX_5X3_COEF_SIZE] = { 60bbbe775eSNeil Armstrong 0, 0, 0, /* pre offset */ 61bbbe775eSNeil Armstrong COEFF_NORM(0.181873), COEFF_NORM(0.611831), COEFF_NORM(0.061765), 62bbbe775eSNeil Armstrong COEFF_NORM(-0.100251), COEFF_NORM(-0.337249), COEFF_NORM(0.437500), 63bbbe775eSNeil Armstrong COEFF_NORM(0.437500), COEFF_NORM(-0.397384), COEFF_NORM(-0.040116), 64bbbe775eSNeil Armstrong 0, 0, 0, /* 10'/11'/12' */ 65bbbe775eSNeil Armstrong 0, 0, 0, /* 20'/21'/22' */ 66bbbe775eSNeil Armstrong 64, 512, 512, /* offset */ 67bbbe775eSNeil Armstrong 0, 0, 0 /* mode, right_shift, clip_en */ 68bbbe775eSNeil Armstrong }; 69bbbe775eSNeil Armstrong 70bbbe775eSNeil Armstrong /* eotf matrix: bypass */ 71bbbe775eSNeil Armstrong static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = { 72bbbe775eSNeil Armstrong EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), 73bbbe775eSNeil Armstrong EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), 74bbbe775eSNeil Armstrong EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), 75bbbe775eSNeil Armstrong EOTF_COEFF_RIGHTSHIFT /* right shift */ 76bbbe775eSNeil Armstrong }; 77bbbe775eSNeil Armstrong 782ccb8433SYueHaibing static void meson_viu_set_g12a_osd1_matrix(struct meson_drm *priv, 792ccb8433SYueHaibing int *m, bool csc_on) 8072888394SNeil Armstrong { 8172888394SNeil Armstrong /* VPP WRAP OSD1 matrix */ 8272888394SNeil Armstrong writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff), 8372888394SNeil Armstrong priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET0_1)); 8472888394SNeil Armstrong writel(m[2] & 0xfff, 8572888394SNeil Armstrong priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET2)); 8672888394SNeil Armstrong writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff), 8772888394SNeil Armstrong priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF00_01)); 8872888394SNeil Armstrong writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff), 8972888394SNeil Armstrong priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF02_10)); 9072888394SNeil Armstrong writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff), 9172888394SNeil Armstrong priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF11_12)); 9272888394SNeil Armstrong writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff), 9372888394SNeil Armstrong priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF20_21)); 9472888394SNeil Armstrong writel((m[11] & 0x1fff) << 16, 9572888394SNeil Armstrong priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF22)); 9672888394SNeil Armstrong 9772888394SNeil Armstrong writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff), 9872888394SNeil Armstrong priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET0_1)); 9972888394SNeil Armstrong writel(m[20] & 0xfff, 10072888394SNeil Armstrong priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET2)); 10172888394SNeil Armstrong 10272888394SNeil Armstrong writel_bits_relaxed(BIT(0), csc_on ? BIT(0) : 0, 10372888394SNeil Armstrong priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL)); 10472888394SNeil Armstrong } 10572888394SNeil Armstrong 1062ccb8433SYueHaibing static void meson_viu_set_osd_matrix(struct meson_drm *priv, 107bbbe775eSNeil Armstrong enum viu_matrix_sel_e m_select, 108bbbe775eSNeil Armstrong int *m, bool csc_on) 109bbbe775eSNeil Armstrong { 110bbbe775eSNeil Armstrong if (m_select == VIU_MATRIX_OSD) { 111bbbe775eSNeil Armstrong /* osd matrix, VIU_MATRIX_0 */ 112bbbe775eSNeil Armstrong writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff), 113bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET0_1)); 114bbbe775eSNeil Armstrong writel(m[2] & 0xfff, 115bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET2)); 116bbbe775eSNeil Armstrong writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff), 117bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_COEF00_01)); 118bbbe775eSNeil Armstrong writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff), 119bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_COEF02_10)); 120bbbe775eSNeil Armstrong writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff), 121bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_COEF11_12)); 122bbbe775eSNeil Armstrong writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff), 123bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_COEF20_21)); 124bbbe775eSNeil Armstrong 125bbbe775eSNeil Armstrong if (m[21]) { 126bbbe775eSNeil Armstrong writel(((m[11] & 0x1fff) << 16) | (m[12] & 0x1fff), 127bbbe775eSNeil Armstrong priv->io_base + 128bbbe775eSNeil Armstrong _REG(VIU_OSD1_MATRIX_COEF22_30)); 129bbbe775eSNeil Armstrong writel(((m[13] & 0x1fff) << 16) | (m[14] & 0x1fff), 130bbbe775eSNeil Armstrong priv->io_base + 131bbbe775eSNeil Armstrong _REG(VIU_OSD1_MATRIX_COEF31_32)); 132bbbe775eSNeil Armstrong writel(((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff), 133bbbe775eSNeil Armstrong priv->io_base + 134bbbe775eSNeil Armstrong _REG(VIU_OSD1_MATRIX_COEF40_41)); 135bbbe775eSNeil Armstrong writel(m[17] & 0x1fff, priv->io_base + 136bbbe775eSNeil Armstrong _REG(VIU_OSD1_MATRIX_COLMOD_COEF42)); 137bbbe775eSNeil Armstrong } else 138bbbe775eSNeil Armstrong writel((m[11] & 0x1fff) << 16, priv->io_base + 139bbbe775eSNeil Armstrong _REG(VIU_OSD1_MATRIX_COEF22_30)); 140bbbe775eSNeil Armstrong 141bbbe775eSNeil Armstrong writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff), 142bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET0_1)); 143bbbe775eSNeil Armstrong writel(m[20] & 0xfff, 144bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET2)); 145bbbe775eSNeil Armstrong 146bbbe775eSNeil Armstrong writel_bits_relaxed(3 << 30, m[21] << 30, 147bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42)); 148bbbe775eSNeil Armstrong writel_bits_relaxed(7 << 16, m[22] << 16, 149bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42)); 150bbbe775eSNeil Armstrong 151bbbe775eSNeil Armstrong /* 23 reserved for clipping control */ 152bbbe775eSNeil Armstrong writel_bits_relaxed(BIT(0), csc_on ? BIT(0) : 0, 153bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL)); 154bbbe775eSNeil Armstrong writel_bits_relaxed(BIT(1), 0, 155bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL)); 156bbbe775eSNeil Armstrong } else if (m_select == VIU_MATRIX_OSD_EOTF) { 157bbbe775eSNeil Armstrong int i; 158bbbe775eSNeil Armstrong 159bbbe775eSNeil Armstrong /* osd eotf matrix, VIU_MATRIX_OSD_EOTF */ 160bbbe775eSNeil Armstrong for (i = 0; i < 5; i++) 161bbbe775eSNeil Armstrong writel(((m[i * 2] & 0x1fff) << 16) | 162bbbe775eSNeil Armstrong (m[i * 2 + 1] & 0x1fff), priv->io_base + 163bbbe775eSNeil Armstrong _REG(VIU_OSD1_EOTF_CTL + i + 1)); 164bbbe775eSNeil Armstrong 165bbbe775eSNeil Armstrong writel_bits_relaxed(BIT(30), csc_on ? BIT(30) : 0, 166bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_EOTF_CTL)); 167bbbe775eSNeil Armstrong writel_bits_relaxed(BIT(31), csc_on ? BIT(31) : 0, 168bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_EOTF_CTL)); 169bbbe775eSNeil Armstrong } 170bbbe775eSNeil Armstrong } 171bbbe775eSNeil Armstrong 172bbbe775eSNeil Armstrong #define OSD_EOTF_LUT_SIZE 33 173bbbe775eSNeil Armstrong #define OSD_OETF_LUT_SIZE 41 174bbbe775eSNeil Armstrong 1752ccb8433SYueHaibing static void 1762ccb8433SYueHaibing meson_viu_set_osd_lut(struct meson_drm *priv, enum viu_lut_sel_e lut_sel, 177bbbe775eSNeil Armstrong unsigned int *r_map, unsigned int *g_map, 1782ccb8433SYueHaibing unsigned int *b_map, bool csc_on) 179bbbe775eSNeil Armstrong { 180bbbe775eSNeil Armstrong unsigned int addr_port; 181bbbe775eSNeil Armstrong unsigned int data_port; 182bbbe775eSNeil Armstrong unsigned int ctrl_port; 183bbbe775eSNeil Armstrong int i; 184bbbe775eSNeil Armstrong 185bbbe775eSNeil Armstrong if (lut_sel == VIU_LUT_OSD_EOTF) { 186bbbe775eSNeil Armstrong addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT; 187bbbe775eSNeil Armstrong data_port = VIU_OSD1_EOTF_LUT_DATA_PORT; 188bbbe775eSNeil Armstrong ctrl_port = VIU_OSD1_EOTF_CTL; 189bbbe775eSNeil Armstrong } else if (lut_sel == VIU_LUT_OSD_OETF) { 190bbbe775eSNeil Armstrong addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT; 191bbbe775eSNeil Armstrong data_port = VIU_OSD1_OETF_LUT_DATA_PORT; 192bbbe775eSNeil Armstrong ctrl_port = VIU_OSD1_OETF_CTL; 193bbbe775eSNeil Armstrong } else 194bbbe775eSNeil Armstrong return; 195bbbe775eSNeil Armstrong 196bbbe775eSNeil Armstrong if (lut_sel == VIU_LUT_OSD_OETF) { 197bbbe775eSNeil Armstrong writel(0, priv->io_base + _REG(addr_port)); 198bbbe775eSNeil Armstrong 19997b2a318SLyude Paul for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++) 200bbbe775eSNeil Armstrong writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16), 201bbbe775eSNeil Armstrong priv->io_base + _REG(data_port)); 202bbbe775eSNeil Armstrong 203bbbe775eSNeil Armstrong writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16), 204bbbe775eSNeil Armstrong priv->io_base + _REG(data_port)); 205bbbe775eSNeil Armstrong 20697b2a318SLyude Paul for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++) 207bbbe775eSNeil Armstrong writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16), 208bbbe775eSNeil Armstrong priv->io_base + _REG(data_port)); 209bbbe775eSNeil Armstrong 21097b2a318SLyude Paul for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++) 211bbbe775eSNeil Armstrong writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16), 212bbbe775eSNeil Armstrong priv->io_base + _REG(data_port)); 213bbbe775eSNeil Armstrong 214bbbe775eSNeil Armstrong writel(b_map[OSD_OETF_LUT_SIZE - 1], 215bbbe775eSNeil Armstrong priv->io_base + _REG(data_port)); 216bbbe775eSNeil Armstrong 217bbbe775eSNeil Armstrong if (csc_on) 218bbbe775eSNeil Armstrong writel_bits_relaxed(0x7 << 29, 7 << 29, 219bbbe775eSNeil Armstrong priv->io_base + _REG(ctrl_port)); 220bbbe775eSNeil Armstrong else 221bbbe775eSNeil Armstrong writel_bits_relaxed(0x7 << 29, 0, 222bbbe775eSNeil Armstrong priv->io_base + _REG(ctrl_port)); 223bbbe775eSNeil Armstrong } else if (lut_sel == VIU_LUT_OSD_EOTF) { 224bbbe775eSNeil Armstrong writel(0, priv->io_base + _REG(addr_port)); 225bbbe775eSNeil Armstrong 22697b2a318SLyude Paul for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++) 227bbbe775eSNeil Armstrong writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16), 228bbbe775eSNeil Armstrong priv->io_base + _REG(data_port)); 229bbbe775eSNeil Armstrong 230bbbe775eSNeil Armstrong writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16), 231bbbe775eSNeil Armstrong priv->io_base + _REG(data_port)); 232bbbe775eSNeil Armstrong 23397b2a318SLyude Paul for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++) 234bbbe775eSNeil Armstrong writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16), 235bbbe775eSNeil Armstrong priv->io_base + _REG(data_port)); 236bbbe775eSNeil Armstrong 23797b2a318SLyude Paul for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++) 238bbbe775eSNeil Armstrong writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16), 239bbbe775eSNeil Armstrong priv->io_base + _REG(data_port)); 240bbbe775eSNeil Armstrong 241bbbe775eSNeil Armstrong writel(b_map[OSD_EOTF_LUT_SIZE - 1], 242bbbe775eSNeil Armstrong priv->io_base + _REG(data_port)); 243bbbe775eSNeil Armstrong 244bbbe775eSNeil Armstrong if (csc_on) 245bbbe775eSNeil Armstrong writel_bits_relaxed(7 << 27, 7 << 27, 246bbbe775eSNeil Armstrong priv->io_base + _REG(ctrl_port)); 247bbbe775eSNeil Armstrong else 248bbbe775eSNeil Armstrong writel_bits_relaxed(7 << 27, 0, 249bbbe775eSNeil Armstrong priv->io_base + _REG(ctrl_port)); 250bbbe775eSNeil Armstrong 251bbbe775eSNeil Armstrong writel_bits_relaxed(BIT(31), BIT(31), 252bbbe775eSNeil Armstrong priv->io_base + _REG(ctrl_port)); 253bbbe775eSNeil Armstrong } 254bbbe775eSNeil Armstrong } 255bbbe775eSNeil Armstrong 256bbbe775eSNeil Armstrong /* eotf lut: linear */ 257bbbe775eSNeil Armstrong static unsigned int eotf_33_linear_mapping[OSD_EOTF_LUT_SIZE] = { 258bbbe775eSNeil Armstrong 0x0000, 0x0200, 0x0400, 0x0600, 259bbbe775eSNeil Armstrong 0x0800, 0x0a00, 0x0c00, 0x0e00, 260bbbe775eSNeil Armstrong 0x1000, 0x1200, 0x1400, 0x1600, 261bbbe775eSNeil Armstrong 0x1800, 0x1a00, 0x1c00, 0x1e00, 262bbbe775eSNeil Armstrong 0x2000, 0x2200, 0x2400, 0x2600, 263bbbe775eSNeil Armstrong 0x2800, 0x2a00, 0x2c00, 0x2e00, 264bbbe775eSNeil Armstrong 0x3000, 0x3200, 0x3400, 0x3600, 265bbbe775eSNeil Armstrong 0x3800, 0x3a00, 0x3c00, 0x3e00, 266bbbe775eSNeil Armstrong 0x4000 267bbbe775eSNeil Armstrong }; 268bbbe775eSNeil Armstrong 269bbbe775eSNeil Armstrong /* osd oetf lut: linear */ 270bbbe775eSNeil Armstrong static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = { 271bbbe775eSNeil Armstrong 0, 0, 0, 0, 272bbbe775eSNeil Armstrong 0, 32, 64, 96, 273bbbe775eSNeil Armstrong 128, 160, 196, 224, 274bbbe775eSNeil Armstrong 256, 288, 320, 352, 275bbbe775eSNeil Armstrong 384, 416, 448, 480, 276bbbe775eSNeil Armstrong 512, 544, 576, 608, 277bbbe775eSNeil Armstrong 640, 672, 704, 736, 278bbbe775eSNeil Armstrong 768, 800, 832, 864, 279bbbe775eSNeil Armstrong 896, 928, 960, 992, 280bbbe775eSNeil Armstrong 1023, 1023, 1023, 1023, 281bbbe775eSNeil Armstrong 1023 282bbbe775eSNeil Armstrong }; 283bbbe775eSNeil Armstrong 284bbbe775eSNeil Armstrong static void meson_viu_load_matrix(struct meson_drm *priv) 285bbbe775eSNeil Armstrong { 286bbbe775eSNeil Armstrong /* eotf lut bypass */ 287bbbe775eSNeil Armstrong meson_viu_set_osd_lut(priv, VIU_LUT_OSD_EOTF, 288bbbe775eSNeil Armstrong eotf_33_linear_mapping, /* R */ 289bbbe775eSNeil Armstrong eotf_33_linear_mapping, /* G */ 290bbbe775eSNeil Armstrong eotf_33_linear_mapping, /* B */ 291bbbe775eSNeil Armstrong false); 292bbbe775eSNeil Armstrong 293bbbe775eSNeil Armstrong /* eotf matrix bypass */ 294bbbe775eSNeil Armstrong meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD_EOTF, 295bbbe775eSNeil Armstrong eotf_bypass_coeff, 296bbbe775eSNeil Armstrong false); 297bbbe775eSNeil Armstrong 298bbbe775eSNeil Armstrong /* oetf lut bypass */ 299bbbe775eSNeil Armstrong meson_viu_set_osd_lut(priv, VIU_LUT_OSD_OETF, 300bbbe775eSNeil Armstrong oetf_41_linear_mapping, /* R */ 301bbbe775eSNeil Armstrong oetf_41_linear_mapping, /* G */ 302bbbe775eSNeil Armstrong oetf_41_linear_mapping, /* B */ 303bbbe775eSNeil Armstrong false); 304bbbe775eSNeil Armstrong 305bbbe775eSNeil Armstrong /* osd matrix RGB709 to YUV709 limit */ 306bbbe775eSNeil Armstrong meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD, 307bbbe775eSNeil Armstrong RGB709_to_YUV709l_coeff, 308bbbe775eSNeil Armstrong true); 309bbbe775eSNeil Armstrong } 310bbbe775eSNeil Armstrong 3113a936bc2SNeil Armstrong /* VIU OSD1 Reset as workaround for GXL+ Alpha OSD Bug */ 3123a936bc2SNeil Armstrong void meson_viu_osd1_reset(struct meson_drm *priv) 3133a936bc2SNeil Armstrong { 3143a936bc2SNeil Armstrong uint32_t osd1_fifo_ctrl_stat, osd1_ctrl_stat2; 3153a936bc2SNeil Armstrong 3163a936bc2SNeil Armstrong /* Save these 2 registers state */ 3173a936bc2SNeil Armstrong osd1_fifo_ctrl_stat = readl_relaxed( 3183a936bc2SNeil Armstrong priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); 3193a936bc2SNeil Armstrong osd1_ctrl_stat2 = readl_relaxed( 3203a936bc2SNeil Armstrong priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); 3213a936bc2SNeil Armstrong 3223a936bc2SNeil Armstrong /* Reset OSD1 */ 3233a936bc2SNeil Armstrong writel_bits_relaxed(BIT(0), BIT(0), 3243a936bc2SNeil Armstrong priv->io_base + _REG(VIU_SW_RESET)); 3253a936bc2SNeil Armstrong writel_bits_relaxed(BIT(0), 0, 3263a936bc2SNeil Armstrong priv->io_base + _REG(VIU_SW_RESET)); 3273a936bc2SNeil Armstrong 3283a936bc2SNeil Armstrong /* Rewrite these registers state lost in the reset */ 3293a936bc2SNeil Armstrong writel_relaxed(osd1_fifo_ctrl_stat, 3303a936bc2SNeil Armstrong priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); 3313a936bc2SNeil Armstrong writel_relaxed(osd1_ctrl_stat2, 3323a936bc2SNeil Armstrong priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); 3333a936bc2SNeil Armstrong 3343a936bc2SNeil Armstrong /* Reload the conversion matrix */ 3353a936bc2SNeil Armstrong meson_viu_load_matrix(priv); 3363a936bc2SNeil Armstrong } 3373a936bc2SNeil Armstrong 338bbbe775eSNeil Armstrong void meson_viu_init(struct meson_drm *priv) 339bbbe775eSNeil Armstrong { 340bbbe775eSNeil Armstrong uint32_t reg; 341bbbe775eSNeil Armstrong 342bbbe775eSNeil Armstrong /* Disable OSDs */ 343bbbe775eSNeil Armstrong writel_bits_relaxed(BIT(0) | BIT(21), 0, 344bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_CTRL_STAT)); 345bbbe775eSNeil Armstrong writel_bits_relaxed(BIT(0) | BIT(21), 0, 346bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD2_CTRL_STAT)); 347bbbe775eSNeil Armstrong 348bbbe775eSNeil Armstrong /* On GXL/GXM, Use the 10bit HDR conversion matrix */ 349bbbe775eSNeil Armstrong if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || 350bbbe775eSNeil Armstrong meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) 351bbbe775eSNeil Armstrong meson_viu_load_matrix(priv); 35272888394SNeil Armstrong else if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) 35372888394SNeil Armstrong meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff, 35472888394SNeil Armstrong true); 355bbbe775eSNeil Armstrong 356bbbe775eSNeil Armstrong /* Initialize OSD1 fifo control register */ 357bbbe775eSNeil Armstrong reg = BIT(0) | /* Urgent DDR request priority */ 35872888394SNeil Armstrong (4 << 5); /* hold_fifo_lines */ 35972888394SNeil Armstrong if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) 36072888394SNeil Armstrong reg |= (1 << 10) | /* burst length 32 */ 36172888394SNeil Armstrong (32 << 12) | /* fifo_depth_val: 32*8=256 */ 36272888394SNeil Armstrong (2 << 22) | /* 4 words in 1 burst */ 36372888394SNeil Armstrong (2 << 24) | 36472888394SNeil Armstrong (1 << 31); 36572888394SNeil Armstrong else 36672888394SNeil Armstrong reg |= (3 << 10) | /* burst length 64 */ 367bbbe775eSNeil Armstrong (32 << 12) | /* fifo_depth_val: 32*8=256 */ 368bbbe775eSNeil Armstrong (2 << 22) | /* 4 words in 1 burst */ 369bbbe775eSNeil Armstrong (2 << 24); 370bbbe775eSNeil Armstrong writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); 371bbbe775eSNeil Armstrong writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT)); 372bbbe775eSNeil Armstrong 373bbbe775eSNeil Armstrong /* Set OSD alpha replace value */ 374bbbe775eSNeil Armstrong writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, 375bbbe775eSNeil Armstrong 0xff << OSD_REPLACE_SHIFT, 376bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); 377bbbe775eSNeil Armstrong writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, 378bbbe775eSNeil Armstrong 0xff << OSD_REPLACE_SHIFT, 379bbbe775eSNeil Armstrong priv->io_base + _REG(VIU_OSD2_CTRL_STAT2)); 380bbbe775eSNeil Armstrong 381f9a23481SNeil Armstrong /* Disable VD1 AFBC */ 382f9a23481SNeil Armstrong /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 */ 383f9a23481SNeil Armstrong writel_bits_relaxed(0x7 << 16, 0, 384f9a23481SNeil Armstrong priv->io_base + _REG(VIU_MISC_CTRL0)); 385f9a23481SNeil Armstrong /* afbc vd1 set=0 */ 386f9a23481SNeil Armstrong writel_bits_relaxed(BIT(20), 0, 387f9a23481SNeil Armstrong priv->io_base + _REG(VIU_MISC_CTRL0)); 388f9a23481SNeil Armstrong writel_relaxed(0, priv->io_base + _REG(AFBC_ENABLE)); 389f9a23481SNeil Armstrong 390f9a23481SNeil Armstrong writel_relaxed(0x00FF00C0, 391f9a23481SNeil Armstrong priv->io_base + _REG(VD1_IF0_LUMA_FIFO_SIZE)); 392f9a23481SNeil Armstrong writel_relaxed(0x00FF00C0, 393f9a23481SNeil Armstrong priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE)); 394f9a23481SNeil Armstrong 39572888394SNeil Armstrong if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) { 39672888394SNeil Armstrong writel_relaxed(4 << 29 | 39772888394SNeil Armstrong 1 << 27 | 39872888394SNeil Armstrong 1 << 26 | /* blend_din0 input to blend0 */ 39972888394SNeil Armstrong 1 << 25 | /* blend1_dout to blend2 */ 40072888394SNeil Armstrong 1 << 24 | /* blend1_din3 input to blend1 */ 40172888394SNeil Armstrong 1 << 20 | 40272888394SNeil Armstrong 0 << 16 | 40372888394SNeil Armstrong 1, 40472888394SNeil Armstrong priv->io_base + _REG(VIU_OSD_BLEND_CTRL)); 4050b84933dSNeil Armstrong writel_relaxed(1 << 20, 40672888394SNeil Armstrong priv->io_base + _REG(OSD1_BLEND_SRC_CTRL)); 40772888394SNeil Armstrong writel_relaxed(1 << 20, 40872888394SNeil Armstrong priv->io_base + _REG(OSD2_BLEND_SRC_CTRL)); 40972888394SNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VD1_BLEND_SRC_CTRL)); 41072888394SNeil Armstrong writel_relaxed(0, priv->io_base + _REG(VD2_BLEND_SRC_CTRL)); 41172888394SNeil Armstrong writel_relaxed(0, 41272888394SNeil Armstrong priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_DATA0)); 41372888394SNeil Armstrong writel_relaxed(0, 41472888394SNeil Armstrong priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_ALPHA)); 41572888394SNeil Armstrong writel_bits_relaxed(0x3 << 2, 0x3 << 2, 41672888394SNeil Armstrong priv->io_base + _REG(DOLBY_PATH_CTRL)); 41772888394SNeil Armstrong } 418f9a23481SNeil Armstrong 419bbbe775eSNeil Armstrong priv->viu.osd1_enabled = false; 420bbbe775eSNeil Armstrong priv->viu.osd1_commit = false; 421bbbe775eSNeil Armstrong priv->viu.osd1_interlace = false; 422bbbe775eSNeil Armstrong } 423