Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.17-rc1 533 lines 15 kB view raw
1/* 2 * Copyright (c) 2014 MediaTek Inc. 3 * Author: Jie Qiu <jie.qiu@mediatek.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 15#include <linux/clk.h> 16#include <linux/clk-provider.h> 17#include <linux/delay.h> 18#include <linux/io.h> 19#include <linux/mfd/syscon.h> 20#include <linux/module.h> 21#include <linux/phy/phy.h> 22#include <linux/platform_device.h> 23#include <linux/types.h> 24 25#define HDMI_CON0 0x00 26#define RG_HDMITX_PLL_EN BIT(31) 27#define RG_HDMITX_PLL_FBKDIV (0x7f << 24) 28#define PLL_FBKDIV_SHIFT 24 29#define RG_HDMITX_PLL_FBKSEL (0x3 << 22) 30#define PLL_FBKSEL_SHIFT 22 31#define RG_HDMITX_PLL_PREDIV (0x3 << 20) 32#define PREDIV_SHIFT 20 33#define RG_HDMITX_PLL_POSDIV (0x3 << 18) 34#define POSDIV_SHIFT 18 35#define RG_HDMITX_PLL_RST_DLY (0x3 << 16) 36#define RG_HDMITX_PLL_IR (0xf << 12) 37#define PLL_IR_SHIFT 12 38#define RG_HDMITX_PLL_IC (0xf << 8) 39#define PLL_IC_SHIFT 8 40#define RG_HDMITX_PLL_BP (0xf << 4) 41#define PLL_BP_SHIFT 4 42#define RG_HDMITX_PLL_BR (0x3 << 2) 43#define PLL_BR_SHIFT 2 44#define RG_HDMITX_PLL_BC (0x3 << 0) 45#define PLL_BC_SHIFT 0 46#define HDMI_CON1 0x04 47#define RG_HDMITX_PLL_DIVEN (0x7 << 29) 48#define PLL_DIVEN_SHIFT 29 49#define RG_HDMITX_PLL_AUTOK_EN BIT(28) 50#define RG_HDMITX_PLL_AUTOK_KF (0x3 << 26) 51#define RG_HDMITX_PLL_AUTOK_KS (0x3 << 24) 52#define RG_HDMITX_PLL_AUTOK_LOAD BIT(23) 53#define RG_HDMITX_PLL_BAND (0x3f << 16) 54#define RG_HDMITX_PLL_REF_SEL BIT(15) 55#define RG_HDMITX_PLL_BIAS_EN BIT(14) 56#define RG_HDMITX_PLL_BIAS_LPF_EN BIT(13) 57#define RG_HDMITX_PLL_TXDIV_EN BIT(12) 58#define RG_HDMITX_PLL_TXDIV (0x3 << 10) 59#define PLL_TXDIV_SHIFT 10 60#define RG_HDMITX_PLL_LVROD_EN BIT(9) 61#define RG_HDMITX_PLL_MONVC_EN BIT(8) 62#define RG_HDMITX_PLL_MONCK_EN BIT(7) 63#define RG_HDMITX_PLL_MONREF_EN BIT(6) 64#define RG_HDMITX_PLL_TST_EN BIT(5) 65#define RG_HDMITX_PLL_TST_CK_EN BIT(4) 66#define RG_HDMITX_PLL_TST_SEL (0xf << 0) 67#define HDMI_CON2 0x08 68#define RGS_HDMITX_PLL_AUTOK_BAND (0x7f << 8) 69#define RGS_HDMITX_PLL_AUTOK_FAIL BIT(1) 70#define RG_HDMITX_EN_TX_CKLDO BIT(0) 71#define HDMI_CON3 0x0c 72#define RG_HDMITX_SER_EN (0xf << 28) 73#define RG_HDMITX_PRD_EN (0xf << 24) 74#define RG_HDMITX_PRD_IMP_EN (0xf << 20) 75#define RG_HDMITX_DRV_EN (0xf << 16) 76#define RG_HDMITX_DRV_IMP_EN (0xf << 12) 77#define DRV_IMP_EN_SHIFT 12 78#define RG_HDMITX_MHLCK_FORCE BIT(10) 79#define RG_HDMITX_MHLCK_PPIX_EN BIT(9) 80#define RG_HDMITX_MHLCK_EN BIT(8) 81#define RG_HDMITX_SER_DIN_SEL (0xf << 4) 82#define RG_HDMITX_SER_5T1_BIST_EN BIT(3) 83#define RG_HDMITX_SER_BIST_TOG BIT(2) 84#define RG_HDMITX_SER_DIN_TOG BIT(1) 85#define RG_HDMITX_SER_CLKDIG_INV BIT(0) 86#define HDMI_CON4 0x10 87#define RG_HDMITX_PRD_IBIAS_CLK (0xf << 24) 88#define RG_HDMITX_PRD_IBIAS_D2 (0xf << 16) 89#define RG_HDMITX_PRD_IBIAS_D1 (0xf << 8) 90#define RG_HDMITX_PRD_IBIAS_D0 (0xf << 0) 91#define PRD_IBIAS_CLK_SHIFT 24 92#define PRD_IBIAS_D2_SHIFT 16 93#define PRD_IBIAS_D1_SHIFT 8 94#define PRD_IBIAS_D0_SHIFT 0 95#define HDMI_CON5 0x14 96#define RG_HDMITX_DRV_IBIAS_CLK (0x3f << 24) 97#define RG_HDMITX_DRV_IBIAS_D2 (0x3f << 16) 98#define RG_HDMITX_DRV_IBIAS_D1 (0x3f << 8) 99#define RG_HDMITX_DRV_IBIAS_D0 (0x3f << 0) 100#define DRV_IBIAS_CLK_SHIFT 24 101#define DRV_IBIAS_D2_SHIFT 16 102#define DRV_IBIAS_D1_SHIFT 8 103#define DRV_IBIAS_D0_SHIFT 0 104#define HDMI_CON6 0x18 105#define RG_HDMITX_DRV_IMP_CLK (0x3f << 24) 106#define RG_HDMITX_DRV_IMP_D2 (0x3f << 16) 107#define RG_HDMITX_DRV_IMP_D1 (0x3f << 8) 108#define RG_HDMITX_DRV_IMP_D0 (0x3f << 0) 109#define DRV_IMP_CLK_SHIFT 24 110#define DRV_IMP_D2_SHIFT 16 111#define DRV_IMP_D1_SHIFT 8 112#define DRV_IMP_D0_SHIFT 0 113#define HDMI_CON7 0x1c 114#define RG_HDMITX_MHLCK_DRV_IBIAS (0x1f << 27) 115#define RG_HDMITX_SER_DIN (0x3ff << 16) 116#define RG_HDMITX_CHLDC_TST (0xf << 12) 117#define RG_HDMITX_CHLCK_TST (0xf << 8) 118#define RG_HDMITX_RESERVE (0xff << 0) 119#define HDMI_CON8 0x20 120#define RGS_HDMITX_2T1_LEV (0xf << 16) 121#define RGS_HDMITX_2T1_EDG (0xf << 12) 122#define RGS_HDMITX_5T1_LEV (0xf << 8) 123#define RGS_HDMITX_5T1_EDG (0xf << 4) 124#define RGS_HDMITX_PLUG_TST BIT(0) 125 126struct mtk_hdmi_phy { 127 void __iomem *regs; 128 struct device *dev; 129 struct clk *pll; 130 struct clk_hw pll_hw; 131 unsigned long pll_rate; 132 u8 drv_imp_clk; 133 u8 drv_imp_d2; 134 u8 drv_imp_d1; 135 u8 drv_imp_d0; 136 u32 ibias; 137 u32 ibias_up; 138}; 139 140static const u8 PREDIV[3][4] = { 141 {0x0, 0x0, 0x0, 0x0}, /* 27Mhz */ 142 {0x1, 0x1, 0x1, 0x1}, /* 74Mhz */ 143 {0x1, 0x1, 0x1, 0x1} /* 148Mhz */ 144}; 145 146static const u8 TXDIV[3][4] = { 147 {0x3, 0x3, 0x3, 0x2}, /* 27Mhz */ 148 {0x2, 0x1, 0x1, 0x1}, /* 74Mhz */ 149 {0x1, 0x0, 0x0, 0x0} /* 148Mhz */ 150}; 151 152static const u8 FBKSEL[3][4] = { 153 {0x1, 0x1, 0x1, 0x1}, /* 27Mhz */ 154 {0x1, 0x0, 0x1, 0x1}, /* 74Mhz */ 155 {0x1, 0x0, 0x1, 0x1} /* 148Mhz */ 156}; 157 158static const u8 FBKDIV[3][4] = { 159 {19, 24, 29, 19}, /* 27Mhz */ 160 {19, 24, 14, 19}, /* 74Mhz */ 161 {19, 24, 14, 19} /* 148Mhz */ 162}; 163 164static const u8 DIVEN[3][4] = { 165 {0x2, 0x1, 0x1, 0x2}, /* 27Mhz */ 166 {0x2, 0x2, 0x2, 0x2}, /* 74Mhz */ 167 {0x2, 0x2, 0x2, 0x2} /* 148Mhz */ 168}; 169 170static const u8 HTPLLBP[3][4] = { 171 {0xc, 0xc, 0x8, 0xc}, /* 27Mhz */ 172 {0xc, 0xf, 0xf, 0xc}, /* 74Mhz */ 173 {0xc, 0xf, 0xf, 0xc} /* 148Mhz */ 174}; 175 176static const u8 HTPLLBC[3][4] = { 177 {0x2, 0x3, 0x3, 0x2}, /* 27Mhz */ 178 {0x2, 0x3, 0x3, 0x2}, /* 74Mhz */ 179 {0x2, 0x3, 0x3, 0x2} /* 148Mhz */ 180}; 181 182static const u8 HTPLLBR[3][4] = { 183 {0x1, 0x1, 0x0, 0x1}, /* 27Mhz */ 184 {0x1, 0x2, 0x2, 0x1}, /* 74Mhz */ 185 {0x1, 0x2, 0x2, 0x1} /* 148Mhz */ 186}; 187 188static void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, 189 u32 bits) 190{ 191 void __iomem *reg = hdmi_phy->regs + offset; 192 u32 tmp; 193 194 tmp = readl(reg); 195 tmp &= ~bits; 196 writel(tmp, reg); 197} 198 199static void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, 200 u32 bits) 201{ 202 void __iomem *reg = hdmi_phy->regs + offset; 203 u32 tmp; 204 205 tmp = readl(reg); 206 tmp |= bits; 207 writel(tmp, reg); 208} 209 210static void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, 211 u32 val, u32 mask) 212{ 213 void __iomem *reg = hdmi_phy->regs + offset; 214 u32 tmp; 215 216 tmp = readl(reg); 217 tmp = (tmp & ~mask) | (val & mask); 218 writel(tmp, reg); 219} 220 221static inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw) 222{ 223 return container_of(hw, struct mtk_hdmi_phy, pll_hw); 224} 225 226static int mtk_hdmi_pll_prepare(struct clk_hw *hw) 227{ 228 struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); 229 230 dev_dbg(hdmi_phy->dev, "%s\n", __func__); 231 232 mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN); 233 mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV); 234 mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, RG_HDMITX_MHLCK_EN); 235 mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_EN); 236 usleep_range(100, 150); 237 mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_EN); 238 usleep_range(100, 150); 239 mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN); 240 mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN); 241 242 return 0; 243} 244 245static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) 246{ 247 struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); 248 249 dev_dbg(hdmi_phy->dev, "%s\n", __func__); 250 251 mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN); 252 mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN); 253 usleep_range(100, 150); 254 mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_EN); 255 usleep_range(100, 150); 256 mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_EN); 257 mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV); 258 mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN); 259 usleep_range(100, 150); 260} 261 262static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, 263 unsigned long parent_rate) 264{ 265 struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); 266 unsigned int pre_div; 267 unsigned int div; 268 unsigned int pre_ibias; 269 unsigned int hdmi_ibias; 270 unsigned int imp_en; 271 272 dev_dbg(hdmi_phy->dev, "%s: %lu Hz, parent: %lu Hz\n", __func__, 273 rate, parent_rate); 274 275 if (rate <= 27000000) { 276 pre_div = 0; 277 div = 3; 278 } else if (rate <= 74250000) { 279 pre_div = 1; 280 div = 2; 281 } else { 282 pre_div = 1; 283 div = 1; 284 } 285 286 mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, 287 (pre_div << PREDIV_SHIFT), RG_HDMITX_PLL_PREDIV); 288 mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV); 289 mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, 290 (0x1 << PLL_IC_SHIFT) | (0x1 << PLL_IR_SHIFT), 291 RG_HDMITX_PLL_IC | RG_HDMITX_PLL_IR); 292 mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, 293 (div << PLL_TXDIV_SHIFT), RG_HDMITX_PLL_TXDIV); 294 mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, 295 (0x1 << PLL_FBKSEL_SHIFT) | (19 << PLL_FBKDIV_SHIFT), 296 RG_HDMITX_PLL_FBKSEL | RG_HDMITX_PLL_FBKDIV); 297 mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, 298 (0x2 << PLL_DIVEN_SHIFT), RG_HDMITX_PLL_DIVEN); 299 mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, 300 (0xc << PLL_BP_SHIFT) | (0x2 << PLL_BC_SHIFT) | 301 (0x1 << PLL_BR_SHIFT), 302 RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC | 303 RG_HDMITX_PLL_BR); 304 if (rate < 165000000) { 305 mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, 306 RG_HDMITX_PRD_IMP_EN); 307 pre_ibias = 0x3; 308 imp_en = 0x0; 309 hdmi_ibias = hdmi_phy->ibias; 310 } else { 311 mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3, 312 RG_HDMITX_PRD_IMP_EN); 313 pre_ibias = 0x6; 314 imp_en = 0xf; 315 hdmi_ibias = hdmi_phy->ibias_up; 316 } 317 mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, 318 (pre_ibias << PRD_IBIAS_CLK_SHIFT) | 319 (pre_ibias << PRD_IBIAS_D2_SHIFT) | 320 (pre_ibias << PRD_IBIAS_D1_SHIFT) | 321 (pre_ibias << PRD_IBIAS_D0_SHIFT), 322 RG_HDMITX_PRD_IBIAS_CLK | 323 RG_HDMITX_PRD_IBIAS_D2 | 324 RG_HDMITX_PRD_IBIAS_D1 | 325 RG_HDMITX_PRD_IBIAS_D0); 326 mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3, 327 (imp_en << DRV_IMP_EN_SHIFT), 328 RG_HDMITX_DRV_IMP_EN); 329 mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, 330 (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) | 331 (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) | 332 (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) | 333 (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT), 334 RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 | 335 RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0); 336 mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5, 337 (hdmi_ibias << DRV_IBIAS_CLK_SHIFT) | 338 (hdmi_ibias << DRV_IBIAS_D2_SHIFT) | 339 (hdmi_ibias << DRV_IBIAS_D1_SHIFT) | 340 (hdmi_ibias << DRV_IBIAS_D0_SHIFT), 341 RG_HDMITX_DRV_IBIAS_CLK | 342 RG_HDMITX_DRV_IBIAS_D2 | 343 RG_HDMITX_DRV_IBIAS_D1 | 344 RG_HDMITX_DRV_IBIAS_D0); 345 return 0; 346} 347 348static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, 349 unsigned long *parent_rate) 350{ 351 struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); 352 353 hdmi_phy->pll_rate = rate; 354 if (rate <= 74250000) 355 *parent_rate = rate; 356 else 357 *parent_rate = rate / 2; 358 359 return rate; 360} 361 362static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, 363 unsigned long parent_rate) 364{ 365 struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); 366 367 return hdmi_phy->pll_rate; 368} 369 370static const struct clk_ops mtk_hdmi_pll_ops = { 371 .prepare = mtk_hdmi_pll_prepare, 372 .unprepare = mtk_hdmi_pll_unprepare, 373 .set_rate = mtk_hdmi_pll_set_rate, 374 .round_rate = mtk_hdmi_pll_round_rate, 375 .recalc_rate = mtk_hdmi_pll_recalc_rate, 376}; 377 378static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy) 379{ 380 mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3, 381 RG_HDMITX_SER_EN | RG_HDMITX_PRD_EN | 382 RG_HDMITX_DRV_EN); 383 usleep_range(100, 150); 384} 385 386static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) 387{ 388 mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, 389 RG_HDMITX_DRV_EN | RG_HDMITX_PRD_EN | 390 RG_HDMITX_SER_EN); 391} 392 393static int mtk_hdmi_phy_power_on(struct phy *phy) 394{ 395 struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); 396 int ret; 397 398 ret = clk_prepare_enable(hdmi_phy->pll); 399 if (ret < 0) 400 return ret; 401 402 mtk_hdmi_phy_enable_tmds(hdmi_phy); 403 404 return 0; 405} 406 407static int mtk_hdmi_phy_power_off(struct phy *phy) 408{ 409 struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); 410 411 mtk_hdmi_phy_disable_tmds(hdmi_phy); 412 clk_disable_unprepare(hdmi_phy->pll); 413 414 return 0; 415} 416 417static const struct phy_ops mtk_hdmi_phy_ops = { 418 .power_on = mtk_hdmi_phy_power_on, 419 .power_off = mtk_hdmi_phy_power_off, 420 .owner = THIS_MODULE, 421}; 422 423static int mtk_hdmi_phy_probe(struct platform_device *pdev) 424{ 425 struct device *dev = &pdev->dev; 426 struct mtk_hdmi_phy *hdmi_phy; 427 struct resource *mem; 428 struct clk *ref_clk; 429 const char *ref_clk_name; 430 struct clk_init_data clk_init = { 431 .ops = &mtk_hdmi_pll_ops, 432 .num_parents = 1, 433 .parent_names = (const char * const *)&ref_clk_name, 434 .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, 435 }; 436 struct phy *phy; 437 struct phy_provider *phy_provider; 438 int ret; 439 440 hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL); 441 if (!hdmi_phy) 442 return -ENOMEM; 443 444 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 445 hdmi_phy->regs = devm_ioremap_resource(dev, mem); 446 if (IS_ERR(hdmi_phy->regs)) { 447 ret = PTR_ERR(hdmi_phy->regs); 448 dev_err(dev, "Failed to get memory resource: %d\n", ret); 449 return ret; 450 } 451 452 ref_clk = devm_clk_get(dev, "pll_ref"); 453 if (IS_ERR(ref_clk)) { 454 ret = PTR_ERR(ref_clk); 455 dev_err(&pdev->dev, "Failed to get PLL reference clock: %d\n", 456 ret); 457 return ret; 458 } 459 ref_clk_name = __clk_get_name(ref_clk); 460 461 ret = of_property_read_string(dev->of_node, "clock-output-names", 462 &clk_init.name); 463 if (ret < 0) { 464 dev_err(dev, "Failed to read clock-output-names: %d\n", ret); 465 return ret; 466 } 467 468 hdmi_phy->pll_hw.init = &clk_init; 469 hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw); 470 if (IS_ERR(hdmi_phy->pll)) { 471 ret = PTR_ERR(hdmi_phy->pll); 472 dev_err(dev, "Failed to register PLL: %d\n", ret); 473 return ret; 474 } 475 476 ret = of_property_read_u32(dev->of_node, "mediatek,ibias", 477 &hdmi_phy->ibias); 478 if (ret < 0) { 479 dev_err(&pdev->dev, "Failed to get ibias: %d\n", ret); 480 return ret; 481 } 482 483 ret = of_property_read_u32(dev->of_node, "mediatek,ibias_up", 484 &hdmi_phy->ibias_up); 485 if (ret < 0) { 486 dev_err(&pdev->dev, "Failed to get ibias up: %d\n", ret); 487 return ret; 488 } 489 490 dev_info(dev, "Using default TX DRV impedance: 4.2k/36\n"); 491 hdmi_phy->drv_imp_clk = 0x30; 492 hdmi_phy->drv_imp_d2 = 0x30; 493 hdmi_phy->drv_imp_d1 = 0x30; 494 hdmi_phy->drv_imp_d0 = 0x30; 495 496 phy = devm_phy_create(dev, NULL, &mtk_hdmi_phy_ops); 497 if (IS_ERR(phy)) { 498 dev_err(dev, "Failed to create HDMI PHY\n"); 499 return PTR_ERR(phy); 500 } 501 phy_set_drvdata(phy, hdmi_phy); 502 503 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 504 if (IS_ERR(phy_provider)) 505 return PTR_ERR(phy_provider); 506 507 hdmi_phy->dev = dev; 508 return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, 509 hdmi_phy->pll); 510} 511 512static int mtk_hdmi_phy_remove(struct platform_device *pdev) 513{ 514 return 0; 515} 516 517static const struct of_device_id mtk_hdmi_phy_match[] = { 518 { .compatible = "mediatek,mt8173-hdmi-phy", }, 519 {}, 520}; 521 522struct platform_driver mtk_hdmi_phy_driver = { 523 .probe = mtk_hdmi_phy_probe, 524 .remove = mtk_hdmi_phy_remove, 525 .driver = { 526 .name = "mediatek-hdmi-phy", 527 .of_match_table = mtk_hdmi_phy_match, 528 }, 529}; 530 531MODULE_AUTHOR("Jie Qiu <jie.qiu@mediatek.com>"); 532MODULE_DESCRIPTION("MediaTek MT8173 HDMI PHY Driver"); 533MODULE_LICENSE("GPL v2");