0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/export.h>
0009
0010 #include <drm/drm_print.h>
0011
0012 #include "meson_drv.h"
0013 #include "meson_vclk.h"
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #define HHI_VID_PLL_CLK_DIV 0x1a0
0051 #define VID_PLL_EN BIT(19)
0052 #define VID_PLL_BYPASS BIT(18)
0053 #define VID_PLL_PRESET BIT(15)
0054 #define HHI_VIID_CLK_DIV 0x128
0055 #define VCLK2_DIV_MASK 0xff
0056 #define VCLK2_DIV_EN BIT(16)
0057 #define VCLK2_DIV_RESET BIT(17)
0058 #define CTS_VDAC_SEL_MASK (0xf << 28)
0059 #define CTS_VDAC_SEL_SHIFT 28
0060 #define HHI_VIID_CLK_CNTL 0x12c
0061 #define VCLK2_EN BIT(19)
0062 #define VCLK2_SEL_MASK (0x7 << 16)
0063 #define VCLK2_SEL_SHIFT 16
0064 #define VCLK2_SOFT_RESET BIT(15)
0065 #define VCLK2_DIV1_EN BIT(0)
0066 #define HHI_VID_CLK_DIV 0x164
0067 #define VCLK_DIV_MASK 0xff
0068 #define VCLK_DIV_EN BIT(16)
0069 #define VCLK_DIV_RESET BIT(17)
0070 #define CTS_ENCP_SEL_MASK (0xf << 24)
0071 #define CTS_ENCP_SEL_SHIFT 24
0072 #define CTS_ENCI_SEL_MASK (0xf << 28)
0073 #define CTS_ENCI_SEL_SHIFT 28
0074 #define HHI_VID_CLK_CNTL 0x17c
0075 #define VCLK_EN BIT(19)
0076 #define VCLK_SEL_MASK (0x7 << 16)
0077 #define VCLK_SEL_SHIFT 16
0078 #define VCLK_SOFT_RESET BIT(15)
0079 #define VCLK_DIV1_EN BIT(0)
0080 #define VCLK_DIV2_EN BIT(1)
0081 #define VCLK_DIV4_EN BIT(2)
0082 #define VCLK_DIV6_EN BIT(3)
0083 #define VCLK_DIV12_EN BIT(4)
0084 #define HHI_VID_CLK_CNTL2 0x194
0085 #define CTS_ENCI_EN BIT(0)
0086 #define CTS_ENCP_EN BIT(2)
0087 #define CTS_VDAC_EN BIT(4)
0088 #define HDMI_TX_PIXEL_EN BIT(5)
0089 #define HHI_HDMI_CLK_CNTL 0x1cc
0090 #define HDMI_TX_PIXEL_SEL_MASK (0xf << 16)
0091 #define HDMI_TX_PIXEL_SEL_SHIFT 16
0092 #define CTS_HDMI_SYS_SEL_MASK (0x7 << 9)
0093 #define CTS_HDMI_SYS_DIV_MASK (0x7f)
0094 #define CTS_HDMI_SYS_EN BIT(8)
0095
0096 #define HHI_VDAC_CNTL0 0x2F4
0097 #define HHI_VDAC_CNTL1 0x2F8
0098
0099 #define HHI_HDMI_PLL_CNTL 0x320
0100 #define HHI_HDMI_PLL_CNTL_EN BIT(30)
0101 #define HHI_HDMI_PLL_CNTL2 0x324
0102 #define HHI_HDMI_PLL_CNTL3 0x328
0103 #define HHI_HDMI_PLL_CNTL4 0x32C
0104 #define HHI_HDMI_PLL_CNTL5 0x330
0105 #define HHI_HDMI_PLL_CNTL6 0x334
0106 #define HHI_HDMI_PLL_CNTL7 0x338
0107
0108 #define HDMI_PLL_RESET BIT(28)
0109 #define HDMI_PLL_RESET_G12A BIT(29)
0110 #define HDMI_PLL_LOCK BIT(31)
0111 #define HDMI_PLL_LOCK_G12A (3 << 30)
0112
0113 #define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001)
0114
0115
0116 enum {
0117 VID_PLL_DIV_1 = 0,
0118 VID_PLL_DIV_2,
0119 VID_PLL_DIV_2p5,
0120 VID_PLL_DIV_3,
0121 VID_PLL_DIV_3p5,
0122 VID_PLL_DIV_3p75,
0123 VID_PLL_DIV_4,
0124 VID_PLL_DIV_5,
0125 VID_PLL_DIV_6,
0126 VID_PLL_DIV_6p25,
0127 VID_PLL_DIV_7,
0128 VID_PLL_DIV_7p5,
0129 VID_PLL_DIV_12,
0130 VID_PLL_DIV_14,
0131 VID_PLL_DIV_15,
0132 };
0133
0134 static void meson_vid_pll_set(struct meson_drm *priv, unsigned int div)
0135 {
0136 unsigned int shift_val = 0;
0137 unsigned int shift_sel = 0;
0138
0139
0140 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
0141 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
0142
0143 switch (div) {
0144 case VID_PLL_DIV_2:
0145 shift_val = 0x0aaa;
0146 shift_sel = 0;
0147 break;
0148 case VID_PLL_DIV_2p5:
0149 shift_val = 0x5294;
0150 shift_sel = 2;
0151 break;
0152 case VID_PLL_DIV_3:
0153 shift_val = 0x0db6;
0154 shift_sel = 0;
0155 break;
0156 case VID_PLL_DIV_3p5:
0157 shift_val = 0x36cc;
0158 shift_sel = 1;
0159 break;
0160 case VID_PLL_DIV_3p75:
0161 shift_val = 0x6666;
0162 shift_sel = 2;
0163 break;
0164 case VID_PLL_DIV_4:
0165 shift_val = 0x0ccc;
0166 shift_sel = 0;
0167 break;
0168 case VID_PLL_DIV_5:
0169 shift_val = 0x739c;
0170 shift_sel = 2;
0171 break;
0172 case VID_PLL_DIV_6:
0173 shift_val = 0x0e38;
0174 shift_sel = 0;
0175 break;
0176 case VID_PLL_DIV_6p25:
0177 shift_val = 0x0000;
0178 shift_sel = 3;
0179 break;
0180 case VID_PLL_DIV_7:
0181 shift_val = 0x3c78;
0182 shift_sel = 1;
0183 break;
0184 case VID_PLL_DIV_7p5:
0185 shift_val = 0x78f0;
0186 shift_sel = 2;
0187 break;
0188 case VID_PLL_DIV_12:
0189 shift_val = 0x0fc0;
0190 shift_sel = 0;
0191 break;
0192 case VID_PLL_DIV_14:
0193 shift_val = 0x3f80;
0194 shift_sel = 1;
0195 break;
0196 case VID_PLL_DIV_15:
0197 shift_val = 0x7f80;
0198 shift_sel = 2;
0199 break;
0200 }
0201
0202 if (div == VID_PLL_DIV_1)
0203
0204 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
0205 VID_PLL_BYPASS, VID_PLL_BYPASS);
0206 else {
0207
0208 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
0209 VID_PLL_BYPASS, 0);
0210
0211 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
0212 3 << 16, 0);
0213 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
0214 VID_PLL_PRESET, 0);
0215 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
0216 0x7fff, 0);
0217
0218
0219 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
0220 3 << 16, shift_sel << 16);
0221 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
0222 VID_PLL_PRESET, VID_PLL_PRESET);
0223 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
0224 0x7fff, shift_val);
0225
0226 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
0227 VID_PLL_PRESET, 0);
0228 }
0229
0230
0231 regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
0232 VID_PLL_EN, VID_PLL_EN);
0233 }
0234
0235
0236
0237
0238
0239
0240 static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
0241 {
0242 unsigned int val;
0243
0244
0245 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
0246 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
0247 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00404e00);
0248 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
0249 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
0250 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
0251 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
0252 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4800023d);
0253
0254
0255 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
0256 (val & HDMI_PLL_LOCK), 10, 0);
0257 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
0258 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
0259 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
0260 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
0261 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0xa6212844);
0262 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
0263 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
0264 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
0265
0266
0267 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0268 HDMI_PLL_RESET, HDMI_PLL_RESET);
0269 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0270 HDMI_PLL_RESET, 0);
0271
0272
0273 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
0274 (val & HDMI_PLL_LOCK), 10, 0);
0275 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
0276 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x1a0504f7);
0277 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00010000);
0278 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x00000000);
0279 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x6a28dc00);
0280 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x65771290);
0281 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39272000);
0282 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x56540000);
0283 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x3a0504f7);
0284 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x1a0504f7);
0285
0286
0287 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
0288 ((val & HDMI_PLL_LOCK_G12A) == HDMI_PLL_LOCK_G12A),
0289 10, 0);
0290 }
0291
0292
0293 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
0294
0295
0296 meson_vid_pll_set(priv, VID_PLL_DIV_1);
0297
0298
0299 regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
0300 VCLK2_DIV_MASK, (55 - 1));
0301
0302
0303 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
0304 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
0305 VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT));
0306 else
0307 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
0308 VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
0309
0310
0311 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
0312
0313
0314 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
0315 CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
0316
0317 regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
0318 CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
0319
0320
0321 regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
0322 VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
0323
0324
0325 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
0326 VCLK2_DIV1_EN, VCLK2_DIV1_EN);
0327
0328
0329 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
0330 VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
0331 regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
0332 VCLK2_SOFT_RESET, 0);
0333
0334
0335 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
0336 CTS_ENCI_EN, CTS_ENCI_EN);
0337
0338 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
0339 CTS_VDAC_EN, CTS_VDAC_EN);
0340 }
0341
0342 enum {
0343
0344
0345 MESON_VCLK_HDMI_ENCI_54000 = 0,
0346
0347 MESON_VCLK_HDMI_DDR_54000,
0348
0349 MESON_VCLK_HDMI_DDR_148500,
0350
0351 MESON_VCLK_HDMI_74250,
0352
0353 MESON_VCLK_HDMI_148500,
0354
0355 MESON_VCLK_HDMI_297000,
0356
0357 MESON_VCLK_HDMI_594000,
0358
0359 MESON_VCLK_HDMI_594000_YUV420,
0360 };
0361
0362 struct meson_vclk_params {
0363 unsigned int pll_freq;
0364 unsigned int phy_freq;
0365 unsigned int vclk_freq;
0366 unsigned int venc_freq;
0367 unsigned int pixel_freq;
0368 unsigned int pll_od1;
0369 unsigned int pll_od2;
0370 unsigned int pll_od3;
0371 unsigned int vid_pll_div;
0372 unsigned int vclk_div;
0373 } params[] = {
0374 [MESON_VCLK_HDMI_ENCI_54000] = {
0375 .pll_freq = 4320000,
0376 .phy_freq = 270000,
0377 .vclk_freq = 54000,
0378 .venc_freq = 54000,
0379 .pixel_freq = 54000,
0380 .pll_od1 = 4,
0381 .pll_od2 = 4,
0382 .pll_od3 = 1,
0383 .vid_pll_div = VID_PLL_DIV_5,
0384 .vclk_div = 1,
0385 },
0386 [MESON_VCLK_HDMI_DDR_54000] = {
0387 .pll_freq = 4320000,
0388 .phy_freq = 270000,
0389 .vclk_freq = 54000,
0390 .venc_freq = 54000,
0391 .pixel_freq = 27000,
0392 .pll_od1 = 4,
0393 .pll_od2 = 4,
0394 .pll_od3 = 1,
0395 .vid_pll_div = VID_PLL_DIV_5,
0396 .vclk_div = 1,
0397 },
0398 [MESON_VCLK_HDMI_DDR_148500] = {
0399 .pll_freq = 2970000,
0400 .phy_freq = 742500,
0401 .vclk_freq = 148500,
0402 .venc_freq = 148500,
0403 .pixel_freq = 74250,
0404 .pll_od1 = 4,
0405 .pll_od2 = 1,
0406 .pll_od3 = 1,
0407 .vid_pll_div = VID_PLL_DIV_5,
0408 .vclk_div = 1,
0409 },
0410 [MESON_VCLK_HDMI_74250] = {
0411 .pll_freq = 2970000,
0412 .phy_freq = 742500,
0413 .vclk_freq = 74250,
0414 .venc_freq = 74250,
0415 .pixel_freq = 74250,
0416 .pll_od1 = 2,
0417 .pll_od2 = 2,
0418 .pll_od3 = 2,
0419 .vid_pll_div = VID_PLL_DIV_5,
0420 .vclk_div = 1,
0421 },
0422 [MESON_VCLK_HDMI_148500] = {
0423 .pll_freq = 2970000,
0424 .phy_freq = 1485000,
0425 .vclk_freq = 148500,
0426 .venc_freq = 148500,
0427 .pixel_freq = 148500,
0428 .pll_od1 = 1,
0429 .pll_od2 = 2,
0430 .pll_od3 = 2,
0431 .vid_pll_div = VID_PLL_DIV_5,
0432 .vclk_div = 1,
0433 },
0434 [MESON_VCLK_HDMI_297000] = {
0435 .pll_freq = 5940000,
0436 .phy_freq = 2970000,
0437 .venc_freq = 297000,
0438 .vclk_freq = 297000,
0439 .pixel_freq = 297000,
0440 .pll_od1 = 2,
0441 .pll_od2 = 1,
0442 .pll_od3 = 1,
0443 .vid_pll_div = VID_PLL_DIV_5,
0444 .vclk_div = 2,
0445 },
0446 [MESON_VCLK_HDMI_594000] = {
0447 .pll_freq = 5940000,
0448 .phy_freq = 5940000,
0449 .venc_freq = 594000,
0450 .vclk_freq = 594000,
0451 .pixel_freq = 594000,
0452 .pll_od1 = 1,
0453 .pll_od2 = 1,
0454 .pll_od3 = 2,
0455 .vid_pll_div = VID_PLL_DIV_5,
0456 .vclk_div = 1,
0457 },
0458 [MESON_VCLK_HDMI_594000_YUV420] = {
0459 .pll_freq = 5940000,
0460 .phy_freq = 2970000,
0461 .venc_freq = 594000,
0462 .vclk_freq = 594000,
0463 .pixel_freq = 297000,
0464 .pll_od1 = 2,
0465 .pll_od2 = 1,
0466 .pll_od3 = 1,
0467 .vid_pll_div = VID_PLL_DIV_5,
0468 .vclk_div = 1,
0469 },
0470 { },
0471 };
0472
0473 static inline unsigned int pll_od_to_reg(unsigned int od)
0474 {
0475 switch (od) {
0476 case 1:
0477 return 0;
0478 case 2:
0479 return 1;
0480 case 4:
0481 return 2;
0482 case 8:
0483 return 3;
0484 }
0485
0486
0487 return 0;
0488 }
0489
0490 static void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
0491 unsigned int frac, unsigned int od1,
0492 unsigned int od2, unsigned int od3)
0493 {
0494 unsigned int val;
0495
0496 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
0497 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000200 | m);
0498 if (frac)
0499 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2,
0500 0x00004000 | frac);
0501 else
0502 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2,
0503 0x00000000);
0504 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
0505 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
0506 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
0507 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
0508
0509
0510 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0511 0x7 << 28, HHI_HDMI_PLL_CNTL_EN);
0512
0513
0514 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
0515 val, (val & HDMI_PLL_LOCK), 10, 0);
0516 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
0517 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
0518 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000200 | m);
0519 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac);
0520 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
0521 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
0522 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
0523 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
0524
0525
0526 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0527 HDMI_PLL_RESET, HDMI_PLL_RESET);
0528 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0529 HDMI_PLL_RESET, 0);
0530
0531
0532 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
0533 (val & HDMI_PLL_LOCK), 10, 0);
0534 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
0535 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x0b3a0400 | m);
0536
0537
0538
0539 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0540 0x3 << 28, 0x3 << 28);
0541
0542 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, frac);
0543 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x00000000);
0544
0545
0546 if (m >= 0xf7) {
0547 if (frac < 0x10000) {
0548 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4,
0549 0x6a685c00);
0550 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5,
0551 0x11551293);
0552 } else {
0553 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4,
0554 0xea68dc00);
0555 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5,
0556 0x65771290);
0557 }
0558 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39272000);
0559 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x55540000);
0560 } else {
0561 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0a691c00);
0562 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x33771290);
0563 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39270000);
0564 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x50540000);
0565 }
0566
0567 do {
0568
0569 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0570 HDMI_PLL_RESET_G12A, HDMI_PLL_RESET_G12A);
0571
0572
0573 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0574 HDMI_PLL_RESET_G12A, 0);
0575
0576
0577 if (!regmap_read_poll_timeout(priv->hhi,
0578 HHI_HDMI_PLL_CNTL, val,
0579 ((val & HDMI_PLL_LOCK_G12A)
0580 == HDMI_PLL_LOCK_G12A),
0581 10, 100))
0582 break;
0583 } while(1);
0584 }
0585
0586 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
0587 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
0588 3 << 16, pll_od_to_reg(od1) << 16);
0589 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
0590 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
0591 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
0592 3 << 21, pll_od_to_reg(od1) << 21);
0593 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
0594 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0595 3 << 16, pll_od_to_reg(od1) << 16);
0596
0597 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
0598 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
0599 3 << 22, pll_od_to_reg(od2) << 22);
0600 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
0601 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
0602 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
0603 3 << 23, pll_od_to_reg(od2) << 23);
0604 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
0605 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0606 3 << 18, pll_od_to_reg(od2) << 18);
0607
0608 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
0609 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
0610 3 << 18, pll_od_to_reg(od3) << 18);
0611 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
0612 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
0613 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
0614 3 << 19, pll_od_to_reg(od3) << 19);
0615 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
0616 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0617 3 << 20, pll_od_to_reg(od3) << 20);
0618 }
0619
0620 #define XTAL_FREQ 24000
0621
0622 static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv,
0623 unsigned int pll_freq)
0624 {
0625
0626 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
0627 pll_freq /= 2;
0628
0629 return pll_freq / XTAL_FREQ;
0630 }
0631
0632 #define HDMI_FRAC_MAX_GXBB 4096
0633 #define HDMI_FRAC_MAX_GXL 1024
0634 #define HDMI_FRAC_MAX_G12A 131072
0635
0636 static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
0637 unsigned int m,
0638 unsigned int pll_freq)
0639 {
0640 unsigned int parent_freq = XTAL_FREQ;
0641 unsigned int frac_max = HDMI_FRAC_MAX_GXL;
0642 unsigned int frac_m;
0643 unsigned int frac;
0644
0645
0646 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
0647 frac_max = HDMI_FRAC_MAX_GXBB;
0648 parent_freq *= 2;
0649 }
0650
0651 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
0652 frac_max = HDMI_FRAC_MAX_G12A;
0653
0654
0655 if (pll_freq / m == parent_freq &&
0656 pll_freq % m == 0)
0657 return 0;
0658
0659 frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq);
0660 frac_m = m * frac_max;
0661 if (frac_m > frac)
0662 return frac_max;
0663 frac -= frac_m;
0664
0665 return min((u16)frac, (u16)(frac_max - 1));
0666 }
0667
0668 static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
0669 unsigned int m,
0670 unsigned int frac)
0671 {
0672 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
0673
0674 if (m < 53 || m > 123)
0675 return false;
0676 if (frac >= HDMI_FRAC_MAX_GXBB)
0677 return false;
0678 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
0679 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
0680
0681 if (m < 106 || m > 247)
0682 return false;
0683 if (frac >= HDMI_FRAC_MAX_GXL)
0684 return false;
0685 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
0686
0687 if (m < 106 || m > 247)
0688 return false;
0689 if (frac >= HDMI_FRAC_MAX_G12A)
0690 return false;
0691 }
0692
0693 return true;
0694 }
0695
0696 static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
0697 unsigned int freq,
0698 unsigned int *m,
0699 unsigned int *frac,
0700 unsigned int *od)
0701 {
0702
0703 for (*od = 16 ; *od > 1 ; *od >>= 1) {
0704 *m = meson_hdmi_pll_get_m(priv, freq * *od);
0705 if (!*m)
0706 continue;
0707 *frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
0708
0709 DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d\n",
0710 freq, *m, *frac, *od);
0711
0712 if (meson_hdmi_pll_validate_params(priv, *m, *frac))
0713 return true;
0714 }
0715
0716 return false;
0717 }
0718
0719
0720 enum drm_mode_status
0721 meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq)
0722 {
0723 unsigned int od, m, frac;
0724
0725
0726 freq *= 10;
0727
0728
0729 if (priv->limits) {
0730 if (priv->limits->max_hdmi_phy_freq &&
0731 freq > priv->limits->max_hdmi_phy_freq)
0732 return MODE_CLOCK_HIGH;
0733 }
0734
0735 if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od))
0736 return MODE_OK;
0737
0738 return MODE_CLOCK_RANGE;
0739 }
0740 EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq);
0741
0742
0743 static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
0744 unsigned int pll_freq)
0745 {
0746 unsigned int od, m, frac, od1, od2, od3;
0747
0748 if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
0749
0750 od3 = 1;
0751 if (od < 4) {
0752 od1 = 2;
0753 od2 = 1;
0754 } else {
0755 od2 = od / 4;
0756 od1 = od / od2;
0757 }
0758
0759 DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n",
0760 pll_freq, m, frac, od1, od2, od3);
0761
0762 meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
0763
0764 return;
0765 }
0766
0767 DRM_ERROR("Fatal, unable to find parameters for PLL freq %d\n",
0768 pll_freq);
0769 }
0770
0771 enum drm_mode_status
0772 meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
0773 unsigned int vclk_freq)
0774 {
0775 int i;
0776
0777 DRM_DEBUG_DRIVER("phy_freq = %d vclk_freq = %d\n",
0778 phy_freq, vclk_freq);
0779
0780
0781 if (priv->limits) {
0782 if (priv->limits->max_hdmi_phy_freq &&
0783 phy_freq > priv->limits->max_hdmi_phy_freq)
0784 return MODE_CLOCK_HIGH;
0785 }
0786
0787 for (i = 0 ; params[i].pixel_freq ; ++i) {
0788 DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n",
0789 i, params[i].pixel_freq,
0790 FREQ_1000_1001(params[i].pixel_freq));
0791 DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n",
0792 i, params[i].phy_freq,
0793 FREQ_1000_1001(params[i].phy_freq/10)*10);
0794
0795 if (phy_freq == params[i].phy_freq &&
0796 vclk_freq == params[i].vclk_freq)
0797 return MODE_OK;
0798
0799 if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) &&
0800 vclk_freq == FREQ_1000_1001(params[i].vclk_freq))
0801 return MODE_OK;
0802 }
0803
0804 return MODE_CLOCK_RANGE;
0805 }
0806 EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq);
0807
0808 static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
0809 unsigned int od1, unsigned int od2, unsigned int od3,
0810 unsigned int vid_pll_div, unsigned int vclk_div,
0811 unsigned int hdmi_tx_div, unsigned int venc_div,
0812 bool hdmi_use_enci, bool vic_alternate_clock)
0813 {
0814 unsigned int m = 0, frac = 0;
0815
0816
0817 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
0818 CTS_HDMI_SYS_SEL_MASK, 0);
0819 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
0820 CTS_HDMI_SYS_DIV_MASK, 0);
0821 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
0822 CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
0823
0824
0825 if (!od1 && !od2 && !od3) {
0826 meson_hdmi_pll_generic_set(priv, pll_base_freq);
0827 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
0828 switch (pll_base_freq) {
0829 case 2970000:
0830 m = 0x3d;
0831 frac = vic_alternate_clock ? 0xd02 : 0xe00;
0832 break;
0833 case 4320000:
0834 m = vic_alternate_clock ? 0x59 : 0x5a;
0835 frac = vic_alternate_clock ? 0xe8f : 0;
0836 break;
0837 case 5940000:
0838 m = 0x7b;
0839 frac = vic_alternate_clock ? 0xa05 : 0xc00;
0840 break;
0841 }
0842
0843 meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
0844 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
0845 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
0846 switch (pll_base_freq) {
0847 case 2970000:
0848 m = 0x7b;
0849 frac = vic_alternate_clock ? 0x281 : 0x300;
0850 break;
0851 case 4320000:
0852 m = vic_alternate_clock ? 0xb3 : 0xb4;
0853 frac = vic_alternate_clock ? 0x347 : 0;
0854 break;
0855 case 5940000:
0856 m = 0xf7;
0857 frac = vic_alternate_clock ? 0x102 : 0x200;
0858 break;
0859 }
0860
0861 meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
0862 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
0863 switch (pll_base_freq) {
0864 case 2970000:
0865 m = 0x7b;
0866 frac = vic_alternate_clock ? 0x140b4 : 0x18000;
0867 break;
0868 case 4320000:
0869 m = vic_alternate_clock ? 0xb3 : 0xb4;
0870 frac = vic_alternate_clock ? 0x1a3ee : 0;
0871 break;
0872 case 5940000:
0873 m = 0xf7;
0874 frac = vic_alternate_clock ? 0x8148 : 0x10000;
0875 break;
0876 }
0877
0878 meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
0879 }
0880
0881
0882 meson_vid_pll_set(priv, vid_pll_div);
0883
0884
0885 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
0886 VCLK_SEL_MASK, 0);
0887 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
0888 VCLK_DIV_MASK, vclk_div - 1);
0889
0890
0891 switch (hdmi_tx_div) {
0892 case 1:
0893
0894 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
0895 VCLK_DIV1_EN, VCLK_DIV1_EN);
0896
0897
0898 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
0899 HDMI_TX_PIXEL_SEL_MASK, 0);
0900 break;
0901 case 2:
0902
0903 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
0904 VCLK_DIV2_EN, VCLK_DIV2_EN);
0905
0906
0907 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
0908 HDMI_TX_PIXEL_SEL_MASK, 1 << HDMI_TX_PIXEL_SEL_SHIFT);
0909 break;
0910 case 4:
0911
0912 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
0913 VCLK_DIV4_EN, VCLK_DIV4_EN);
0914
0915
0916 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
0917 HDMI_TX_PIXEL_SEL_MASK, 2 << HDMI_TX_PIXEL_SEL_SHIFT);
0918 break;
0919 case 6:
0920
0921 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
0922 VCLK_DIV6_EN, VCLK_DIV6_EN);
0923
0924
0925 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
0926 HDMI_TX_PIXEL_SEL_MASK, 3 << HDMI_TX_PIXEL_SEL_SHIFT);
0927 break;
0928 case 12:
0929
0930 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
0931 VCLK_DIV12_EN, VCLK_DIV12_EN);
0932
0933
0934 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
0935 HDMI_TX_PIXEL_SEL_MASK, 4 << HDMI_TX_PIXEL_SEL_SHIFT);
0936 break;
0937 }
0938 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
0939 HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
0940
0941
0942 switch (venc_div) {
0943 case 1:
0944
0945 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
0946 VCLK_DIV1_EN, VCLK_DIV1_EN);
0947
0948 if (hdmi_use_enci)
0949
0950 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
0951 CTS_ENCI_SEL_MASK, 0);
0952 else
0953
0954 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
0955 CTS_ENCP_SEL_MASK, 0);
0956 break;
0957 case 2:
0958
0959 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
0960 VCLK_DIV2_EN, VCLK_DIV2_EN);
0961
0962 if (hdmi_use_enci)
0963
0964 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
0965 CTS_ENCI_SEL_MASK, 1 << CTS_ENCI_SEL_SHIFT);
0966 else
0967
0968 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
0969 CTS_ENCP_SEL_MASK, 1 << CTS_ENCP_SEL_SHIFT);
0970 break;
0971 case 4:
0972
0973 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
0974 VCLK_DIV4_EN, VCLK_DIV4_EN);
0975
0976 if (hdmi_use_enci)
0977
0978 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
0979 CTS_ENCI_SEL_MASK, 2 << CTS_ENCI_SEL_SHIFT);
0980 else
0981
0982 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
0983 CTS_ENCP_SEL_MASK, 2 << CTS_ENCP_SEL_SHIFT);
0984 break;
0985 case 6:
0986
0987 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
0988 VCLK_DIV6_EN, VCLK_DIV6_EN);
0989
0990 if (hdmi_use_enci)
0991
0992 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
0993 CTS_ENCI_SEL_MASK, 3 << CTS_ENCI_SEL_SHIFT);
0994 else
0995
0996 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
0997 CTS_ENCP_SEL_MASK, 3 << CTS_ENCP_SEL_SHIFT);
0998 break;
0999 case 12:
1000
1001 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
1002 VCLK_DIV12_EN, VCLK_DIV12_EN);
1003
1004 if (hdmi_use_enci)
1005
1006 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
1007 CTS_ENCI_SEL_MASK, 4 << CTS_ENCI_SEL_SHIFT);
1008 else
1009
1010 regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
1011 CTS_ENCP_SEL_MASK, 4 << CTS_ENCP_SEL_SHIFT);
1012 break;
1013 }
1014
1015 if (hdmi_use_enci)
1016
1017 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
1018 CTS_ENCI_EN, CTS_ENCI_EN);
1019 else
1020
1021 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
1022 CTS_ENCP_EN, CTS_ENCP_EN);
1023
1024 regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
1025 }
1026
1027 void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
1028 unsigned int phy_freq, unsigned int vclk_freq,
1029 unsigned int venc_freq, unsigned int dac_freq,
1030 bool hdmi_use_enci)
1031 {
1032 bool vic_alternate_clock = false;
1033 unsigned int freq;
1034 unsigned int hdmi_tx_div;
1035 unsigned int venc_div;
1036
1037 if (target == MESON_VCLK_TARGET_CVBS) {
1038 meson_venci_cvbs_clock_config(priv);
1039 return;
1040 } else if (target == MESON_VCLK_TARGET_DMT) {
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050 meson_vclk_set(priv, phy_freq, 0, 0, 0,
1051 VID_PLL_DIV_5, 2, 1, 1, false, false);
1052 return;
1053 }
1054
1055 hdmi_tx_div = vclk_freq / dac_freq;
1056
1057 if (hdmi_tx_div == 0) {
1058 pr_err("Fatal Error, invalid HDMI-TX freq %d\n",
1059 dac_freq);
1060 return;
1061 }
1062
1063 venc_div = vclk_freq / venc_freq;
1064
1065 if (venc_div == 0) {
1066 pr_err("Fatal Error, invalid HDMI venc freq %d\n",
1067 venc_freq);
1068 return;
1069 }
1070
1071 for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
1072 if ((phy_freq == params[freq].phy_freq ||
1073 phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) &&
1074 (vclk_freq == params[freq].vclk_freq ||
1075 vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) {
1076 if (vclk_freq != params[freq].vclk_freq)
1077 vic_alternate_clock = true;
1078 else
1079 vic_alternate_clock = false;
1080
1081 if (freq == MESON_VCLK_HDMI_ENCI_54000 &&
1082 !hdmi_use_enci)
1083 continue;
1084
1085 if (freq == MESON_VCLK_HDMI_DDR_54000 &&
1086 hdmi_use_enci)
1087 continue;
1088
1089 if (freq == MESON_VCLK_HDMI_DDR_148500 &&
1090 dac_freq == vclk_freq)
1091 continue;
1092
1093 if (freq == MESON_VCLK_HDMI_148500 &&
1094 dac_freq != vclk_freq)
1095 continue;
1096 break;
1097 }
1098 }
1099
1100 if (!params[freq].pixel_freq) {
1101 pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq);
1102 return;
1103 }
1104
1105 meson_vclk_set(priv, params[freq].pll_freq,
1106 params[freq].pll_od1, params[freq].pll_od2,
1107 params[freq].pll_od3, params[freq].vid_pll_div,
1108 params[freq].vclk_div, hdmi_tx_div, venc_div,
1109 hdmi_use_enci, vic_alternate_clock);
1110 }
1111 EXPORT_SYMBOL_GPL(meson_vclk_setup);