File Index
Files and directories
Sign in
FILE

meson_vclk.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/meson/meson_vclk.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright (C) 2016 BayLibre, SAS
   4 * Author: Neil Armstrong <narmstrong@baylibre.com>
   5 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
   6 */
   7
   8#include <linux/export.h>
   9
  10#include <drm/drm_print.h>
  11
  12#include "meson_drv.h"
  13#include "meson_vclk.h"
  14
  15/**
  16 * DOC: Video Clocks
  17 *
  18 * VCLK is the "Pixel Clock" frequency generator from a dedicated PLL.
  19 * We handle the following encodings :
  20 *
  21 * - CVBS 27MHz generator via the VCLK2 to the VENCI and VDAC blocks
  22 * - HDMI Pixel Clocks generation
  23 *
  24 * What is missing :
  25 *
  26 * - Genenate Pixel clocks for 2K/4K 10bit formats
  27 *
  28 * Clock generator scheme :
  29 *
  30 * .. code::
  31 *
  32 *    __________   _________            _____
  33 *   |          | |         |          |     |--ENCI
  34 *   | HDMI PLL |-| PLL_DIV |--- VCLK--|     |--ENCL
  35 *   |__________| |_________| \        | MUX |--ENCP
  36 *                             --VCLK2-|     |--VDAC
  37 *                                     |_____|--HDMI-TX
  38 *
  39 * Final clocks can take input for either VCLK or VCLK2, but
  40 * VCLK is the preferred path for HDMI clocking and VCLK2 is the
  41 * preferred path for CVBS VDAC clocking.
  42 *
  43 * VCLK and VCLK2 have fixed divided clocks paths for /1, /2, /4, /6 or /12.
  44 *
  45 * The PLL_DIV can achieve an additional fractional dividing like
  46 * 1.5, 3.5, 3.75... to generate special 2K and 4K 10bit clocks.
  47 */
  48
  49/* HHI Registers */
  50#define HHI_VID_PLL_CLK_DIV	0x1a0 /* 0x68 offset in data sheet */
  51#define VID_PLL_EN		BIT(19)
  52#define VID_PLL_BYPASS		BIT(18)
  53#define VID_PLL_PRESET		BIT(15)
  54#define HHI_VIID_CLK_DIV	0x128 /* 0x4a offset in data sheet */
  55#define VCLK2_DIV_MASK		0xff
  56#define VCLK2_DIV_EN		BIT(16)
  57#define VCLK2_DIV_RESET		BIT(17)
  58#define CTS_VDAC_SEL_MASK	(0xf << 28)
  59#define CTS_VDAC_SEL_SHIFT	28
  60#define HHI_VIID_CLK_CNTL	0x12c /* 0x4b offset in data sheet */
  61#define VCLK2_EN		BIT(19)
  62#define VCLK2_SEL_MASK		(0x7 << 16)
  63#define VCLK2_SEL_SHIFT		16
  64#define VCLK2_SOFT_RESET	BIT(15)
  65#define VCLK2_DIV1_EN		BIT(0)
  66#define HHI_VID_CLK_DIV		0x164 /* 0x59 offset in data sheet */
  67#define VCLK_DIV_MASK		0xff
  68#define VCLK_DIV_EN		BIT(16)
  69#define VCLK_DIV_RESET		BIT(17)
  70#define CTS_ENCP_SEL_MASK	(0xf << 24)
  71#define CTS_ENCP_SEL_SHIFT	24
  72#define CTS_ENCI_SEL_MASK	(0xf << 28)
  73#define CTS_ENCI_SEL_SHIFT	28
  74#define HHI_VID_CLK_CNTL	0x17c /* 0x5f offset in data sheet */
  75#define VCLK_EN			BIT(19)
  76#define VCLK_SEL_MASK		(0x7 << 16)
  77#define VCLK_SEL_SHIFT		16
  78#define VCLK_SOFT_RESET		BIT(15)
  79#define VCLK_DIV1_EN		BIT(0)
  80#define VCLK_DIV2_EN		BIT(1)
  81#define VCLK_DIV4_EN		BIT(2)
  82#define VCLK_DIV6_EN		BIT(3)
  83#define VCLK_DIV12_EN		BIT(4)
  84#define HHI_VID_CLK_CNTL2	0x194 /* 0x65 offset in data sheet */
  85#define CTS_ENCI_EN		BIT(0)
  86#define CTS_ENCP_EN		BIT(2)
  87#define CTS_VDAC_EN		BIT(4)
  88#define HDMI_TX_PIXEL_EN	BIT(5)
  89#define HHI_HDMI_CLK_CNTL	0x1cc /* 0x73 offset in data sheet */
  90#define HDMI_TX_PIXEL_SEL_MASK	(0xf << 16)
  91#define HDMI_TX_PIXEL_SEL_SHIFT	16
  92#define CTS_HDMI_SYS_SEL_MASK	(0x7 << 9)
  93#define CTS_HDMI_SYS_DIV_MASK	(0x7f)
  94#define CTS_HDMI_SYS_EN		BIT(8)
  95
  96#define HHI_VDAC_CNTL0		0x2F4 /* 0xbd offset in data sheet */
  97#define HHI_VDAC_CNTL1		0x2F8 /* 0xbe offset in data sheet */
  98
  99#define HHI_HDMI_PLL_CNTL	0x320 /* 0xc8 offset in data sheet */
 100#define HHI_HDMI_PLL_CNTL_EN	BIT(30)
 101#define HHI_HDMI_PLL_CNTL2	0x324 /* 0xc9 offset in data sheet */
 102#define HHI_HDMI_PLL_CNTL3	0x328 /* 0xca offset in data sheet */
 103#define HHI_HDMI_PLL_CNTL4	0x32C /* 0xcb offset in data sheet */
 104#define HHI_HDMI_PLL_CNTL5	0x330 /* 0xcc offset in data sheet */
 105#define HHI_HDMI_PLL_CNTL6	0x334 /* 0xcd offset in data sheet */
 106#define HHI_HDMI_PLL_CNTL7	0x338 /* 0xce offset in data sheet */
 107
 108#define HDMI_PLL_RESET		BIT(28)
 109#define HDMI_PLL_RESET_G12A	BIT(29)
 110#define HDMI_PLL_LOCK		BIT(31)
 111#define HDMI_PLL_LOCK_G12A	(3 << 30)
 112
 113#define FREQ_1000_1001(_freq)	DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL)
 114
 115/* VID PLL Dividers */
 116enum {
 117	VID_PLL_DIV_1 = 0,
 118	VID_PLL_DIV_2,
 119	VID_PLL_DIV_2p5,
 120	VID_PLL_DIV_3,
 121	VID_PLL_DIV_3p5,
 122	VID_PLL_DIV_3p75,
 123	VID_PLL_DIV_4,
 124	VID_PLL_DIV_5,
 125	VID_PLL_DIV_6,
 126	VID_PLL_DIV_6p25,
 127	VID_PLL_DIV_7,
 128	VID_PLL_DIV_7p5,
 129	VID_PLL_DIV_12,
 130	VID_PLL_DIV_14,
 131	VID_PLL_DIV_15,
 132};
 133
 134static void meson_vid_pll_set(struct meson_drm *priv, unsigned int div)
 135{
 136	unsigned int shift_val = 0;
 137	unsigned int shift_sel = 0;
 138
 139	/* Disable vid_pll output clock */
 140	regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
 141	regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
 142
 143	switch (div) {
 144	case VID_PLL_DIV_2:
 145		shift_val = 0x0aaa;
 146		shift_sel = 0;
 147		break;
 148	case VID_PLL_DIV_2p5:
 149		shift_val = 0x5294;
 150		shift_sel = 2;
 151		break;
 152	case VID_PLL_DIV_3:
 153		shift_val = 0x0db6;
 154		shift_sel = 0;
 155		break;
 156	case VID_PLL_DIV_3p5:
 157		shift_val = 0x36cc;
 158		shift_sel = 1;
 159		break;
 160	case VID_PLL_DIV_3p75:
 161		shift_val = 0x6666;
 162		shift_sel = 2;
 163		break;
 164	case VID_PLL_DIV_4:
 165		shift_val = 0x0ccc;
 166		shift_sel = 0;
 167		break;
 168	case VID_PLL_DIV_5:
 169		shift_val = 0x739c;
 170		shift_sel = 2;
 171		break;
 172	case VID_PLL_DIV_6:
 173		shift_val = 0x0e38;
 174		shift_sel = 0;
 175		break;
 176	case VID_PLL_DIV_6p25:
 177		shift_val = 0x0000;
 178		shift_sel = 3;
 179		break;
 180	case VID_PLL_DIV_7:
 181		shift_val = 0x3c78;
 182		shift_sel = 1;
 183		break;
 184	case VID_PLL_DIV_7p5:
 185		shift_val = 0x78f0;
 186		shift_sel = 2;
 187		break;
 188	case VID_PLL_DIV_12:
 189		shift_val = 0x0fc0;
 190		shift_sel = 0;
 191		break;
 192	case VID_PLL_DIV_14:
 193		shift_val = 0x3f80;
 194		shift_sel = 1;
 195		break;
 196	case VID_PLL_DIV_15:
 197		shift_val = 0x7f80;
 198		shift_sel = 2;
 199		break;
 200	}
 201
 202	if (div == VID_PLL_DIV_1)
 203		/* Enable vid_pll bypass to HDMI pll */
 204		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
 205				   VID_PLL_BYPASS, VID_PLL_BYPASS);
 206	else {
 207		/* Disable Bypass */
 208		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
 209				   VID_PLL_BYPASS, 0);
 210		/* Clear sel */
 211		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
 212				   3 << 16, 0);
 213		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
 214				   VID_PLL_PRESET, 0);
 215		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
 216				   0x7fff, 0);
 217
 218		/* Setup sel and val */
 219		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
 220				   3 << 16, shift_sel << 16);
 221		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
 222				   VID_PLL_PRESET, VID_PLL_PRESET);
 223		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
 224				   0x7fff, shift_val);
 225
 226		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
 227				   VID_PLL_PRESET, 0);
 228	}
 229
 230	/* Enable the vid_pll output clock */
 231	regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
 232				VID_PLL_EN, VID_PLL_EN);
 233}
 234
 235/*
 236 * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC
 237 *
 238 * TOFIX: Refactor into table to also handle HDMI frequency and paths
 239 */
 240static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
 241{
 242	unsigned int val;
 243
 244	/* Setup PLL to output 1.485GHz */
 245	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
 246		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
 247		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00404e00);
 248		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
 249		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
 250		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
 251		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
 252		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4800023d);
 253
 254		/* Poll for lock bit */
 255		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
 256					 (val & HDMI_PLL_LOCK), 10, 0);
 257	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
 258		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
 259		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
 260		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
 261		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0xa6212844);
 262		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
 263		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
 264		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
 265
 266		/* Reset PLL */
 267		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 268					HDMI_PLL_RESET, HDMI_PLL_RESET);
 269		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 270					HDMI_PLL_RESET, 0);
 271
 272		/* Poll for lock bit */
 273		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
 274					 (val & HDMI_PLL_LOCK), 10, 0);
 275	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
 276		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x1a0504f7);
 277		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00010000);
 278		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x00000000);
 279		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x6a28dc00);
 280		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x65771290);
 281		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39272000);
 282		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x56540000);
 283		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x3a0504f7);
 284		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x1a0504f7);
 285
 286		/* Poll for lock bit */
 287		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
 288			((val & HDMI_PLL_LOCK_G12A) == HDMI_PLL_LOCK_G12A),
 289			10, 0);
 290	}
 291
 292	/* Disable VCLK2 */
 293	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
 294
 295	/* Setup vid_pll to /1 */
 296	meson_vid_pll_set(priv, VID_PLL_DIV_1);
 297
 298	/* Setup the VCLK2 divider value to achieve 27MHz */
 299	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
 300				VCLK2_DIV_MASK, (55 - 1));
 301
 302	/* select vid_pll for vclk2 */
 303	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
 304		regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
 305					VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT));
 306	else
 307		regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
 308					VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
 309
 310	/* enable vclk2 gate */
 311	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
 312
 313	/* select vclk_div1 for enci */
 314	regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
 315				CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
 316	/* select vclk_div1 for vdac */
 317	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
 318				CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
 319
 320	/* release vclk2_div_reset and enable vclk2_div */
 321	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
 322				VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
 323
 324	/* enable vclk2_div1 gate */
 325	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
 326				VCLK2_DIV1_EN, VCLK2_DIV1_EN);
 327
 328	/* reset vclk2 */
 329	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
 330				VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
 331	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
 332				VCLK2_SOFT_RESET, 0);
 333
 334	/* enable enci_clk */
 335	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
 336				CTS_ENCI_EN, CTS_ENCI_EN);
 337	/* enable vdac_clk */
 338	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
 339				CTS_VDAC_EN, CTS_VDAC_EN);
 340}
 341
 342enum {
 343/* PLL	O1 O2 O3 VP DV     EN TX */
 344/* 4320 /4 /4 /1 /5 /1  => /2 /2 */
 345	MESON_VCLK_HDMI_ENCI_54000 = 0,
 346/* 4320 /4 /4 /1 /5 /1  => /1 /2 */
 347	MESON_VCLK_HDMI_DDR_54000,
 348/* 2970 /4 /1 /1 /5 /1  => /1 /2 */
 349	MESON_VCLK_HDMI_DDR_148500,
 350/* 2970 /2 /2 /2 /5 /1  => /1 /1 */
 351	MESON_VCLK_HDMI_74250,
 352/* 2970 /1 /2 /2 /5 /1  => /1 /1 */
 353	MESON_VCLK_HDMI_148500,
 354/* 2970 /1 /1 /1 /5 /2  => /1 /1 */
 355	MESON_VCLK_HDMI_297000,
 356/* 5940 /1 /1 /2 /5 /1  => /1 /1 */
 357	MESON_VCLK_HDMI_594000,
 358/* 2970 /1 /1 /1 /5 /1  => /1 /2 */
 359	MESON_VCLK_HDMI_594000_YUV420,
 360};
 361
 362struct meson_vclk_params {
 363	unsigned long long pll_freq;
 364	unsigned long long phy_freq;
 365	unsigned long long vclk_freq;
 366	unsigned long long venc_freq;
 367	unsigned long long pixel_freq;
 368	unsigned int pll_od1;
 369	unsigned int pll_od2;
 370	unsigned int pll_od3;
 371	unsigned int vid_pll_div;
 372	unsigned int vclk_div;
 373} params[] = {
 374	[MESON_VCLK_HDMI_ENCI_54000] = {
 375		.pll_freq = 4320000000,
 376		.phy_freq = 270000000,
 377		.vclk_freq = 54000000,
 378		.venc_freq = 54000000,
 379		.pixel_freq = 54000000,
 380		.pll_od1 = 4,
 381		.pll_od2 = 4,
 382		.pll_od3 = 1,
 383		.vid_pll_div = VID_PLL_DIV_5,
 384		.vclk_div = 1,
 385	},
 386	[MESON_VCLK_HDMI_DDR_54000] = {
 387		.pll_freq = 4320000000,
 388		.phy_freq = 270000000,
 389		.vclk_freq = 54000000,
 390		.venc_freq = 54000000,
 391		.pixel_freq = 27000000,
 392		.pll_od1 = 4,
 393		.pll_od2 = 4,
 394		.pll_od3 = 1,
 395		.vid_pll_div = VID_PLL_DIV_5,
 396		.vclk_div = 1,
 397	},
 398	[MESON_VCLK_HDMI_DDR_148500] = {
 399		.pll_freq = 2970000000,
 400		.phy_freq = 742500000,
 401		.vclk_freq = 148500000,
 402		.venc_freq = 148500000,
 403		.pixel_freq = 74250000,
 404		.pll_od1 = 4,
 405		.pll_od2 = 1,
 406		.pll_od3 = 1,
 407		.vid_pll_div = VID_PLL_DIV_5,
 408		.vclk_div = 1,
 409	},
 410	[MESON_VCLK_HDMI_74250] = {
 411		.pll_freq = 2970000000,
 412		.phy_freq = 742500000,
 413		.vclk_freq = 74250000,
 414		.venc_freq = 74250000,
 415		.pixel_freq = 74250000,
 416		.pll_od1 = 2,
 417		.pll_od2 = 2,
 418		.pll_od3 = 2,
 419		.vid_pll_div = VID_PLL_DIV_5,
 420		.vclk_div = 1,
 421	},
 422	[MESON_VCLK_HDMI_148500] = {
 423		.pll_freq = 2970000000,
 424		.phy_freq = 1485000000,
 425		.vclk_freq = 148500000,
 426		.venc_freq = 148500000,
 427		.pixel_freq = 148500000,
 428		.pll_od1 = 1,
 429		.pll_od2 = 2,
 430		.pll_od3 = 2,
 431		.vid_pll_div = VID_PLL_DIV_5,
 432		.vclk_div = 1,
 433	},
 434	[MESON_VCLK_HDMI_297000] = {
 435		.pll_freq = 5940000000,
 436		.phy_freq = 2970000000,
 437		.venc_freq = 297000000,
 438		.vclk_freq = 297000000,
 439		.pixel_freq = 297000000,
 440		.pll_od1 = 2,
 441		.pll_od2 = 1,
 442		.pll_od3 = 1,
 443		.vid_pll_div = VID_PLL_DIV_5,
 444		.vclk_div = 2,
 445	},
 446	[MESON_VCLK_HDMI_594000] = {
 447		.pll_freq = 5940000000,
 448		.phy_freq = 5940000000,
 449		.venc_freq = 594000000,
 450		.vclk_freq = 594000000,
 451		.pixel_freq = 594000000,
 452		.pll_od1 = 1,
 453		.pll_od2 = 1,
 454		.pll_od3 = 2,
 455		.vid_pll_div = VID_PLL_DIV_5,
 456		.vclk_div = 1,
 457	},
 458	[MESON_VCLK_HDMI_594000_YUV420] = {
 459		.pll_freq = 5940000000,
 460		.phy_freq = 2970000000,
 461		.venc_freq = 594000000,
 462		.vclk_freq = 594000000,
 463		.pixel_freq = 297000000,
 464		.pll_od1 = 2,
 465		.pll_od2 = 1,
 466		.pll_od3 = 1,
 467		.vid_pll_div = VID_PLL_DIV_5,
 468		.vclk_div = 1,
 469	},
 470	{ /* sentinel */ },
 471};
 472
 473static inline unsigned int pll_od_to_reg(unsigned int od)
 474{
 475	switch (od) {
 476	case 1:
 477		return 0;
 478	case 2:
 479		return 1;
 480	case 4:
 481		return 2;
 482	case 8:
 483		return 3;
 484	}
 485
 486	/* Invalid */
 487	return 0;
 488}
 489
 490static void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
 491				      unsigned int frac, unsigned int od1,
 492				      unsigned int od2, unsigned int od3)
 493{
 494	unsigned int val;
 495
 496	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
 497		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000200 | m);
 498		if (frac)
 499			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2,
 500				     0x00004000 | frac);
 501		else
 502			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2,
 503				     0x00000000);
 504		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
 505		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
 506		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
 507		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
 508
 509		/* Enable and unreset */
 510		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 511				   0x7 << 28, HHI_HDMI_PLL_CNTL_EN);
 512
 513		/* Poll for lock bit */
 514		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
 515					 val, (val & HDMI_PLL_LOCK), 10, 0);
 516	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
 517		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
 518		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000200 | m);
 519		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac);
 520		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
 521		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
 522		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
 523		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
 524
 525		/* Reset PLL */
 526		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 527				HDMI_PLL_RESET, HDMI_PLL_RESET);
 528		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 529				HDMI_PLL_RESET, 0);
 530
 531		/* Poll for lock bit */
 532		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
 533				(val & HDMI_PLL_LOCK), 10, 0);
 534	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
 535		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x0b3a0400 | m);
 536
 537		/* Enable and reset */
 538		/* TODO: add specific macro for g12a here */
 539		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 540				   0x3 << 28, 0x3 << 28);
 541
 542		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, frac);
 543		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x00000000);
 544
 545		/* G12A HDMI PLL Needs specific parameters for 5.4GHz */
 546		if (m >= 0xf7) {
 547			if (frac < 0x10000) {
 548				regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4,
 549							0x6a685c00);
 550				regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5,
 551							0x11551293);
 552			} else {
 553				regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4,
 554							0xea68dc00);
 555				regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5,
 556							0x65771290);
 557			}
 558			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39272000);
 559			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x55540000);
 560		} else {
 561			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0a691c00);
 562			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x33771290);
 563			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39270000);
 564			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x50540000);
 565		}
 566
 567		do {
 568			/* Reset PLL */
 569			regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 570					HDMI_PLL_RESET_G12A, HDMI_PLL_RESET_G12A);
 571
 572			/* UN-Reset PLL */
 573			regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 574					HDMI_PLL_RESET_G12A, 0);
 575
 576			/* Poll for lock bits */
 577			if (!regmap_read_poll_timeout(priv->hhi,
 578						      HHI_HDMI_PLL_CNTL, val,
 579						      ((val & HDMI_PLL_LOCK_G12A)
 580						        == HDMI_PLL_LOCK_G12A),
 581						      10, 100))
 582				break;
 583		} while(1);
 584	}
 585
 586	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
 587		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
 588				3 << 16, pll_od_to_reg(od1) << 16);
 589	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
 590		 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
 591		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
 592				3 << 21, pll_od_to_reg(od1) << 21);
 593	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
 594		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 595				3 << 16, pll_od_to_reg(od1) << 16);
 596
 597	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
 598		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
 599				3 << 22, pll_od_to_reg(od2) << 22);
 600	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
 601		 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
 602		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
 603				3 << 23, pll_od_to_reg(od2) << 23);
 604	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
 605		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 606				3 << 18, pll_od_to_reg(od2) << 18);
 607
 608	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
 609		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
 610				3 << 18, pll_od_to_reg(od3) << 18);
 611	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
 612		 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
 613		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
 614				3 << 19, pll_od_to_reg(od3) << 19);
 615	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
 616		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
 617				3 << 20, pll_od_to_reg(od3) << 20);
 618}
 619
 620#define XTAL_FREQ (24 * 1000 * 1000)
 621
 622static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv,
 623					 unsigned long long pll_freq)
 624{
 625	/* The GXBB PLL has a /2 pre-multiplier */
 626	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
 627		pll_freq = DIV_ROUND_DOWN_ULL(pll_freq, 2);
 628
 629	return DIV_ROUND_DOWN_ULL(pll_freq, XTAL_FREQ);
 630}
 631
 632#define HDMI_FRAC_MAX_GXBB	4096
 633#define HDMI_FRAC_MAX_GXL	1024
 634#define HDMI_FRAC_MAX_G12A	131072
 635
 636static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
 637					    unsigned int m,
 638					    unsigned long long pll_freq)
 639{
 640	unsigned long long parent_freq = XTAL_FREQ;
 641	unsigned int frac_max = HDMI_FRAC_MAX_GXL;
 642	unsigned int frac_m;
 643	unsigned int frac;
 644	u32 remainder;
 645
 646	/* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */
 647	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
 648		frac_max = HDMI_FRAC_MAX_GXBB;
 649		parent_freq *= 2;
 650	}
 651
 652	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
 653		frac_max = HDMI_FRAC_MAX_G12A;
 654
 655	/* We can have a perfect match !*/
 656	if (div_u64_rem(pll_freq, m, &remainder) == parent_freq &&
 657	    remainder == 0)
 658		return 0;
 659
 660	frac = mul_u64_u64_div_u64(pll_freq, frac_max, parent_freq);
 661	frac_m = m * frac_max;
 662	if (frac_m > frac)
 663		return frac_max;
 664	frac -= frac_m;
 665
 666	return min((u16)frac, (u16)(frac_max - 1));
 667}
 668
 669static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
 670					   unsigned long long m,
 671					   unsigned int frac)
 672{
 673	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
 674		/* Empiric supported min/max dividers */
 675		if (m < 53 || m > 123)
 676			return false;
 677		if (frac >= HDMI_FRAC_MAX_GXBB)
 678			return false;
 679	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
 680		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
 681		/* Empiric supported min/max dividers */
 682		if (m < 106 || m > 247)
 683			return false;
 684		if (frac >= HDMI_FRAC_MAX_GXL)
 685			return false;
 686	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
 687		/* Empiric supported min/max dividers */
 688		if (m < 106 || m > 247)
 689			return false;
 690		if (frac >= HDMI_FRAC_MAX_G12A)
 691			return false;
 692	}
 693
 694	return true;
 695}
 696
 697static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
 698				       unsigned long long freq,
 699				       unsigned int *m,
 700				       unsigned int *frac,
 701				       unsigned int *od)
 702{
 703	/* Cycle from /16 to /2 */
 704	for (*od = 16 ; *od > 1 ; *od >>= 1) {
 705		*m = meson_hdmi_pll_get_m(priv, freq * *od);
 706		if (!*m)
 707			continue;
 708		*frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
 709
 710		DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d\n",
 711				 freq, *m, *frac, *od);
 712
 713		if (meson_hdmi_pll_validate_params(priv, *m, *frac))
 714			return true;
 715	}
 716
 717	return false;
 718}
 719
 720/* pll_freq is the frequency after the OD dividers */
 721enum drm_mode_status
 722meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq)
 723{
 724	unsigned int od, m, frac;
 725
 726	/* In DMT mode, path after PLL is always /10 */
 727	freq *= 10;
 728
 729	/* Check against soc revision/package limits */
 730	if (priv->limits) {
 731		if (priv->limits->max_hdmi_phy_freq &&
 732		    freq > priv->limits->max_hdmi_phy_freq)
 733			return MODE_CLOCK_HIGH;
 734	}
 735
 736	if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od))
 737		return MODE_OK;
 738
 739	return MODE_CLOCK_RANGE;
 740}
 741EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq);
 742
 743/* pll_freq is the frequency after the OD dividers */
 744static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
 745				       unsigned long long pll_freq)
 746{
 747	unsigned int od, m, frac, od1, od2, od3;
 748
 749	if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
 750		/* OD2 goes to the PHY, and needs to be *10, so keep OD3=1 */
 751		od3 = 1;
 752		if (od < 4) {
 753			od1 = 2;
 754			od2 = 1;
 755		} else {
 756			od2 = od / 4;
 757			od1 = od / od2;
 758		}
 759
 760		DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d/%d/%d\n",
 761				 pll_freq, m, frac, od1, od2, od3);
 762
 763		meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
 764
 765		return;
 766	}
 767
 768	DRM_ERROR("Fatal, unable to find parameters for PLL freq %lluHz\n",
 769		  pll_freq);
 770}
 771
 772static bool meson_vclk_freqs_are_matching_param(unsigned int idx,
 773						unsigned long long phy_freq,
 774						unsigned long long vclk_freq)
 775{
 776	DRM_DEBUG_DRIVER("i = %d vclk_freq = %lluHz alt = %lluHz\n",
 777			 idx, params[idx].vclk_freq,
 778			 FREQ_1000_1001(params[idx].vclk_freq));
 779	DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n",
 780			 idx, params[idx].phy_freq,
 781			 FREQ_1000_1001(params[idx].phy_freq));
 782
 783	/* Match strict frequency */
 784	if (phy_freq == params[idx].phy_freq &&
 785	    vclk_freq == params[idx].vclk_freq)
 786		return true;
 787
 788	/* Match 1000/1001 variant: vclk deviation has to be less than 1kHz
 789	 * (drm EDID is defined in 1kHz steps, so everything smaller must be
 790	 * rounding error) and the PHY freq deviation has to be less than
 791	 * 10kHz (as the TMDS clock is 10 times the pixel clock, so anything
 792	 * smaller must be rounding error as well).
 793	 */
 794	if (abs(vclk_freq - FREQ_1000_1001(params[idx].vclk_freq)) < 1000 &&
 795	    abs(phy_freq - FREQ_1000_1001(params[idx].phy_freq)) < 10000)
 796		return true;
 797
 798	/* no match */
 799	return false;
 800}
 801
 802enum drm_mode_status
 803meson_vclk_vic_supported_freq(struct meson_drm *priv,
 804			      unsigned long long phy_freq,
 805			      unsigned long long vclk_freq)
 806{
 807	int i;
 808
 809	DRM_DEBUG_DRIVER("phy_freq = %lluHz vclk_freq = %lluHz\n",
 810			 phy_freq, vclk_freq);
 811
 812	/* Check against soc revision/package limits */
 813	if (priv->limits) {
 814		if (priv->limits->max_hdmi_phy_freq &&
 815		    phy_freq > priv->limits->max_hdmi_phy_freq)
 816			return MODE_CLOCK_HIGH;
 817	}
 818
 819	for (i = 0 ; params[i].pixel_freq ; ++i) {
 820		if (meson_vclk_freqs_are_matching_param(i, phy_freq, vclk_freq))
 821			return MODE_OK;
 822	}
 823
 824	return MODE_CLOCK_RANGE;
 825}
 826EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq);
 827
 828static void meson_vclk_set(struct meson_drm *priv,
 829			   unsigned long long pll_base_freq, unsigned int od1,
 830			   unsigned int od2, unsigned int od3,
 831			   unsigned int vid_pll_div, unsigned int vclk_div,
 832			   unsigned int hdmi_tx_div, unsigned int venc_div,
 833			   bool hdmi_use_enci, bool vic_alternate_clock)
 834{
 835	unsigned int m = 0, frac = 0;
 836
 837	/* Set HDMI-TX sys clock */
 838	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
 839			   CTS_HDMI_SYS_SEL_MASK, 0);
 840	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
 841			   CTS_HDMI_SYS_DIV_MASK, 0);
 842	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
 843			   CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
 844
 845	/* Set HDMI PLL rate */
 846	if (!od1 && !od2 && !od3) {
 847		meson_hdmi_pll_generic_set(priv, pll_base_freq);
 848	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
 849		switch (pll_base_freq) {
 850		case 2970000000:
 851			m = 0x3d;
 852			frac = vic_alternate_clock ? 0xd02 : 0xe00;
 853			break;
 854		case 4320000000:
 855			m = vic_alternate_clock ? 0x59 : 0x5a;
 856			frac = vic_alternate_clock ? 0xe8f : 0;
 857			break;
 858		case 5940000000:
 859			m = 0x7b;
 860			frac = vic_alternate_clock ? 0xa05 : 0xc00;
 861			break;
 862		}
 863
 864		meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
 865	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
 866		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
 867		switch (pll_base_freq) {
 868		case 2970000000:
 869			m = 0x7b;
 870			frac = vic_alternate_clock ? 0x281 : 0x300;
 871			break;
 872		case 4320000000:
 873			m = vic_alternate_clock ? 0xb3 : 0xb4;
 874			frac = vic_alternate_clock ? 0x347 : 0;
 875			break;
 876		case 5940000000:
 877			m = 0xf7;
 878			frac = vic_alternate_clock ? 0x102 : 0x200;
 879			break;
 880		}
 881
 882		meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
 883	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
 884		switch (pll_base_freq) {
 885		case 2970000000:
 886			m = 0x7b;
 887			frac = vic_alternate_clock ? 0x140b4 : 0x18000;
 888			break;
 889		case 4320000000:
 890			m = vic_alternate_clock ? 0xb3 : 0xb4;
 891			frac = vic_alternate_clock ? 0x1a3ee : 0;
 892			break;
 893		case 5940000000:
 894			m = 0xf7;
 895			frac = vic_alternate_clock ? 0x8148 : 0x10000;
 896			break;
 897		}
 898
 899		meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
 900	}
 901
 902	/* Setup vid_pll divider */
 903	meson_vid_pll_set(priv, vid_pll_div);
 904
 905	/* Set VCLK div */
 906	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
 907			   VCLK_SEL_MASK, 0);
 908	regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
 909			   VCLK_DIV_MASK, vclk_div - 1);
 910
 911	/* Set HDMI-TX source */
 912	switch (hdmi_tx_div) {
 913	case 1:
 914		/* enable vclk_div1 gate */
 915		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
 916				   VCLK_DIV1_EN, VCLK_DIV1_EN);
 917
 918		/* select vclk_div1 for HDMI-TX */
 919		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
 920				   HDMI_TX_PIXEL_SEL_MASK, 0);
 921		break;
 922	case 2:
 923		/* enable vclk_div2 gate */
 924		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
 925				   VCLK_DIV2_EN, VCLK_DIV2_EN);
 926
 927		/* select vclk_div2 for HDMI-TX */
 928		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
 929			HDMI_TX_PIXEL_SEL_MASK, 1 << HDMI_TX_PIXEL_SEL_SHIFT);
 930		break;
 931	case 4:
 932		/* enable vclk_div4 gate */
 933		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
 934				   VCLK_DIV4_EN, VCLK_DIV4_EN);
 935
 936		/* select vclk_div4 for HDMI-TX */
 937		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
 938			HDMI_TX_PIXEL_SEL_MASK, 2 << HDMI_TX_PIXEL_SEL_SHIFT);
 939		break;
 940	case 6:
 941		/* enable vclk_div6 gate */
 942		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
 943				   VCLK_DIV6_EN, VCLK_DIV6_EN);
 944
 945		/* select vclk_div6 for HDMI-TX */
 946		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
 947			HDMI_TX_PIXEL_SEL_MASK, 3 << HDMI_TX_PIXEL_SEL_SHIFT);
 948		break;
 949	case 12:
 950		/* enable vclk_div12 gate */
 951		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
 952				   VCLK_DIV12_EN, VCLK_DIV12_EN);
 953
 954		/* select vclk_div12 for HDMI-TX */
 955		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
 956			HDMI_TX_PIXEL_SEL_MASK, 4 << HDMI_TX_PIXEL_SEL_SHIFT);
 957		break;
 958	}
 959	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
 960				   HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
 961
 962	/* Set ENCI/ENCP Source */
 963	switch (venc_div) {
 964	case 1:
 965		/* enable vclk_div1 gate */
 966		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
 967				   VCLK_DIV1_EN, VCLK_DIV1_EN);
 968
 969		if (hdmi_use_enci)
 970			/* select vclk_div1 for enci */
 971			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
 972					   CTS_ENCI_SEL_MASK, 0);
 973		else
 974			/* select vclk_div1 for encp */
 975			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
 976					   CTS_ENCP_SEL_MASK, 0);
 977		break;
 978	case 2:
 979		/* enable vclk_div2 gate */
 980		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
 981				   VCLK_DIV2_EN, VCLK_DIV2_EN);
 982
 983		if (hdmi_use_enci)
 984			/* select vclk_div2 for enci */
 985			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
 986				CTS_ENCI_SEL_MASK, 1 << CTS_ENCI_SEL_SHIFT);
 987		else
 988			/* select vclk_div2 for encp */
 989			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
 990				CTS_ENCP_SEL_MASK, 1 << CTS_ENCP_SEL_SHIFT);
 991		break;
 992	case 4:
 993		/* enable vclk_div4 gate */
 994		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
 995				   VCLK_DIV4_EN, VCLK_DIV4_EN);
 996
 997		if (hdmi_use_enci)
 998			/* select vclk_div4 for enci */
 999			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
