1169 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.4 * Copyright (c) 2024 Collabora Ltd.5 *6 * Author: Algea Cao <algea.cao@rock-chips.com>7 * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>8 */9#include <linux/bitfield.h>10#include <linux/clk.h>11#include <linux/clk-provider.h>12#include <linux/delay.h>13#include <linux/mfd/syscon.h>14#include <linux/module.h>15#include <linux/of.h>16#include <linux/of_platform.h>17#include <linux/phy/phy.h>18#include <linux/platform_device.h>19#include <linux/pm_runtime.h>20#include <linux/rational.h>21#include <linux/regmap.h>22#include <linux/reset.h>23 24#define GRF_HDPTX_CON0 0x0025#define HDPTX_I_PLL_EN BIT(7)26#define HDPTX_I_BIAS_EN BIT(6)27#define HDPTX_I_BGR_EN BIT(5)28#define GRF_HDPTX_STATUS 0x8029#define HDPTX_O_PLL_LOCK_DONE BIT(3)30#define HDPTX_O_PHY_CLK_RDY BIT(2)31#define HDPTX_O_PHY_RDY BIT(1)32#define HDPTX_O_SB_RDY BIT(0)33 34#define HDTPX_REG(_n, _min, _max) \35 ( \36 BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) + \37 BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) + \38 ((0x##_n) * 4) \39 )40 41#define CMN_REG(n) HDTPX_REG(n, 0000, 00a7)42#define SB_REG(n) HDTPX_REG(n, 0100, 0129)43#define LNTOP_REG(n) HDTPX_REG(n, 0200, 0229)44#define LANE_REG(n) HDTPX_REG(n, 0300, 062d)45 46/* CMN_REG(0008) */47#define LCPLL_EN_MASK BIT(6)48#define LCPLL_LCVCO_MODE_EN_MASK BIT(4)49/* CMN_REG(001e) */50#define LCPLL_PI_EN_MASK BIT(5)51#define LCPLL_100M_CLK_EN_MASK BIT(0)52/* CMN_REG(0025) */53#define LCPLL_PMS_IQDIV_RSTN BIT(4)54/* CMN_REG(0028) */55#define LCPLL_SDC_FRAC_EN BIT(2)56#define LCPLL_SDC_FRAC_RSTN BIT(0)57/* CMN_REG(002d) */58#define LCPLL_SDC_N_MASK GENMASK(3, 1)59/* CMN_REG(002e) */60#define LCPLL_SDC_NUMBERATOR_MASK GENMASK(5, 0)61/* CMN_REG(002f) */62#define LCPLL_SDC_DENOMINATOR_MASK GENMASK(7, 2)63#define LCPLL_SDC_NDIV_RSTN BIT(0)64/* CMN_REG(003d) */65#define ROPLL_LCVCO_EN BIT(4)66/* CMN_REG(004e) */67#define ROPLL_PI_EN BIT(5)68/* CMN_REG(005c) */69#define ROPLL_PMS_IQDIV_RSTN BIT(5)70/* CMN_REG(005e) */71#define ROPLL_SDM_EN_MASK BIT(6)72#define ROPLL_SDM_FRAC_EN_RBR BIT(3)73#define ROPLL_SDM_FRAC_EN_HBR BIT(2)74#define ROPLL_SDM_FRAC_EN_HBR2 BIT(1)75#define ROPLL_SDM_FRAC_EN_HBR3 BIT(0)76/* CMN_REG(0064) */77#define ROPLL_SDM_NUM_SIGN_RBR_MASK BIT(3)78/* CMN_REG(0069) */79#define ROPLL_SDC_N_RBR_MASK GENMASK(2, 0)80/* CMN_REG(0074) */81#define ROPLL_SDC_NDIV_RSTN BIT(2)82#define ROPLL_SSC_EN BIT(0)83/* CMN_REG(0081) */84#define OVRD_PLL_CD_CLK_EN BIT(8)85#define PLL_CD_HSCLK_EAST_EN BIT(0)86/* CMN_REG(0086) */87#define PLL_PCG_POSTDIV_SEL_MASK GENMASK(7, 4)88#define PLL_PCG_CLK_SEL_MASK GENMASK(3, 1)89#define PLL_PCG_CLK_EN BIT(0)90/* CMN_REG(0087) */91#define PLL_FRL_MODE_EN BIT(3)92#define PLL_TX_HS_CLK_EN BIT(2)93/* CMN_REG(0089) */94#define LCPLL_ALONE_MODE BIT(1)95/* CMN_REG(0097) */96#define DIG_CLK_SEL BIT(1)97#define ROPLL_REF BIT(1)98#define LCPLL_REF 099/* CMN_REG(0099) */100#define CMN_ROPLL_ALONE_MODE BIT(2)101#define ROPLL_ALONE_MODE BIT(2)102/* CMN_REG(009a) */103#define HS_SPEED_SEL BIT(0)104#define DIV_10_CLOCK BIT(0)105/* CMN_REG(009b) */106#define IS_SPEED_SEL BIT(4)107#define LINK_SYMBOL_CLOCK BIT(4)108#define LINK_SYMBOL_CLOCK1_2 0109 110/* SB_REG(0102) */111#define OVRD_SB_RXTERM_EN_MASK BIT(5)112#define SB_RXTERM_EN_MASK BIT(4)113#define ANA_SB_RXTERM_OFFSP_MASK GENMASK(3, 0)114/* SB_REG(0103) */115#define ANA_SB_RXTERM_OFFSN_MASK GENMASK(6, 3)116#define OVRD_SB_RX_RESCAL_DONE_MASK BIT(1)117#define SB_RX_RESCAL_DONE_MASK BIT(0)118/* SB_REG(0104) */119#define OVRD_SB_EN_MASK BIT(5)120#define SB_EN_MASK BIT(4)121/* SB_REG(0105) */122#define OVRD_SB_EARC_CMDC_EN_MASK BIT(6)123#define SB_EARC_CMDC_EN_MASK BIT(5)124#define ANA_SB_TX_HLVL_PROG_MASK GENMASK(2, 0)125/* SB_REG(0106) */126#define ANA_SB_TX_LLVL_PROG_MASK GENMASK(6, 4)127/* SB_REG(0109) */128#define ANA_SB_DMRX_AFC_DIV_RATIO_MASK GENMASK(2, 0)129/* SB_REG(010f) */130#define OVRD_SB_VREG_EN_MASK BIT(7)131#define SB_VREG_EN_MASK BIT(6)132#define OVRD_SB_VREG_LPF_BYPASS_MASK BIT(5)133#define SB_VREG_LPF_BYPASS_MASK BIT(4)134#define ANA_SB_VREG_GAIN_CTRL_MASK GENMASK(3, 0)135/* SB_REG(0110) */136#define ANA_SB_VREG_REF_SEL_MASK BIT(0)137/* SB_REG(0113) */138#define SB_RX_RCAL_OPT_CODE_MASK GENMASK(5, 4)139#define SB_RX_RTERM_CTRL_MASK GENMASK(3, 0)140/* SB_REG(0114) */141#define SB_TG_SB_EN_DELAY_TIME_MASK GENMASK(5, 3)142#define SB_TG_RXTERM_EN_DELAY_TIME_MASK GENMASK(2, 0)143/* SB_REG(0115) */144#define SB_READY_DELAY_TIME_MASK GENMASK(5, 3)145#define SB_TG_OSC_EN_DELAY_TIME_MASK GENMASK(2, 0)146/* SB_REG(0116) */147#define AFC_RSTN_DELAY_TIME_MASK GENMASK(6, 4)148/* SB_REG(0117) */149#define FAST_PULSE_TIME_MASK GENMASK(3, 0)150/* SB_REG(011b) */151#define SB_EARC_SIG_DET_BYPASS_MASK BIT(4)152#define SB_AFC_TOL_MASK GENMASK(3, 0)153/* SB_REG(011f) */154#define SB_PWM_AFC_CTRL_MASK GENMASK(7, 2)155#define SB_RCAL_RSTN_MASK BIT(1)156/* SB_REG(0120) */157#define SB_EARC_EN_MASK BIT(1)158#define SB_EARC_AFC_EN_MASK BIT(2)159/* SB_REG(0123) */160#define OVRD_SB_READY_MASK BIT(5)161#define SB_READY_MASK BIT(4)162 163/* LNTOP_REG(0200) */164#define PROTOCOL_SEL BIT(2)165#define HDMI_MODE BIT(2)166#define HDMI_TMDS_FRL_SEL BIT(1)167/* LNTOP_REG(0206) */168#define DATA_BUS_SEL BIT(0)169#define DATA_BUS_36_40 BIT(0)170/* LNTOP_REG(0207) */171#define LANE_EN 0xf172#define ALL_LANE_EN 0xf173 174/* LANE_REG(0312) */175#define LN0_TX_SER_RATE_SEL_RBR BIT(5)176#define LN0_TX_SER_RATE_SEL_HBR BIT(4)177#define LN0_TX_SER_RATE_SEL_HBR2 BIT(3)178#define LN0_TX_SER_RATE_SEL_HBR3 BIT(2)179/* LANE_REG(0412) */180#define LN1_TX_SER_RATE_SEL_RBR BIT(5)181#define LN1_TX_SER_RATE_SEL_HBR BIT(4)182#define LN1_TX_SER_RATE_SEL_HBR2 BIT(3)183#define LN1_TX_SER_RATE_SEL_HBR3 BIT(2)184/* LANE_REG(0512) */185#define LN2_TX_SER_RATE_SEL_RBR BIT(5)186#define LN2_TX_SER_RATE_SEL_HBR BIT(4)187#define LN2_TX_SER_RATE_SEL_HBR2 BIT(3)188#define LN2_TX_SER_RATE_SEL_HBR3 BIT(2)189/* LANE_REG(0612) */190#define LN3_TX_SER_RATE_SEL_RBR BIT(5)191#define LN3_TX_SER_RATE_SEL_HBR BIT(4)192#define LN3_TX_SER_RATE_SEL_HBR2 BIT(3)193#define LN3_TX_SER_RATE_SEL_HBR3 BIT(2)194 195#define HDMI20_MAX_RATE 600000000196 197struct lcpll_config {198 u32 bit_rate;199 u8 lcvco_mode_en;200 u8 pi_en;201 u8 clk_en_100m;202 u8 pms_mdiv;203 u8 pms_mdiv_afc;204 u8 pms_pdiv;205 u8 pms_refdiv;206 u8 pms_sdiv;207 u8 pi_cdiv_rstn;208 u8 pi_cdiv_sel;209 u8 sdm_en;210 u8 sdm_rstn;211 u8 sdc_frac_en;212 u8 sdc_rstn;213 u8 sdm_deno;214 u8 sdm_num_sign;215 u8 sdm_num;216 u8 sdc_n;217 u8 sdc_n2;218 u8 sdc_num;219 u8 sdc_deno;220 u8 sdc_ndiv_rstn;221 u8 ssc_en;222 u8 ssc_fm_dev;223 u8 ssc_fm_freq;224 u8 ssc_clk_div_sel;225 u8 cd_tx_ser_rate_sel;226};227 228struct ropll_config {229 u32 bit_rate;230 u8 pms_mdiv;231 u8 pms_mdiv_afc;232 u8 pms_pdiv;233 u8 pms_refdiv;234 u8 pms_sdiv;235 u8 pms_iqdiv_rstn;236 u8 ref_clk_sel;237 u8 sdm_en;238 u8 sdm_rstn;239 u8 sdc_frac_en;240 u8 sdc_rstn;241 u8 sdm_clk_div;242 u8 sdm_deno;243 u8 sdm_num_sign;244 u8 sdm_num;245 u8 sdc_n;246 u8 sdc_num;247 u8 sdc_deno;248 u8 sdc_ndiv_rstn;249 u8 ssc_en;250 u8 ssc_fm_dev;251 u8 ssc_fm_freq;252 u8 ssc_clk_div_sel;253 u8 ana_cpp_ctrl;254 u8 ana_lpf_c_sel;255 u8 cd_tx_ser_rate_sel;256};257 258enum rk_hdptx_reset {259 RST_PHY = 0,260 RST_APB,261 RST_INIT,262 RST_CMN,263 RST_LANE,264 RST_ROPLL,265 RST_LCPLL,266 RST_MAX267};268 269struct rk_hdptx_phy {270 struct device *dev;271 struct regmap *regmap;272 struct regmap *grf;273 274 struct phy *phy;275 struct phy_config *phy_cfg;276 struct clk_bulk_data *clks;277 int nr_clks;278 struct reset_control_bulk_data rsts[RST_MAX];279 280 /* clk provider */281 struct clk_hw hw;282 unsigned long rate;283 284 atomic_t usage_count;285};286 287static const struct ropll_config ropll_tmds_cfg[] = {288 { 5940000, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,289 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },290 { 3712500, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,291 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },292 { 2970000, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,293 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },294 { 1620000, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10,295 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },296 { 1856250, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,297 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },298 { 1540000, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1,299 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },300 { 1485000, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5,301 0x10, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },302 { 1462500, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1,303 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },304 { 1190000, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1,305 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },306 { 1065000, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1,307 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },308 { 1080000, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,309 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },310 { 855000, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1,311 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },312 { 835000, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0,313 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },314 { 928125, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,315 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },316 { 742500, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,317 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },318 { 650000, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1,319 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },320 { 337500, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5,321 1, 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },322 { 400000, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,323 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },324 { 270000, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,325 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },326 { 251750, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1,327 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },328};329 330static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {331 REG_SEQ0(CMN_REG(0009), 0x0c),332 REG_SEQ0(CMN_REG(000a), 0x83),333 REG_SEQ0(CMN_REG(000b), 0x06),334 REG_SEQ0(CMN_REG(000c), 0x20),335 REG_SEQ0(CMN_REG(000d), 0xb8),336 REG_SEQ0(CMN_REG(000e), 0x0f),337 REG_SEQ0(CMN_REG(000f), 0x0f),338 REG_SEQ0(CMN_REG(0010), 0x04),339 REG_SEQ0(CMN_REG(0011), 0x00),340 REG_SEQ0(CMN_REG(0012), 0x26),341 REG_SEQ0(CMN_REG(0013), 0x22),342 REG_SEQ0(CMN_REG(0014), 0x24),343 REG_SEQ0(CMN_REG(0015), 0x77),344 REG_SEQ0(CMN_REG(0016), 0x08),345 REG_SEQ0(CMN_REG(0017), 0x00),346 REG_SEQ0(CMN_REG(0018), 0x04),347 REG_SEQ0(CMN_REG(0019), 0x48),348 REG_SEQ0(CMN_REG(001a), 0x01),349 REG_SEQ0(CMN_REG(001b), 0x00),350 REG_SEQ0(CMN_REG(001c), 0x01),351 REG_SEQ0(CMN_REG(001d), 0x64),352 REG_SEQ0(CMN_REG(001f), 0x00),353 REG_SEQ0(CMN_REG(0026), 0x53),354 REG_SEQ0(CMN_REG(0029), 0x01),355 REG_SEQ0(CMN_REG(0030), 0x00),356 REG_SEQ0(CMN_REG(0031), 0x20),357 REG_SEQ0(CMN_REG(0032), 0x30),358 REG_SEQ0(CMN_REG(0033), 0x0b),359 REG_SEQ0(CMN_REG(0034), 0x23),360 REG_SEQ0(CMN_REG(0035), 0x00),361 REG_SEQ0(CMN_REG(0038), 0x00),362 REG_SEQ0(CMN_REG(0039), 0x00),363 REG_SEQ0(CMN_REG(003a), 0x00),364 REG_SEQ0(CMN_REG(003b), 0x00),365 REG_SEQ0(CMN_REG(003c), 0x80),366 REG_SEQ0(CMN_REG(003e), 0x0c),367 REG_SEQ0(CMN_REG(003f), 0x83),368 REG_SEQ0(CMN_REG(0040), 0x06),369 REG_SEQ0(CMN_REG(0041), 0x20),370 REG_SEQ0(CMN_REG(0042), 0xb8),371 REG_SEQ0(CMN_REG(0043), 0x00),372 REG_SEQ0(CMN_REG(0044), 0x46),373 REG_SEQ0(CMN_REG(0045), 0x24),374 REG_SEQ0(CMN_REG(0046), 0xff),375 REG_SEQ0(CMN_REG(0047), 0x00),376 REG_SEQ0(CMN_REG(0048), 0x44),377 REG_SEQ0(CMN_REG(0049), 0xfa),378 REG_SEQ0(CMN_REG(004a), 0x08),379 REG_SEQ0(CMN_REG(004b), 0x00),380 REG_SEQ0(CMN_REG(004c), 0x01),381 REG_SEQ0(CMN_REG(004d), 0x64),382 REG_SEQ0(CMN_REG(004e), 0x14),383 REG_SEQ0(CMN_REG(004f), 0x00),384 REG_SEQ0(CMN_REG(0050), 0x00),385 REG_SEQ0(CMN_REG(005d), 0x0c),386 REG_SEQ0(CMN_REG(005f), 0x01),387 REG_SEQ0(CMN_REG(006b), 0x04),388 REG_SEQ0(CMN_REG(0073), 0x30),389 REG_SEQ0(CMN_REG(0074), 0x00),390 REG_SEQ0(CMN_REG(0075), 0x20),391 REG_SEQ0(CMN_REG(0076), 0x30),392 REG_SEQ0(CMN_REG(0077), 0x08),393 REG_SEQ0(CMN_REG(0078), 0x0c),394 REG_SEQ0(CMN_REG(0079), 0x00),395 REG_SEQ0(CMN_REG(007b), 0x00),396 REG_SEQ0(CMN_REG(007c), 0x00),397 REG_SEQ0(CMN_REG(007d), 0x00),398 REG_SEQ0(CMN_REG(007e), 0x00),399 REG_SEQ0(CMN_REG(007f), 0x00),400 REG_SEQ0(CMN_REG(0080), 0x00),401 REG_SEQ0(CMN_REG(0081), 0x09),402 REG_SEQ0(CMN_REG(0082), 0x04),403 REG_SEQ0(CMN_REG(0083), 0x24),404 REG_SEQ0(CMN_REG(0084), 0x20),405 REG_SEQ0(CMN_REG(0085), 0x03),406 REG_SEQ0(CMN_REG(0086), 0x01),407 REG_SEQ0(CMN_REG(0087), 0x0c),408 REG_SEQ0(CMN_REG(008a), 0x55),409 REG_SEQ0(CMN_REG(008b), 0x25),410 REG_SEQ0(CMN_REG(008c), 0x2c),411 REG_SEQ0(CMN_REG(008d), 0x22),412 REG_SEQ0(CMN_REG(008e), 0x14),413 REG_SEQ0(CMN_REG(008f), 0x20),414 REG_SEQ0(CMN_REG(0090), 0x00),415 REG_SEQ0(CMN_REG(0091), 0x00),416 REG_SEQ0(CMN_REG(0092), 0x00),417 REG_SEQ0(CMN_REG(0093), 0x00),418 REG_SEQ0(CMN_REG(009a), 0x11),419 REG_SEQ0(CMN_REG(009b), 0x10),420};421 422static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {423 REG_SEQ0(CMN_REG(0008), 0x00),424 REG_SEQ0(CMN_REG(0011), 0x01),425 REG_SEQ0(CMN_REG(0017), 0x20),426 REG_SEQ0(CMN_REG(001e), 0x14),427 REG_SEQ0(CMN_REG(0020), 0x00),428 REG_SEQ0(CMN_REG(0021), 0x00),429 REG_SEQ0(CMN_REG(0022), 0x11),430 REG_SEQ0(CMN_REG(0023), 0x00),431 REG_SEQ0(CMN_REG(0024), 0x00),432 REG_SEQ0(CMN_REG(0025), 0x53),433 REG_SEQ0(CMN_REG(0026), 0x00),434 REG_SEQ0(CMN_REG(0027), 0x00),435 REG_SEQ0(CMN_REG(0028), 0x01),436 REG_SEQ0(CMN_REG(002a), 0x00),437 REG_SEQ0(CMN_REG(002b), 0x00),438 REG_SEQ0(CMN_REG(002c), 0x00),439 REG_SEQ0(CMN_REG(002d), 0x00),440 REG_SEQ0(CMN_REG(002e), 0x04),441 REG_SEQ0(CMN_REG(002f), 0x00),442 REG_SEQ0(CMN_REG(0030), 0x20),443 REG_SEQ0(CMN_REG(0031), 0x30),444 REG_SEQ0(CMN_REG(0032), 0x0b),445 REG_SEQ0(CMN_REG(0033), 0x23),446 REG_SEQ0(CMN_REG(0034), 0x00),447 REG_SEQ0(CMN_REG(003d), 0x40),448 REG_SEQ0(CMN_REG(0042), 0x78),449 REG_SEQ0(CMN_REG(004e), 0x34),450 REG_SEQ0(CMN_REG(005c), 0x25),451 REG_SEQ0(CMN_REG(005e), 0x4f),452 REG_SEQ0(CMN_REG(0074), 0x04),453 REG_SEQ0(CMN_REG(0081), 0x01),454 REG_SEQ0(CMN_REG(0087), 0x04),455 REG_SEQ0(CMN_REG(0089), 0x00),456 REG_SEQ0(CMN_REG(0095), 0x00),457 REG_SEQ0(CMN_REG(0097), 0x02),458 REG_SEQ0(CMN_REG(0099), 0x04),459 REG_SEQ0(CMN_REG(009b), 0x00),460};461 462static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = {463 REG_SEQ0(SB_REG(0114), 0x00),464 REG_SEQ0(SB_REG(0115), 0x00),465 REG_SEQ0(SB_REG(0116), 0x00),466 REG_SEQ0(SB_REG(0117), 0x00),467};468 469static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = {470 REG_SEQ0(LNTOP_REG(0201), 0x00),471 REG_SEQ0(LNTOP_REG(0202), 0x00),472 REG_SEQ0(LNTOP_REG(0203), 0x0f),473 REG_SEQ0(LNTOP_REG(0204), 0xff),474 REG_SEQ0(LNTOP_REG(0205), 0xff),475};476 477static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = {478 REG_SEQ0(LNTOP_REG(0201), 0x07),479 REG_SEQ0(LNTOP_REG(0202), 0xc1),480 REG_SEQ0(LNTOP_REG(0203), 0xf0),481 REG_SEQ0(LNTOP_REG(0204), 0x7c),482 REG_SEQ0(LNTOP_REG(0205), 0x1f),483};484 485static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {486 REG_SEQ0(LANE_REG(0303), 0x0c),487 REG_SEQ0(LANE_REG(0307), 0x20),488 REG_SEQ0(LANE_REG(030a), 0x17),489 REG_SEQ0(LANE_REG(030b), 0x77),490 REG_SEQ0(LANE_REG(030c), 0x77),491 REG_SEQ0(LANE_REG(030d), 0x77),492 REG_SEQ0(LANE_REG(030e), 0x38),493 REG_SEQ0(LANE_REG(0310), 0x03),494 REG_SEQ0(LANE_REG(0311), 0x0f),495 REG_SEQ0(LANE_REG(0316), 0x02),496 REG_SEQ0(LANE_REG(031b), 0x01),497 REG_SEQ0(LANE_REG(031f), 0x15),498 REG_SEQ0(LANE_REG(0320), 0xa0),499 REG_SEQ0(LANE_REG(0403), 0x0c),500 REG_SEQ0(LANE_REG(0407), 0x20),501 REG_SEQ0(LANE_REG(040a), 0x17),502 REG_SEQ0(LANE_REG(040b), 0x77),503 REG_SEQ0(LANE_REG(040c), 0x77),504 REG_SEQ0(LANE_REG(040d), 0x77),505 REG_SEQ0(LANE_REG(040e), 0x38),506 REG_SEQ0(LANE_REG(0410), 0x03),507 REG_SEQ0(LANE_REG(0411), 0x0f),508 REG_SEQ0(LANE_REG(0416), 0x02),509 REG_SEQ0(LANE_REG(041b), 0x01),510 REG_SEQ0(LANE_REG(041f), 0x15),511 REG_SEQ0(LANE_REG(0420), 0xa0),512 REG_SEQ0(LANE_REG(0503), 0x0c),513 REG_SEQ0(LANE_REG(0507), 0x20),514 REG_SEQ0(LANE_REG(050a), 0x17),515 REG_SEQ0(LANE_REG(050b), 0x77),516 REG_SEQ0(LANE_REG(050c), 0x77),517 REG_SEQ0(LANE_REG(050d), 0x77),518 REG_SEQ0(LANE_REG(050e), 0x38),519 REG_SEQ0(LANE_REG(0510), 0x03),520 REG_SEQ0(LANE_REG(0511), 0x0f),521 REG_SEQ0(LANE_REG(0516), 0x02),522 REG_SEQ0(LANE_REG(051b), 0x01),523 REG_SEQ0(LANE_REG(051f), 0x15),524 REG_SEQ0(LANE_REG(0520), 0xa0),525 REG_SEQ0(LANE_REG(0603), 0x0c),526 REG_SEQ0(LANE_REG(0607), 0x20),527 REG_SEQ0(LANE_REG(060a), 0x17),528 REG_SEQ0(LANE_REG(060b), 0x77),529 REG_SEQ0(LANE_REG(060c), 0x77),530 REG_SEQ0(LANE_REG(060d), 0x77),531 REG_SEQ0(LANE_REG(060e), 0x38),532 REG_SEQ0(LANE_REG(0610), 0x03),533 REG_SEQ0(LANE_REG(0611), 0x0f),534 REG_SEQ0(LANE_REG(0616), 0x02),535 REG_SEQ0(LANE_REG(061b), 0x01),536 REG_SEQ0(LANE_REG(061f), 0x15),537 REG_SEQ0(LANE_REG(0620), 0xa0),538};539 540static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {541 REG_SEQ0(LANE_REG(0312), 0x00),542 REG_SEQ0(LANE_REG(031e), 0x00),543 REG_SEQ0(LANE_REG(0412), 0x00),544 REG_SEQ0(LANE_REG(041e), 0x00),545 REG_SEQ0(LANE_REG(0512), 0x00),546 REG_SEQ0(LANE_REG(051e), 0x00),547 REG_SEQ0(LANE_REG(0612), 0x00),548 REG_SEQ0(LANE_REG(061e), 0x08),549 REG_SEQ0(LANE_REG(0303), 0x2f),550 REG_SEQ0(LANE_REG(0403), 0x2f),551 REG_SEQ0(LANE_REG(0503), 0x2f),552 REG_SEQ0(LANE_REG(0603), 0x2f),553 REG_SEQ0(LANE_REG(0305), 0x03),554 REG_SEQ0(LANE_REG(0405), 0x03),555 REG_SEQ0(LANE_REG(0505), 0x03),556 REG_SEQ0(LANE_REG(0605), 0x03),557 REG_SEQ0(LANE_REG(0306), 0x1c),558 REG_SEQ0(LANE_REG(0406), 0x1c),559 REG_SEQ0(LANE_REG(0506), 0x1c),560 REG_SEQ0(LANE_REG(0606), 0x1c),561};562 563static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)564{565 switch (reg) {566 case 0x0000 ... 0x029c:567 case 0x0400 ... 0x04a4:568 case 0x0800 ... 0x08a4:569 case 0x0c00 ... 0x0cb4:570 case 0x1000 ... 0x10b4:571 case 0x1400 ... 0x14b4:572 case 0x1800 ... 0x18b4:573 return true;574 }575 576 return false;577}578 579static const struct regmap_config rk_hdptx_phy_regmap_config = {580 .reg_bits = 32,581 .reg_stride = 4,582 .val_bits = 32,583 .writeable_reg = rk_hdptx_phy_is_rw_reg,584 .readable_reg = rk_hdptx_phy_is_rw_reg,585 .fast_io = true,586 .max_register = 0x18b4,587};588 589#define rk_hdptx_multi_reg_write(hdptx, seq) \590 regmap_multi_reg_write((hdptx)->regmap, seq, ARRAY_SIZE(seq))591 592static void rk_hdptx_pre_power_up(struct rk_hdptx_phy *hdptx)593{594 u32 val;595 596 reset_control_assert(hdptx->rsts[RST_APB].rstc);597 usleep_range(20, 25);598 reset_control_deassert(hdptx->rsts[RST_APB].rstc);599 600 reset_control_assert(hdptx->rsts[RST_LANE].rstc);601 reset_control_assert(hdptx->rsts[RST_CMN].rstc);602 reset_control_assert(hdptx->rsts[RST_INIT].rstc);603 604 val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;605 regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);606}607 608static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx)609{610 u32 val;611 int ret;612 613 reset_control_deassert(hdptx->rsts[RST_LANE].rstc);614 615 val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |616 HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;617 regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);618 619 ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,620 (val & HDPTX_O_PHY_RDY) &&621 (val & HDPTX_O_PLL_LOCK_DONE),622 100, 5000);623 if (ret) {624 dev_err(hdptx->dev, "Failed to get PHY lane lock: %d\n", ret);625 return ret;626 }627 628 dev_dbg(hdptx->dev, "PHY lane locked\n");629 630 return 0;631}632 633static int rk_hdptx_post_enable_pll(struct rk_hdptx_phy *hdptx)634{635 u32 val;636 int ret;637 638 val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |639 HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;640 regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);641 642 usleep_range(10, 15);643 reset_control_deassert(hdptx->rsts[RST_INIT].rstc);644 645 usleep_range(10, 15);646 val = HDPTX_I_PLL_EN << 16 | HDPTX_I_PLL_EN;647 regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);648 649 usleep_range(10, 15);650 reset_control_deassert(hdptx->rsts[RST_CMN].rstc);651 652 ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,653 val & HDPTX_O_PHY_CLK_RDY, 20, 400);654 if (ret) {655 dev_err(hdptx->dev, "Failed to get PHY clk ready: %d\n", ret);656 return ret;657 }658 659 dev_dbg(hdptx->dev, "PHY clk ready\n");660 661 return 0;662}663 664static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)665{666 u32 val;667 668 /* reset phy and apb, or phy locked flag may keep 1 */669 reset_control_assert(hdptx->rsts[RST_PHY].rstc);670 usleep_range(20, 30);671 reset_control_deassert(hdptx->rsts[RST_PHY].rstc);672 673 reset_control_assert(hdptx->rsts[RST_APB].rstc);674 usleep_range(20, 30);675 reset_control_deassert(hdptx->rsts[RST_APB].rstc);676 677 regmap_write(hdptx->regmap, LANE_REG(0300), 0x82);678 regmap_write(hdptx->regmap, SB_REG(010f), 0xc1);679 regmap_write(hdptx->regmap, SB_REG(0110), 0x1);680 regmap_write(hdptx->regmap, LANE_REG(0301), 0x80);681 regmap_write(hdptx->regmap, LANE_REG(0401), 0x80);682 regmap_write(hdptx->regmap, LANE_REG(0501), 0x80);683 regmap_write(hdptx->regmap, LANE_REG(0601), 0x80);684 685 reset_control_assert(hdptx->rsts[RST_LANE].rstc);686 reset_control_assert(hdptx->rsts[RST_CMN].rstc);687 reset_control_assert(hdptx->rsts[RST_INIT].rstc);688 689 val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;690 regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);691}692 693static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate,694 struct ropll_config *cfg)695{696 const unsigned int fout = data_rate / 2, fref = 24000;697 unsigned long k = 0, lc, k_sub, lc_sub;698 unsigned int fvco, sdc;699 u32 mdiv, sdiv, n = 8;700 701 if (fout > 0xfffffff)702 return false;703 704 for (sdiv = 16; sdiv >= 1; sdiv--) {705 if (sdiv % 2 && sdiv != 1)706 continue;707 708 fvco = fout * sdiv;709 710 if (fvco < 2000000 || fvco > 4000000)711 continue;712 713 mdiv = DIV_ROUND_UP(fvco, fref);714 if (mdiv < 20 || mdiv > 255)715 continue;716 717 if (fref * mdiv - fvco) {718 for (sdc = 264000; sdc <= 750000; sdc += fref)719 if (sdc * n > fref * mdiv)720 break;721 722 if (sdc > 750000)723 continue;724 725 rational_best_approximation(fref * mdiv - fvco,726 sdc / 16,727 GENMASK(6, 0),728 GENMASK(7, 0),729 &k, &lc);730 731 rational_best_approximation(sdc * n - fref * mdiv,732 sdc,733 GENMASK(6, 0),734 GENMASK(7, 0),735 &k_sub, &lc_sub);736 }737 738 break;739 }740 741 if (sdiv < 1)742 return false;743 744 if (cfg) {745 cfg->pms_mdiv = mdiv;746 cfg->pms_mdiv_afc = mdiv;747 cfg->pms_pdiv = 1;748 cfg->pms_refdiv = 1;749 cfg->pms_sdiv = sdiv - 1;750 751 cfg->sdm_en = k > 0 ? 1 : 0;752 if (cfg->sdm_en) {753 cfg->sdm_deno = lc;754 cfg->sdm_num_sign = 1;755 cfg->sdm_num = k;756 cfg->sdc_n = n - 3;757 cfg->sdc_num = k_sub;758 cfg->sdc_deno = lc_sub;759 }760 }761 762 return true;763}764 765static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,766 unsigned int rate)767{768 const struct ropll_config *cfg = NULL;769 struct ropll_config rc = {0};770 int i;771 772 hdptx->rate = rate * 100;773 774 for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)775 if (rate == ropll_tmds_cfg[i].bit_rate) {776 cfg = &ropll_tmds_cfg[i];777 break;778 }779 780 if (!cfg) {781 if (rk_hdptx_phy_clk_pll_calc(rate, &rc)) {782 cfg = &rc;783 } else {784 dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__);785 return -EINVAL;786 }787 }788 789 dev_dbg(hdptx->dev, "mdiv=%u, sdiv=%u, sdm_en=%u, k_sign=%u, k=%u, lc=%u\n",790 cfg->pms_mdiv, cfg->pms_sdiv + 1, cfg->sdm_en,791 cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno);792 793 rk_hdptx_pre_power_up(hdptx);794 795 reset_control_assert(hdptx->rsts[RST_ROPLL].rstc);796 usleep_range(20, 30);797 reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc);798 799 rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq);800 rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq);801 802 regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv);803 regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc);804 regmap_write(hdptx->regmap, CMN_REG(0059),805 (cfg->pms_pdiv << 4) | cfg->pms_refdiv);806 regmap_write(hdptx->regmap, CMN_REG(005a), cfg->pms_sdiv << 4);807 808 regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK,809 FIELD_PREP(ROPLL_SDM_EN_MASK, cfg->sdm_en));810 if (!cfg->sdm_en)811 regmap_update_bits(hdptx->regmap, CMN_REG(005e), 0xf, 0);812 813 regmap_update_bits(hdptx->regmap, CMN_REG(0064), ROPLL_SDM_NUM_SIGN_RBR_MASK,814 FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, cfg->sdm_num_sign));815 816 regmap_write(hdptx->regmap, CMN_REG(0060), cfg->sdm_deno);817 regmap_write(hdptx->regmap, CMN_REG(0065), cfg->sdm_num);818 819 regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,820 FIELD_PREP(ROPLL_SDC_N_RBR_MASK, cfg->sdc_n));821 822 regmap_write(hdptx->regmap, CMN_REG(006c), cfg->sdc_num);823 regmap_write(hdptx->regmap, CMN_REG(0070), cfg->sdc_deno);824 825 regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,826 FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));827 828 regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN,829 PLL_PCG_CLK_EN);830 831 return rk_hdptx_post_enable_pll(hdptx);832}833 834static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,835 unsigned int rate)836{837 rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq);838 839 regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);840 841 if (rate >= 3400000) {842 /* For 1/40 bitrate clk */843 rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq);844 } else {845 /* For 1/10 bitrate clk */846 rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_lowbr_seq);847 }848 849 regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07);850 regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);851 852 rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq);853 rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq);854 855 return rk_hdptx_post_enable_lane(hdptx);856}857 858static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx,859 unsigned int rate)860{861 u32 status;862 int ret;863 864 if (atomic_inc_return(&hdptx->usage_count) > 1)865 return 0;866 867 ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &status);868 if (ret)869 goto dec_usage;870 871 if (status & HDPTX_O_PLL_LOCK_DONE)872 dev_warn(hdptx->dev, "PLL locked by unknown consumer!\n");873 874 if (rate) {875 ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate);876 if (ret)877 goto dec_usage;878 }879 880 return 0;881 882dec_usage:883 atomic_dec(&hdptx->usage_count);884 return ret;885}886 887static int rk_hdptx_phy_consumer_put(struct rk_hdptx_phy *hdptx, bool force)888{889 u32 status;890 int ret;891 892 ret = atomic_dec_return(&hdptx->usage_count);893 if (ret > 0)894 return 0;895 896 if (ret < 0) {897 dev_warn(hdptx->dev, "Usage count underflow!\n");898 ret = -EINVAL;899 } else {900 ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &status);901 if (!ret) {902 if (status & HDPTX_O_PLL_LOCK_DONE)903 rk_hdptx_phy_disable(hdptx);904 return 0;905 } else if (force) {906 return 0;907 }908 }909 910 atomic_inc(&hdptx->usage_count);911 return ret;912}913 914static int rk_hdptx_phy_power_on(struct phy *phy)915{916 struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);917 int bus_width = phy_get_bus_width(hdptx->phy);918 int ret;919 920 /*921 * FIXME: Temporary workaround to pass pixel_clk_rate922 * from the HDMI bridge driver until phy_configure_opts_hdmi923 * becomes available in the PHY API.924 */925 unsigned int rate = bus_width & 0xfffffff;926 927 dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",928 __func__, bus_width, rate);929 930 ret = rk_hdptx_phy_consumer_get(hdptx, rate);931 if (ret)932 return ret;933 934 ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);935 if (ret)936 rk_hdptx_phy_consumer_put(hdptx, true);937 938 return ret;939}940 941static int rk_hdptx_phy_power_off(struct phy *phy)942{943 struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);944 945 return rk_hdptx_phy_consumer_put(hdptx, false);946}947 948static const struct phy_ops rk_hdptx_phy_ops = {949 .power_on = rk_hdptx_phy_power_on,950 .power_off = rk_hdptx_phy_power_off,951 .owner = THIS_MODULE,952};953 954static struct rk_hdptx_phy *to_rk_hdptx_phy(struct clk_hw *hw)955{956 return container_of(hw, struct rk_hdptx_phy, hw);957}958 959static int rk_hdptx_phy_clk_prepare(struct clk_hw *hw)960{961 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);962 963 return rk_hdptx_phy_consumer_get(hdptx, hdptx->rate / 100);964}965 966static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)967{968 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);969 970 rk_hdptx_phy_consumer_put(hdptx, true);971}972 973static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,974 unsigned long parent_rate)975{976 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);977 978 return hdptx->rate;979}980 981static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,982 unsigned long *parent_rate)983{984 u32 bit_rate = rate / 100;985 int i;986 987 if (rate > HDMI20_MAX_RATE)988 return rate;989 990 for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)991 if (bit_rate == ropll_tmds_cfg[i].bit_rate)992 break;993 994 if (i == ARRAY_SIZE(ropll_tmds_cfg) &&995 !rk_hdptx_phy_clk_pll_calc(bit_rate, NULL))996 return -EINVAL;997 998 return rate;999}1000 1001static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,1002 unsigned long parent_rate)1003{1004 struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);1005 1006 return rk_hdptx_ropll_tmds_cmn_config(hdptx, rate / 100);1007}1008 1009static const struct clk_ops hdptx_phy_clk_ops = {1010 .prepare = rk_hdptx_phy_clk_prepare,1011 .unprepare = rk_hdptx_phy_clk_unprepare,1012 .recalc_rate = rk_hdptx_phy_clk_recalc_rate,1013 .round_rate = rk_hdptx_phy_clk_round_rate,1014 .set_rate = rk_hdptx_phy_clk_set_rate,1015};1016 1017static int rk_hdptx_phy_clk_register(struct rk_hdptx_phy *hdptx)1018{1019 struct device *dev = hdptx->dev;1020 const char *name, *pname;1021 struct clk *refclk;1022 int ret, id;1023 1024 refclk = devm_clk_get(dev, "ref");1025 if (IS_ERR(refclk))1026 return dev_err_probe(dev, PTR_ERR(refclk),1027 "Failed to get ref clock\n");1028 1029 id = of_alias_get_id(dev->of_node, "hdptxphy");1030 name = id > 0 ? "clk_hdmiphy_pixel1" : "clk_hdmiphy_pixel0";1031 pname = __clk_get_name(refclk);1032 1033 hdptx->hw.init = CLK_HW_INIT(name, pname, &hdptx_phy_clk_ops,1034 CLK_GET_RATE_NOCACHE);1035 1036 ret = devm_clk_hw_register(dev, &hdptx->hw);1037 if (ret)1038 return dev_err_probe(dev, ret, "Failed to register clock\n");1039 1040 ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &hdptx->hw);1041 if (ret)1042 return dev_err_probe(dev, ret,1043 "Failed to register clk provider\n");1044 return 0;1045}1046 1047static int rk_hdptx_phy_runtime_suspend(struct device *dev)1048{1049 struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev);1050 1051 clk_bulk_disable_unprepare(hdptx->nr_clks, hdptx->clks);1052 1053 return 0;1054}1055 1056static int rk_hdptx_phy_runtime_resume(struct device *dev)1057{1058 struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev);1059 int ret;1060 1061 ret = clk_bulk_prepare_enable(hdptx->nr_clks, hdptx->clks);1062 if (ret)1063 dev_err(hdptx->dev, "Failed to enable clocks: %d\n", ret);1064 1065 return ret;1066}1067 1068static int rk_hdptx_phy_probe(struct platform_device *pdev)1069{1070 struct phy_provider *phy_provider;1071 struct device *dev = &pdev->dev;1072 struct rk_hdptx_phy *hdptx;1073 void __iomem *regs;1074 int ret;1075 1076 hdptx = devm_kzalloc(dev, sizeof(*hdptx), GFP_KERNEL);1077 if (!hdptx)1078 return -ENOMEM;1079 1080 hdptx->dev = dev;1081 1082 regs = devm_platform_ioremap_resource(pdev, 0);1083 if (IS_ERR(regs))1084 return dev_err_probe(dev, PTR_ERR(regs),1085 "Failed to ioremap resource\n");1086 1087 ret = devm_clk_bulk_get_all(dev, &hdptx->clks);1088 if (ret < 0)1089 return dev_err_probe(dev, ret, "Failed to get clocks\n");1090 if (ret == 0)1091 return dev_err_probe(dev, -EINVAL, "Missing clocks\n");1092 1093 hdptx->nr_clks = ret;1094 1095 hdptx->regmap = devm_regmap_init_mmio(dev, regs,1096 &rk_hdptx_phy_regmap_config);1097 if (IS_ERR(hdptx->regmap))1098 return dev_err_probe(dev, PTR_ERR(hdptx->regmap),1099 "Failed to init regmap\n");1100 1101 hdptx->rsts[RST_PHY].id = "phy";1102 hdptx->rsts[RST_APB].id = "apb";1103 hdptx->rsts[RST_INIT].id = "init";1104 hdptx->rsts[RST_CMN].id = "cmn";1105 hdptx->rsts[RST_LANE].id = "lane";1106 hdptx->rsts[RST_ROPLL].id = "ropll";1107 hdptx->rsts[RST_LCPLL].id = "lcpll";1108 1109 ret = devm_reset_control_bulk_get_exclusive(dev, RST_MAX, hdptx->rsts);1110 if (ret)1111 return dev_err_probe(dev, ret, "Failed to get resets\n");1112 1113 hdptx->grf = syscon_regmap_lookup_by_phandle(dev->of_node,1114 "rockchip,grf");1115 if (IS_ERR(hdptx->grf))1116 return dev_err_probe(dev, PTR_ERR(hdptx->grf),1117 "Could not get GRF syscon\n");1118 1119 ret = devm_pm_runtime_enable(dev);1120 if (ret)1121 return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");1122 1123 hdptx->phy = devm_phy_create(dev, NULL, &rk_hdptx_phy_ops);1124 if (IS_ERR(hdptx->phy))1125 return dev_err_probe(dev, PTR_ERR(hdptx->phy),1126 "Failed to create HDMI PHY\n");1127 1128 platform_set_drvdata(pdev, hdptx);1129 phy_set_drvdata(hdptx->phy, hdptx);1130 phy_set_bus_width(hdptx->phy, 8);1131 1132 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);1133 if (IS_ERR(phy_provider))1134 return dev_err_probe(dev, PTR_ERR(phy_provider),1135 "Failed to register PHY provider\n");1136 1137 reset_control_deassert(hdptx->rsts[RST_APB].rstc);1138 reset_control_deassert(hdptx->rsts[RST_CMN].rstc);1139 reset_control_deassert(hdptx->rsts[RST_INIT].rstc);1140 1141 return rk_hdptx_phy_clk_register(hdptx);1142}1143 1144static const struct dev_pm_ops rk_hdptx_phy_pm_ops = {1145 RUNTIME_PM_OPS(rk_hdptx_phy_runtime_suspend,1146 rk_hdptx_phy_runtime_resume, NULL)1147};1148 1149static const struct of_device_id rk_hdptx_phy_of_match[] = {1150 { .compatible = "rockchip,rk3588-hdptx-phy", },1151 {}1152};1153MODULE_DEVICE_TABLE(of, rk_hdptx_phy_of_match);1154 1155static struct platform_driver rk_hdptx_phy_driver = {1156 .probe = rk_hdptx_phy_probe,1157 .driver = {1158 .name = "rockchip-hdptx-phy",1159 .pm = &rk_hdptx_phy_pm_ops,1160 .of_match_table = rk_hdptx_phy_of_match,1161 },1162};1163module_platform_driver(rk_hdptx_phy_driver);1164 1165MODULE_AUTHOR("Algea Cao <algea.cao@rock-chips.com>");1166MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@collabora.com>");1167MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver");1168MODULE_LICENSE("GPL");1169