0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/export.h>
0010
0011 #include "meson_drv.h"
0012 #include "meson_registers.h"
0013 #include "meson_vpp.h"
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux)
0037 {
0038 writel(mux, priv->io_base + _REG(VPU_VIU_VENC_MUX_CTRL));
0039 }
0040
0041 static unsigned int vpp_filter_coefs_4point_bspline[] = {
0042 0x15561500, 0x14561600, 0x13561700, 0x12561800,
0043 0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,
0044 0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200,
0045 0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700,
0046 0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01,
0047 0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201,
0048 0x05473301, 0x05463401, 0x04453601, 0x04433702,
0049 0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02,
0050 0x033d3d03
0051 };
0052
0053 static void meson_vpp_write_scaling_filter_coefs(struct meson_drm *priv,
0054 const unsigned int *coefs,
0055 bool is_horizontal)
0056 {
0057 int i;
0058
0059 writel_relaxed(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
0060 priv->io_base + _REG(VPP_OSD_SCALE_COEF_IDX));
0061 for (i = 0; i < 33; i++)
0062 writel_relaxed(coefs[i],
0063 priv->io_base + _REG(VPP_OSD_SCALE_COEF));
0064 }
0065
0066 static const uint32_t vpp_filter_coefs_bicubic[] = {
0067 0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300,
0068 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900,
0069 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
0070 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe,
0071 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd,
0072 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
0073 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa,
0074 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9,
0075 0xf84848f8
0076 };
0077
0078 static void meson_vpp_write_vd_scaling_filter_coefs(struct meson_drm *priv,
0079 const unsigned int *coefs,
0080 bool is_horizontal)
0081 {
0082 int i;
0083
0084 writel_relaxed(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
0085 priv->io_base + _REG(VPP_SCALE_COEF_IDX));
0086 for (i = 0; i < 33; i++)
0087 writel_relaxed(coefs[i],
0088 priv->io_base + _REG(VPP_SCALE_COEF));
0089 }
0090
0091 void meson_vpp_init(struct meson_drm *priv)
0092 {
0093
0094 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
0095 writel_relaxed(0x108080, priv->io_base + _REG(VPP_DUMMY_DATA1));
0096 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) {
0097 writel_bits_relaxed(0xff << 16, 0xff << 16,
0098 priv->io_base + _REG(VIU_MISC_CTRL1));
0099 writel_relaxed(VPP_PPS_DUMMY_DATA_MODE,
0100 priv->io_base + _REG(VPP_DOLBY_CTRL));
0101 writel_relaxed(0x1020080,
0102 priv->io_base + _REG(VPP_DUMMY_DATA1));
0103 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
0104 writel_relaxed(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL));
0105
0106
0107 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
0108 writel_relaxed(VPP_OFIFO_SIZE_DEFAULT,
0109 priv->io_base + _REG(VPP_OFIFO_SIZE));
0110 else
0111 writel_bits_relaxed(VPP_OFIFO_SIZE_MASK, 0x77f,
0112 priv->io_base + _REG(VPP_OFIFO_SIZE));
0113 writel_relaxed(VPP_POSTBLEND_HOLD_LINES(4) | VPP_PREBLEND_HOLD_LINES(4),
0114 priv->io_base + _REG(VPP_HOLD_LINES));
0115
0116 if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
0117
0118 writel_bits_relaxed(VPP_PREBLEND_ENABLE, 0,
0119 priv->io_base + _REG(VPP_MISC));
0120
0121
0122 writel_bits_relaxed(VPP_POSTBLEND_ENABLE, 0,
0123 priv->io_base + _REG(VPP_MISC));
0124
0125
0126 writel_bits_relaxed(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND |
0127 VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND |
0128 VPP_VD1_PREBLEND | VPP_VD2_PREBLEND, 0,
0129 priv->io_base + _REG(VPP_MISC));
0130
0131
0132 writel_relaxed(4096,
0133 priv->io_base + _REG(VPP_PREBLEND_VD1_H_START_END));
0134 writel_relaxed(4096,
0135 priv->io_base + _REG(VPP_BLEND_VD2_H_START_END));
0136 }
0137
0138
0139 writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
0140 writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
0141 writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
0142
0143
0144 writel_relaxed(VPP_VSC_BANK_LENGTH(4) | VPP_HSC_BANK_LENGTH(4) |
0145 VPP_SC_VD_EN_ENABLE,
0146 priv->io_base + _REG(VPP_SC_MISC));
0147
0148
0149 writel_relaxed(VPP_MINUS_BLACK_LVL_VADJ1_ENABLE,
0150 priv->io_base + _REG(VPP_VADJ_CTRL));
0151
0152
0153 meson_vpp_write_scaling_filter_coefs(priv,
0154 vpp_filter_coefs_4point_bspline, false);
0155 meson_vpp_write_scaling_filter_coefs(priv,
0156 vpp_filter_coefs_4point_bspline, true);
0157
0158
0159 meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic,
0160 false);
0161 meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic,
0162 true);
0163 }