1000				CTS_ENCI_SEL_MASK, 2 << CTS_ENCI_SEL_SHIFT);
1001		else
1002			/* select vclk_div4 for encp */
1003			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
1004				CTS_ENCP_SEL_MASK, 2 << CTS_ENCP_SEL_SHIFT);
1005		break;
1006	case 6:
1007		/* enable vclk_div6 gate */
1008		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
1009				   VCLK_DIV6_EN, VCLK_DIV6_EN);
1010
1011		if (hdmi_use_enci)
1012			/* select vclk_div6 for enci */
1013			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
1014				CTS_ENCI_SEL_MASK, 3 << CTS_ENCI_SEL_SHIFT);
1015		else
1016			/* select vclk_div6 for encp */
1017			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
1018				CTS_ENCP_SEL_MASK, 3 << CTS_ENCP_SEL_SHIFT);
1019		break;
1020	case 12:
1021		/* enable vclk_div12 gate */
1022		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
1023				   VCLK_DIV12_EN, VCLK_DIV12_EN);
1024
1025		if (hdmi_use_enci)
1026			/* select vclk_div12 for enci */
1027			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
1028				CTS_ENCI_SEL_MASK, 4 << CTS_ENCI_SEL_SHIFT);
1029		else
1030			/* select vclk_div12 for encp */
1031			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
1032				CTS_ENCP_SEL_MASK, 4 << CTS_ENCP_SEL_SHIFT);
1033		break;
1034	}
1035
1036	if (hdmi_use_enci)
1037		/* Enable ENCI clock gate */
1038		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
1039				   CTS_ENCI_EN, CTS_ENCI_EN);
1040	else
1041		/* Enable ENCP clock gate */
1042		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
1043				   CTS_ENCP_EN, CTS_ENCP_EN);
1044
1045	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
1046}
1047
1048void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
1049		      unsigned long long phy_freq, unsigned long long vclk_freq,
1050		      unsigned long long venc_freq, unsigned long long dac_freq,
1051		      bool hdmi_use_enci)
1052{
1053	bool vic_alternate_clock = false;
1054	unsigned long long freq;
1055	unsigned long long hdmi_tx_div;
1056	unsigned long long venc_div;
1057
1058	if (target == MESON_VCLK_TARGET_CVBS) {
1059		meson_venci_cvbs_clock_config(priv);
1060		return;
1061	} else if (target == MESON_VCLK_TARGET_DMT) {
1062		/*
1063		 * The DMT clock path is fixed after the PLL:
1064		 * - automatic PLL freq + OD management
1065		 * - vid_pll_div = VID_PLL_DIV_5
1066		 * - vclk_div = 2
1067		 * - hdmi_tx_div = 1
1068		 * - venc_div = 1
1069		 * - encp encoder
1070		 */
1071		meson_vclk_set(priv, phy_freq, 0, 0, 0,
1072			       VID_PLL_DIV_5, 2, 1, 1, false, false);
1073		return;
1074	}
1075
1076	hdmi_tx_div = DIV_ROUND_DOWN_ULL(vclk_freq, dac_freq);
1077
1078	if (hdmi_tx_div == 0) {
1079		pr_err("Fatal Error, invalid HDMI-TX freq %lluHz\n",
1080		       dac_freq);
1081		return;
1082	}
1083
1084	venc_div = DIV_ROUND_DOWN_ULL(vclk_freq, venc_freq);
1085
1086	if (venc_div == 0) {
1087		pr_err("Fatal Error, invalid HDMI venc freq %lluHz\n",
1088		       venc_freq);
1089		return;
1090	}
1091
1092	for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
1093		if (meson_vclk_freqs_are_matching_param(freq, phy_freq,
1094							vclk_freq)) {
1095			if (vclk_freq != params[freq].vclk_freq)
1096				vic_alternate_clock = true;
1097			else
1098				vic_alternate_clock = false;
1099
1100			if (freq == MESON_VCLK_HDMI_ENCI_54000 &&
1101			    !hdmi_use_enci)
1102				continue;
1103
1104			if (freq == MESON_VCLK_HDMI_DDR_54000 &&
1105			    hdmi_use_enci)
1106				continue;
1107
1108			if (freq == MESON_VCLK_HDMI_DDR_148500 &&
1109			    dac_freq == vclk_freq)
1110				continue;
1111
1112			if (freq == MESON_VCLK_HDMI_148500 &&
1113			    dac_freq != vclk_freq)
1114				continue;
1115			break;
1116		}
1117	}
1118
1119	if (!params[freq].pixel_freq) {
1120		pr_err("Fatal Error, invalid HDMI vclk freq %lluHz\n",
1121		       vclk_freq);
1122		return;
1123	}
1124
1125	meson_vclk_set(priv, params[freq].pll_freq,
1126		       params[freq].pll_od1, params[freq].pll_od2,
1127		       params[freq].pll_od3, params[freq].vid_pll_div,
1128		       params[freq].vclk_div, hdmi_tx_div, venc_div,
1129		       hdmi_use_enci, vic_alternate_clock);
1130}
1131EXPORT_SYMBOL_GPL(meson_vclk_setup);
~/ Read-only file preview.