^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Zheng Yang <zhengyang@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Heiko Stuebner <heiko@sntech.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/nvmem-consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* REG: 0x00 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define RK3228_PRE_PLL_REFCLK_SEL_PCLK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* REG: 0x01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define RK3228_BYPASS_RXSENSE_EN BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define RK3228_BYPASS_PWRON_EN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define RK3228_BYPASS_PLLPD_EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* REG: 0x02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define RK3228_BYPASS_PDATA_EN BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define RK3228_PDATAEN_DISABLE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* REG: 0x03 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define RK3228_BYPASS_AUTO_TERM_RES_CAL BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define RK3228_AUTO_TERM_RES_CAL_SPEED_14_8(x) UPDATE(x, 6, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* REG: 0x04 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define RK3228_AUTO_TERM_RES_CAL_SPEED_7_0(x) UPDATE(x, 7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* REG: 0xaa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define RK3228_POST_PLL_CTRL_MANUAL BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* REG: 0xe0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define RK3228_POST_PLL_POWER_DOWN BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define RK3228_PRE_PLL_POWER_DOWN BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define RK3228_RXSENSE_CLK_CH_ENABLE BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define RK3228_RXSENSE_DATA_CH2_ENABLE BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define RK3228_RXSENSE_DATA_CH1_ENABLE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define RK3228_RXSENSE_DATA_CH0_ENABLE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* REG: 0xe1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define RK3228_BANDGAP_ENABLE BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define RK3228_TMDS_DRIVER_ENABLE GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* REG: 0xe2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define RK3228_PRE_PLL_FB_DIV_8_MASK BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define RK3228_PRE_PLL_FB_DIV_8(x) UPDATE((x) >> 8, 7, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define RK3228_PCLK_VCO_DIV_5_MASK BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define RK3228_PCLK_VCO_DIV_5(x) UPDATE(x, 5, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define RK3228_PRE_PLL_PRE_DIV_MASK GENMASK(4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define RK3228_PRE_PLL_PRE_DIV(x) UPDATE(x, 4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* REG: 0xe3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define RK3228_PRE_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* REG: 0xe4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define RK3228_PRE_PLL_PCLK_DIV_B_MASK GENMASK(6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define RK3228_PRE_PLL_PCLK_DIV_B_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define RK3228_PRE_PLL_PCLK_DIV_B(x) UPDATE(x, 6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define RK3228_PRE_PLL_PCLK_DIV_A_MASK GENMASK(4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define RK3228_PRE_PLL_PCLK_DIV_A(x) UPDATE(x, 4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* REG: 0xe5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define RK3228_PRE_PLL_PCLK_DIV_C_MASK GENMASK(6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define RK3228_PRE_PLL_PCLK_DIV_C(x) UPDATE(x, 6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define RK3228_PRE_PLL_PCLK_DIV_D_MASK GENMASK(4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define RK3228_PRE_PLL_PCLK_DIV_D(x) UPDATE(x, 4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* REG: 0xe6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define RK3228_PRE_PLL_TMDSCLK_DIV_C_MASK GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define RK3228_PRE_PLL_TMDSCLK_DIV_C(x) UPDATE(x, 5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define RK3228_PRE_PLL_TMDSCLK_DIV_A_MASK GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define RK3228_PRE_PLL_TMDSCLK_DIV_A(x) UPDATE(x, 3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define RK3228_PRE_PLL_TMDSCLK_DIV_B_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define RK3228_PRE_PLL_TMDSCLK_DIV_B(x) UPDATE(x, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* REG: 0xe8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define RK3228_PRE_PLL_LOCK_STATUS BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* REG: 0xe9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define RK3228_POST_PLL_POST_DIV_ENABLE UPDATE(3, 7, 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define RK3228_POST_PLL_PRE_DIV_MASK GENMASK(4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define RK3228_POST_PLL_PRE_DIV(x) UPDATE(x, 4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* REG: 0xea */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define RK3228_POST_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* REG: 0xeb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define RK3228_POST_PLL_FB_DIV_8_MASK BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define RK3228_POST_PLL_FB_DIV_8(x) UPDATE((x) >> 8, 7, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define RK3228_POST_PLL_POST_DIV_MASK GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define RK3228_POST_PLL_POST_DIV(x) UPDATE(x, 5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define RK3228_POST_PLL_LOCK_STATUS BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* REG: 0xee */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define RK3228_TMDS_CH_TA_ENABLE GENMASK(7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* REG: 0xef */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define RK3228_TMDS_CLK_CH_TA(x) UPDATE(x, 7, 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define RK3228_TMDS_DATA_CH2_TA(x) UPDATE(x, 5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define RK3228_TMDS_DATA_CH1_TA(x) UPDATE(x, 3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define RK3228_TMDS_DATA_CH0_TA(x) UPDATE(x, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* REG: 0xf0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define RK3228_TMDS_DATA_CH2_PRE_EMPHASIS_MASK GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define RK3228_TMDS_DATA_CH2_PRE_EMPHASIS(x) UPDATE(x, 5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define RK3228_TMDS_DATA_CH1_PRE_EMPHASIS_MASK GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define RK3228_TMDS_DATA_CH1_PRE_EMPHASIS(x) UPDATE(x, 3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define RK3228_TMDS_DATA_CH0_PRE_EMPHASIS_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define RK3228_TMDS_DATA_CH0_PRE_EMPHASIS(x) UPDATE(x, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* REG: 0xf1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define RK3228_TMDS_CLK_CH_OUTPUT_SWING(x) UPDATE(x, 7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define RK3228_TMDS_DATA_CH2_OUTPUT_SWING(x) UPDATE(x, 3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* REG: 0xf2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define RK3228_TMDS_DATA_CH1_OUTPUT_SWING(x) UPDATE(x, 7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define RK3228_TMDS_DATA_CH0_OUTPUT_SWING(x) UPDATE(x, 3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* REG: 0x01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define RK3328_BYPASS_RXSENSE_EN BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define RK3328_BYPASS_POWERON_EN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define RK3328_BYPASS_PLLPD_EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* REG: 0x02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define RK3328_INT_POL_HIGH BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define RK3328_BYPASS_PDATA_EN BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define RK3328_PDATA_EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* REG:0x05 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define RK3328_INT_TMDS_CLK(x) UPDATE(x, 7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define RK3328_INT_TMDS_D2(x) UPDATE(x, 3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* REG:0x07 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define RK3328_INT_TMDS_D1(x) UPDATE(x, 7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define RK3328_INT_TMDS_D0(x) UPDATE(x, 3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* for all RK3328_INT_TMDS_*, ESD_DET as defined in 0xc8-0xcb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define RK3328_INT_AGND_LOW_PULSE_LOCKED BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define RK3328_INT_RXSENSE_LOW_PULSE_LOCKED BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define RK3328_INT_VSS_AGND_ESD_DET BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define RK3328_INT_AGND_VSS_ESD_DET BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* REG: 0xa0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define RK3328_PCLK_VCO_DIV_5_MASK BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define RK3328_PCLK_VCO_DIV_5(x) UPDATE(x, 1, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define RK3328_PRE_PLL_POWER_DOWN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* REG: 0xa1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define RK3328_PRE_PLL_PRE_DIV_MASK GENMASK(5, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define RK3328_PRE_PLL_PRE_DIV(x) UPDATE(x, 5, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* REG: 0xa2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* unset means center spread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define RK3328_SPREAD_SPECTRUM_MOD_DOWN BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define RK3328_SPREAD_SPECTRUM_MOD_DISABLE BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define RK3328_PRE_PLL_FRAC_DIV_DISABLE UPDATE(3, 5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define RK3328_PRE_PLL_FB_DIV_11_8_MASK GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define RK3328_PRE_PLL_FB_DIV_11_8(x) UPDATE((x) >> 8, 3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* REG: 0xa3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define RK3328_PRE_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* REG: 0xa4*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define RK3328_PRE_PLL_TMDSCLK_DIV_C_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define RK3328_PRE_PLL_TMDSCLK_DIV_C(x) UPDATE(x, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define RK3328_PRE_PLL_TMDSCLK_DIV_B_MASK GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define RK3328_PRE_PLL_TMDSCLK_DIV_B(x) UPDATE(x, 3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define RK3328_PRE_PLL_TMDSCLK_DIV_A_MASK GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define RK3328_PRE_PLL_TMDSCLK_DIV_A(x) UPDATE(x, 5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* REG: 0xa5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define RK3328_PRE_PLL_PCLK_DIV_B_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define RK3328_PRE_PLL_PCLK_DIV_B_MASK GENMASK(6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define RK3328_PRE_PLL_PCLK_DIV_B(x) UPDATE(x, 6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define RK3328_PRE_PLL_PCLK_DIV_A_MASK GENMASK(4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define RK3328_PRE_PLL_PCLK_DIV_A(x) UPDATE(x, 4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* REG: 0xa6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define RK3328_PRE_PLL_PCLK_DIV_C_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define RK3328_PRE_PLL_PCLK_DIV_C_MASK GENMASK(6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define RK3328_PRE_PLL_PCLK_DIV_C(x) UPDATE(x, 6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define RK3328_PRE_PLL_PCLK_DIV_D_MASK GENMASK(4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define RK3328_PRE_PLL_PCLK_DIV_D(x) UPDATE(x, 4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* REG: 0xa9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define RK3328_PRE_PLL_LOCK_STATUS BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* REG: 0xaa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define RK3328_POST_PLL_POST_DIV_ENABLE GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define RK3328_POST_PLL_REFCLK_SEL_TMDS BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define RK3328_POST_PLL_POWER_DOWN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* REG:0xab */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define RK3328_POST_PLL_FB_DIV_8(x) UPDATE((x) >> 8, 7, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define RK3328_POST_PLL_PRE_DIV(x) UPDATE(x, 4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* REG: 0xac */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define RK3328_POST_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* REG: 0xad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define RK3328_POST_PLL_POST_DIV_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define RK3328_POST_PLL_POST_DIV_2 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define RK3328_POST_PLL_POST_DIV_4 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define RK3328_POST_PLL_POST_DIV_8 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* REG: 0xaf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define RK3328_POST_PLL_LOCK_STATUS BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* REG: 0xb0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define RK3328_BANDGAP_ENABLE BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* REG: 0xb2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define RK3328_TMDS_CLK_DRIVER_EN BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define RK3328_TMDS_D2_DRIVER_EN BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define RK3328_TMDS_D1_DRIVER_EN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define RK3328_TMDS_D0_DRIVER_EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define RK3328_TMDS_DRIVER_ENABLE (RK3328_TMDS_CLK_DRIVER_EN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) RK3328_TMDS_D2_DRIVER_EN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) RK3328_TMDS_D1_DRIVER_EN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) RK3328_TMDS_D0_DRIVER_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* REG:0xc5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define RK3328_BYPASS_TERM_RESISTOR_CALIB BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define RK3328_TERM_RESISTOR_CALIB_SPEED_14_8(x) UPDATE((x) >> 8, 6, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* REG:0xc6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define RK3328_TERM_RESISTOR_CALIB_SPEED_7_0(x) UPDATE(x, 7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* REG:0xc7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define RK3328_TERM_RESISTOR_50 UPDATE(0, 2, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define RK3328_TERM_RESISTOR_62_5 UPDATE(1, 2, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define RK3328_TERM_RESISTOR_75 UPDATE(2, 2, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define RK3328_TERM_RESISTOR_100 UPDATE(3, 2, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* REG 0xc8 - 0xcb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define RK3328_ESD_DETECT_MASK GENMASK(7, 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define RK3328_ESD_DETECT_340MV (0x0 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #define RK3328_ESD_DETECT_280MV (0x1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define RK3328_ESD_DETECT_260MV (0x2 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define RK3328_ESD_DETECT_240MV (0x3 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /* resistors can be used in parallel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define RK3328_TMDS_TERM_RESIST_MASK GENMASK(5, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define RK3328_TMDS_TERM_RESIST_75 BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define RK3328_TMDS_TERM_RESIST_150 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define RK3328_TMDS_TERM_RESIST_300 BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define RK3328_TMDS_TERM_RESIST_600 BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define RK3328_TMDS_TERM_RESIST_1000 BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define RK3328_TMDS_TERM_RESIST_2000 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* REG: 0xd1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define RK3328_PRE_PLL_FRAC_DIV_23_16(x) UPDATE((x) >> 16, 7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* REG: 0xd2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define RK3328_PRE_PLL_FRAC_DIV_15_8(x) UPDATE((x) >> 8, 7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* REG: 0xd3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define RK3328_PRE_PLL_FRAC_DIV_7_0(x) UPDATE(x, 7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct inno_hdmi_phy_drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct inno_hdmi_phy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct clk *sysclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct clk *refoclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct clk *refpclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* platform data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) const struct inno_hdmi_phy_drv_data *plat_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int chip_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* clk provider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct clk *phyclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned long pixclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct pre_pll_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) unsigned long pixclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) unsigned long tmdsclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) u8 prediv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u16 fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u8 tmds_div_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u8 tmds_div_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) u8 tmds_div_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) u8 pclk_div_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) u8 pclk_div_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) u8 pclk_div_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u8 pclk_div_d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) u8 vco_div_5_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u32 fracdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct post_pll_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned long tmdsclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u8 prediv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u16 fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) u8 postdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) u8 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct phy_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) unsigned long tmdsclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u8 regs[14];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct inno_hdmi_phy_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int (*init)(struct inno_hdmi_phy *inno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int (*power_on)(struct inno_hdmi_phy *inno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) const struct post_pll_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) const struct phy_config *phy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) void (*power_off)(struct inno_hdmi_phy *inno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct inno_hdmi_phy_drv_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) const struct inno_hdmi_phy_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) const struct clk_ops *clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) const struct phy_config *phy_cfg_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static const struct pre_pll_config pre_pll_cfg_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) { 27000000, 27000000, 1, 90, 3, 2, 2, 10, 3, 3, 4, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) { 27000000, 33750000, 1, 90, 1, 3, 3, 10, 3, 3, 4, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) { 40000000, 40000000, 1, 80, 2, 2, 2, 12, 2, 2, 2, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) { 59341000, 59341000, 1, 98, 3, 1, 2, 1, 3, 3, 4, 0, 0xE6AE6B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) { 59400000, 59400000, 1, 99, 3, 1, 1, 1, 3, 3, 4, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) { 59341000, 74176250, 1, 98, 0, 3, 3, 1, 3, 3, 4, 0, 0xE6AE6B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) { 59400000, 74250000, 1, 99, 1, 2, 2, 1, 3, 3, 4, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) { 74176000, 74176000, 1, 98, 1, 2, 2, 1, 2, 3, 4, 0, 0xE6AE6B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) { 74250000, 74250000, 1, 99, 1, 2, 2, 1, 2, 3, 4, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) { 74176000, 92720000, 4, 494, 1, 2, 2, 1, 3, 3, 4, 0, 0x816817},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) { 74250000, 92812500, 4, 495, 1, 2, 2, 1, 3, 3, 4, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {148352000, 148352000, 1, 98, 1, 1, 1, 1, 2, 2, 2, 0, 0xE6AE6B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {148500000, 148500000, 1, 99, 1, 1, 1, 1, 2, 2, 2, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {148352000, 185440000, 4, 494, 0, 2, 2, 1, 3, 2, 2, 0, 0x816817},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {148500000, 185625000, 4, 495, 0, 2, 2, 1, 3, 2, 2, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {296703000, 296703000, 1, 98, 0, 1, 1, 1, 0, 2, 2, 0, 0xE6AE6B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {297000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 2, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {296703000, 370878750, 4, 494, 1, 2, 0, 1, 3, 1, 1, 0, 0x816817},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {297000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {593407000, 296703500, 1, 98, 0, 1, 1, 1, 0, 2, 1, 0, 0xE6AE6B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {594000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 1, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {593407000, 370879375, 4, 494, 1, 2, 0, 1, 3, 1, 1, 1, 0x816817},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static const struct post_pll_config post_pll_cfg_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {33750000, 1, 40, 8, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {33750000, 1, 80, 8, 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {74250000, 1, 40, 8, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {74250000, 18, 80, 8, 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {148500000, 2, 40, 4, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {297000000, 4, 40, 2, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {594000000, 8, 40, 1, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* phy tuning values for an undocumented set of registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static const struct phy_config rk3228_phy_cfg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) { 165000000, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 0xaa, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 340000000, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 0xaa, 0x15, 0x6a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 594000000, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 0xaa, 0x15, 0x7a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }, { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* phy tuning values for an undocumented set of registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static const struct phy_config rk3328_phy_cfg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) { 165000000, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 0x07, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x08, 0x08, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 0x00, 0xac, 0xcc, 0xcc, 0xcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 340000000, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 0x0b, 0x0d, 0x0d, 0x0d, 0x07, 0x15, 0x08, 0x08, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 0x3f, 0xac, 0xcc, 0xcd, 0xdd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 594000000, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 0x10, 0x1a, 0x1a, 0x1a, 0x07, 0x15, 0x08, 0x08, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 0x00, 0xac, 0xcc, 0xcc, 0xcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }, { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static inline struct inno_hdmi_phy *to_inno_hdmi_phy(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return container_of(hw, struct inno_hdmi_phy, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * The register description of the IP block does not use any distinct names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * but instead the databook simply numbers the registers in one-increments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * As the registers are obviously 32bit sized, the inno_* functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * translate the databook register names to the actual registers addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static inline void inno_write(struct inno_hdmi_phy *inno, u32 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) regmap_write(inno->regmap, reg * 4, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static inline u8 inno_read(struct inno_hdmi_phy *inno, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) regmap_read(inno->regmap, reg * 4, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static inline void inno_update_bits(struct inno_hdmi_phy *inno, u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) u8 mask, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) regmap_update_bits(inno->regmap, reg * 4, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) #define inno_poll(inno, reg, val, cond, sleep_us, timeout_us) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) regmap_read_poll_timeout((inno)->regmap, (reg) * 4, val, cond, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) sleep_us, timeout_us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static unsigned long inno_hdmi_phy_get_tmdsclk(struct inno_hdmi_phy *inno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) int bus_width = phy_get_bus_width(inno->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) switch (bus_width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return (u64)rate * bus_width / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static irqreturn_t inno_hdmi_phy_rk3328_hardirq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct inno_hdmi_phy *inno = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int intr_stat1, intr_stat2, intr_stat3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) intr_stat1 = inno_read(inno, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) intr_stat2 = inno_read(inno, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) intr_stat3 = inno_read(inno, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (intr_stat1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) inno_write(inno, 0x04, intr_stat1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (intr_stat2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) inno_write(inno, 0x06, intr_stat2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (intr_stat3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) inno_write(inno, 0x08, intr_stat3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (intr_stat1 || intr_stat2 || intr_stat3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return IRQ_WAKE_THREAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static irqreturn_t inno_hdmi_phy_rk3328_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct inno_hdmi_phy *inno = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) inno_update_bits(inno, 0x02, RK3328_PDATA_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) inno_update_bits(inno, 0x02, RK3328_PDATA_EN, RK3328_PDATA_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int inno_hdmi_phy_power_on(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct inno_hdmi_phy *inno = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) const struct post_pll_config *cfg = post_pll_cfg_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) const struct phy_config *phy_cfg = inno->plat_data->phy_cfg_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) unsigned long tmdsclock = inno_hdmi_phy_get_tmdsclk(inno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) inno->pixclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (!tmdsclock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) dev_err(inno->dev, "TMDS clock is zero!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (!inno->plat_data->ops->power_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) for (; cfg->tmdsclock != 0; cfg++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (tmdsclock <= cfg->tmdsclock &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) cfg->version & inno->chip_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) for (; phy_cfg->tmdsclock != 0; phy_cfg++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (tmdsclock <= phy_cfg->tmdsclock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (cfg->tmdsclock == 0 || phy_cfg->tmdsclock == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) dev_dbg(inno->dev, "Inno HDMI PHY Power On\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ret = clk_prepare_enable(inno->phyclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = inno->plat_data->ops->power_on(inno, cfg, phy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) clk_disable_unprepare(inno->phyclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static int inno_hdmi_phy_power_off(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct inno_hdmi_phy *inno = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (!inno->plat_data->ops->power_off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) inno->plat_data->ops->power_off(inno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) clk_disable_unprepare(inno->phyclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dev_dbg(inno->dev, "Inno HDMI PHY Power Off\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static const struct phy_ops inno_hdmi_phy_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .power_on = inno_hdmi_phy_power_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) .power_off = inno_hdmi_phy_power_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static const
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct pre_pll_config *inno_hdmi_phy_get_pre_pll_cfg(struct inno_hdmi_phy *inno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) const struct pre_pll_config *cfg = pre_pll_cfg_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) unsigned long tmdsclock = inno_hdmi_phy_get_tmdsclk(inno, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) for (; cfg->pixclock != 0; cfg++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (cfg->pixclock == rate && cfg->tmdsclock == tmdsclock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (cfg->pixclock == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static int inno_hdmi_phy_rk3228_clk_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) status = inno_read(inno, 0xe0) & RK3228_PRE_PLL_POWER_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return status ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static int inno_hdmi_phy_rk3228_clk_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static void inno_hdmi_phy_rk3228_clk_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) RK3228_PRE_PLL_POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) unsigned long inno_hdmi_phy_rk3228_clk_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) u8 nd, no_a, no_b, no_d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) u64 vco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) u16 nf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) nd = inno_read(inno, 0xe2) & RK3228_PRE_PLL_PRE_DIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) nf = (inno_read(inno, 0xe2) & RK3228_PRE_PLL_FB_DIV_8_MASK) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) nf |= inno_read(inno, 0xe3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) vco = parent_rate * nf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (inno_read(inno, 0xe2) & RK3228_PCLK_VCO_DIV_5_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) do_div(vco, nd * 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) no_a = inno_read(inno, 0xe4) & RK3228_PRE_PLL_PCLK_DIV_A_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (!no_a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) no_a = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) no_b = inno_read(inno, 0xe4) & RK3228_PRE_PLL_PCLK_DIV_B_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) no_b >>= RK3228_PRE_PLL_PCLK_DIV_B_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) no_b += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) no_d = inno_read(inno, 0xe5) & RK3228_PRE_PLL_PCLK_DIV_D_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) inno->pixclock = vco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return vco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) unsigned long *parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) const struct pre_pll_config *cfg = pre_pll_cfg_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) rate = (rate / 1000) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) for (; cfg->pixclock != 0; cfg++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (cfg->pixclock == rate && !cfg->fracdiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (cfg->pixclock == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return cfg->pixclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) const struct pre_pll_config *cfg = pre_pll_cfg_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) unsigned long tmdsclock = inno_hdmi_phy_get_tmdsclk(inno, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) __func__, rate, tmdsclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (IS_ERR(cfg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return PTR_ERR(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* Power down PRE-PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) RK3228_PRE_PLL_POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) inno_update_bits(inno, 0xe2, RK3228_PRE_PLL_FB_DIV_8_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) RK3228_PCLK_VCO_DIV_5_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) RK3228_PRE_PLL_PRE_DIV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) RK3228_PRE_PLL_FB_DIV_8(cfg->fbdiv) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) RK3228_PRE_PLL_PRE_DIV(cfg->prediv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) inno_write(inno, 0xe3, RK3228_PRE_PLL_FB_DIV_7_0(cfg->fbdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) inno_update_bits(inno, 0xe4, RK3228_PRE_PLL_PCLK_DIV_B_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) RK3228_PRE_PLL_PCLK_DIV_A_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) RK3228_PRE_PLL_PCLK_DIV_B(cfg->pclk_div_b) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) RK3228_PRE_PLL_PCLK_DIV_A(cfg->pclk_div_a));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) inno_update_bits(inno, 0xe5, RK3228_PRE_PLL_PCLK_DIV_C_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) RK3228_PRE_PLL_PCLK_DIV_D_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) RK3228_PRE_PLL_PCLK_DIV_C(cfg->pclk_div_c) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) RK3228_PRE_PLL_PCLK_DIV_D(cfg->pclk_div_d));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) inno_update_bits(inno, 0xe6, RK3228_PRE_PLL_TMDSCLK_DIV_C_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) RK3228_PRE_PLL_TMDSCLK_DIV_A_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) RK3228_PRE_PLL_TMDSCLK_DIV_B_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) RK3228_PRE_PLL_TMDSCLK_DIV_C(cfg->tmds_div_c) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) RK3228_PRE_PLL_TMDSCLK_DIV_A(cfg->tmds_div_a) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) RK3228_PRE_PLL_TMDSCLK_DIV_B(cfg->tmds_div_b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* Power up PRE-PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* Wait for Pre-PLL lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ret = inno_poll(inno, 0xe8, v, v & RK3228_PRE_PLL_LOCK_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 100, 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) dev_err(inno->dev, "Pre-PLL locking failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) inno->pixclock = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static const struct clk_ops inno_hdmi_phy_rk3228_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) .prepare = inno_hdmi_phy_rk3228_clk_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) .unprepare = inno_hdmi_phy_rk3228_clk_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) .is_prepared = inno_hdmi_phy_rk3228_clk_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .recalc_rate = inno_hdmi_phy_rk3228_clk_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .round_rate = inno_hdmi_phy_rk3228_clk_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) .set_rate = inno_hdmi_phy_rk3228_clk_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static int inno_hdmi_phy_rk3328_clk_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) status = inno_read(inno, 0xa0) & RK3328_PRE_PLL_POWER_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return status ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) static int inno_hdmi_phy_rk3328_clk_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) inno_update_bits(inno, 0xa0, RK3328_PRE_PLL_POWER_DOWN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static void inno_hdmi_phy_rk3328_clk_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) inno_update_bits(inno, 0xa0, RK3328_PRE_PLL_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) RK3328_PRE_PLL_POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) unsigned long frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) u8 nd, no_a, no_b, no_c, no_d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) u64 vco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) u16 nf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) nd = inno_read(inno, 0xa1) & RK3328_PRE_PLL_PRE_DIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) nf = ((inno_read(inno, 0xa2) & RK3328_PRE_PLL_FB_DIV_11_8_MASK) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) nf |= inno_read(inno, 0xa3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) vco = parent_rate * nf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (!(inno_read(inno, 0xa2) & RK3328_PRE_PLL_FRAC_DIV_DISABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) frac = inno_read(inno, 0xd3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) (inno_read(inno, 0xd2) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) (inno_read(inno, 0xd1) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) vco += DIV_ROUND_CLOSEST(parent_rate * frac, (1 << 24));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (inno_read(inno, 0xa0) & RK3328_PCLK_VCO_DIV_5_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) do_div(vco, nd * 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) no_a = inno_read(inno, 0xa5) & RK3328_PRE_PLL_PCLK_DIV_A_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) no_b = inno_read(inno, 0xa5) & RK3328_PRE_PLL_PCLK_DIV_B_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) no_b >>= RK3328_PRE_PLL_PCLK_DIV_B_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) no_b += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) no_c = inno_read(inno, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_C_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) no_c >>= RK3328_PRE_PLL_PCLK_DIV_C_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) no_c = 1 << no_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) no_d = inno_read(inno, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_D_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) inno->pixclock = vco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return vco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) unsigned long *parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) const struct pre_pll_config *cfg = pre_pll_cfg_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) rate = (rate / 1000) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) for (; cfg->pixclock != 0; cfg++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (cfg->pixclock == rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (cfg->pixclock == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return cfg->pixclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) const struct pre_pll_config *cfg = pre_pll_cfg_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) unsigned long tmdsclock = inno_hdmi_phy_get_tmdsclk(inno, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) __func__, rate, tmdsclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (IS_ERR(cfg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return PTR_ERR(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) inno_update_bits(inno, 0xa0, RK3328_PRE_PLL_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) RK3328_PRE_PLL_POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /* Configure pre-pll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) inno_update_bits(inno, 0xa0, RK3228_PCLK_VCO_DIV_5_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) inno_write(inno, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (!cfg->fracdiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) val |= RK3328_PRE_PLL_FRAC_DIV_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) inno_write(inno, 0xa2, RK3328_PRE_PLL_FB_DIV_11_8(cfg->fbdiv) | val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) inno_write(inno, 0xa3, RK3328_PRE_PLL_FB_DIV_7_0(cfg->fbdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) inno_write(inno, 0xa5, RK3328_PRE_PLL_PCLK_DIV_A(cfg->pclk_div_a) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) RK3328_PRE_PLL_PCLK_DIV_B(cfg->pclk_div_b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) inno_write(inno, 0xa6, RK3328_PRE_PLL_PCLK_DIV_C(cfg->pclk_div_c) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) RK3328_PRE_PLL_PCLK_DIV_D(cfg->pclk_div_d));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) inno_write(inno, 0xa4, RK3328_PRE_PLL_TMDSCLK_DIV_C(cfg->tmds_div_c) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) RK3328_PRE_PLL_TMDSCLK_DIV_A(cfg->tmds_div_a) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) RK3328_PRE_PLL_TMDSCLK_DIV_B(cfg->tmds_div_b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) inno_write(inno, 0xd3, RK3328_PRE_PLL_FRAC_DIV_7_0(cfg->fracdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) inno_write(inno, 0xd2, RK3328_PRE_PLL_FRAC_DIV_15_8(cfg->fracdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) inno_write(inno, 0xd1, RK3328_PRE_PLL_FRAC_DIV_23_16(cfg->fracdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) inno_update_bits(inno, 0xa0, RK3328_PRE_PLL_POWER_DOWN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* Wait for Pre-PLL lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) ret = inno_poll(inno, 0xa9, val, val & RK3328_PRE_PLL_LOCK_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 1000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) dev_err(inno->dev, "Pre-PLL locking failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) inno->pixclock = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static const struct clk_ops inno_hdmi_phy_rk3328_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) .prepare = inno_hdmi_phy_rk3328_clk_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .unprepare = inno_hdmi_phy_rk3328_clk_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) .is_prepared = inno_hdmi_phy_rk3328_clk_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) .recalc_rate = inno_hdmi_phy_rk3328_clk_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .round_rate = inno_hdmi_phy_rk3328_clk_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .set_rate = inno_hdmi_phy_rk3328_clk_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy *inno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) struct device *dev = inno->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) parent_name = __clk_get_name(inno->refoclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) init.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) init.name = "pin_hd20_pclk";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) init.ops = inno->plat_data->clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) /* optional override of the clock name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) of_property_read_string(np, "clock-output-names", &init.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) inno->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) inno->phyclk = devm_clk_register(dev, &inno->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (IS_ERR(inno->phyclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) ret = PTR_ERR(inno->phyclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) dev_err(dev, "failed to register clock: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) ret = of_clk_add_provider(np, of_clk_src_simple_get, inno->phyclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) dev_err(dev, "failed to register clock provider: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * Use phy internal register control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * rxsense/poweron/pllpd/pdataen signal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) inno_write(inno, 0x01, RK3228_BYPASS_RXSENSE_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) RK3228_BYPASS_PWRON_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) RK3228_BYPASS_PLLPD_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) inno_update_bits(inno, 0x02, RK3228_BYPASS_PDATA_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) RK3228_BYPASS_PDATA_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* manual power down post-PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) inno_update_bits(inno, 0xaa, RK3228_POST_PLL_CTRL_MANUAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) RK3228_POST_PLL_CTRL_MANUAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) inno->chip_version = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) inno_hdmi_phy_rk3228_power_on(struct inno_hdmi_phy *inno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) const struct post_pll_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) const struct phy_config *phy_cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) inno_update_bits(inno, 0x02, RK3228_PDATAEN_DISABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) RK3228_PDATAEN_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) RK3228_POST_PLL_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) RK3228_PRE_PLL_POWER_DOWN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) RK3228_POST_PLL_POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /* Post-PLL update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) inno_update_bits(inno, 0xe9, RK3228_POST_PLL_PRE_DIV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) RK3228_POST_PLL_PRE_DIV(cfg->prediv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) inno_update_bits(inno, 0xeb, RK3228_POST_PLL_FB_DIV_8_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) RK3228_POST_PLL_FB_DIV_8(cfg->fbdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) inno_write(inno, 0xea, RK3228_POST_PLL_FB_DIV_7_0(cfg->fbdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (cfg->postdiv == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) inno_update_bits(inno, 0xe9, RK3228_POST_PLL_POST_DIV_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) int div = cfg->postdiv / 2 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) inno_update_bits(inno, 0xe9, RK3228_POST_PLL_POST_DIV_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) RK3228_POST_PLL_POST_DIV_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) inno_update_bits(inno, 0xeb, RK3228_POST_PLL_POST_DIV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) RK3228_POST_PLL_POST_DIV(div));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) for (v = 0; v < 4; v++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) inno_write(inno, 0xef + v, phy_cfg->regs[v]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) inno_update_bits(inno, 0xe0, RK3228_PRE_PLL_POWER_DOWN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) RK3228_POST_PLL_POWER_DOWN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) inno_update_bits(inno, 0xe1, RK3228_BANDGAP_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) RK3228_BANDGAP_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) inno_update_bits(inno, 0xe1, RK3228_TMDS_DRIVER_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) RK3228_TMDS_DRIVER_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) /* Wait for post PLL lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ret = inno_poll(inno, 0xeb, v, v & RK3228_POST_PLL_LOCK_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 100, 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) dev_err(inno->dev, "Post-PLL locking failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (cfg->tmdsclock > 340000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) inno_update_bits(inno, 0x02, RK3228_PDATAEN_DISABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) static void inno_hdmi_phy_rk3228_power_off(struct inno_hdmi_phy *inno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) inno_update_bits(inno, 0xe1, RK3228_TMDS_DRIVER_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) inno_update_bits(inno, 0xe1, RK3228_BANDGAP_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) inno_update_bits(inno, 0xe0, RK3228_POST_PLL_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) RK3228_POST_PLL_POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) static const struct inno_hdmi_phy_ops rk3228_hdmi_phy_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .init = inno_hdmi_phy_rk3228_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .power_on = inno_hdmi_phy_rk3228_power_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .power_off = inno_hdmi_phy_rk3228_power_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct nvmem_cell *cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) unsigned char *efuse_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) * Use phy internal register control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) * rxsense/poweron/pllpd/pdataen signal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) inno_write(inno, 0x01, RK3328_BYPASS_RXSENSE_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) RK3328_BYPASS_POWERON_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) RK3328_BYPASS_PLLPD_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) inno_write(inno, 0x02, RK3328_INT_POL_HIGH | RK3328_BYPASS_PDATA_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) RK3328_PDATA_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) /* Disable phy irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) inno_write(inno, 0x05, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) inno_write(inno, 0x07, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /* try to read the chip-version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) inno->chip_version = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) cell = nvmem_cell_get(inno->dev, "cpu-version");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (IS_ERR(cell)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (PTR_ERR(cell) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) efuse_buf = nvmem_cell_read(cell, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) nvmem_cell_put(cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (IS_ERR(efuse_buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (len == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) inno->chip_version = efuse_buf[0] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) kfree(efuse_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) const struct post_pll_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) const struct phy_config *phy_cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) inno_update_bits(inno, 0x02, RK3328_PDATA_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) inno_update_bits(inno, 0xaa, RK3328_POST_PLL_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) RK3328_POST_PLL_POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) inno_write(inno, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (cfg->postdiv == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) RK3328_POST_PLL_PRE_DIV(cfg->prediv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) v = (cfg->postdiv / 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) v &= RK3328_POST_PLL_POST_DIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) inno_write(inno, 0xad, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) RK3328_POST_PLL_PRE_DIV(cfg->prediv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) inno_write(inno, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) RK3328_POST_PLL_REFCLK_SEL_TMDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) for (v = 0; v < 14; v++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) inno_write(inno, 0xb5 + v, phy_cfg->regs[v]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) /* set ESD detection threshold for TMDS CLK, D2, D1 and D0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) for (v = 0; v < 4; v++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) inno_update_bits(inno, 0xc8 + v, RK3328_ESD_DETECT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) RK3328_ESD_DETECT_340MV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (phy_cfg->tmdsclock > 340000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /* Set termination resistor to 100ohm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) v = clk_get_rate(inno->sysclk) / 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) inno_write(inno, 0xc5, RK3328_TERM_RESISTOR_CALIB_SPEED_14_8(v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) | RK3328_BYPASS_TERM_RESISTOR_CALIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) inno_write(inno, 0xc6, RK3328_TERM_RESISTOR_CALIB_SPEED_7_0(v));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) inno_write(inno, 0xc7, RK3328_TERM_RESISTOR_100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) inno_update_bits(inno, 0xc5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) RK3328_BYPASS_TERM_RESISTOR_CALIB, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) inno_write(inno, 0xc5, RK3328_BYPASS_TERM_RESISTOR_CALIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /* clk termination resistor is 50ohm (parallel resistors) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (phy_cfg->tmdsclock > 165000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) inno_update_bits(inno, 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) RK3328_TMDS_TERM_RESIST_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) RK3328_TMDS_TERM_RESIST_75 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) RK3328_TMDS_TERM_RESIST_150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /* data termination resistor for D2, D1 and D0 is 150ohm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) for (v = 0; v < 3; v++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) inno_update_bits(inno, 0xc9 + v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) RK3328_TMDS_TERM_RESIST_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) RK3328_TMDS_TERM_RESIST_150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) inno_update_bits(inno, 0xaa, RK3328_POST_PLL_POWER_DOWN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) inno_update_bits(inno, 0xb0, RK3328_BANDGAP_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) RK3328_BANDGAP_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) inno_update_bits(inno, 0xb2, RK3328_TMDS_DRIVER_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) RK3328_TMDS_DRIVER_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) /* Wait for post PLL lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) ret = inno_poll(inno, 0xaf, v, v & RK3328_POST_PLL_LOCK_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 1000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) dev_err(inno->dev, "Post-PLL locking failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (phy_cfg->tmdsclock > 340000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) inno_update_bits(inno, 0x02, RK3328_PDATA_EN, RK3328_PDATA_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /* Enable PHY IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) inno_write(inno, 0x05, RK3328_INT_TMDS_CLK(RK3328_INT_VSS_AGND_ESD_DET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) | RK3328_INT_TMDS_D2(RK3328_INT_VSS_AGND_ESD_DET));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) inno_write(inno, 0x07, RK3328_INT_TMDS_D1(RK3328_INT_VSS_AGND_ESD_DET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) | RK3328_INT_TMDS_D0(RK3328_INT_VSS_AGND_ESD_DET));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) static void inno_hdmi_phy_rk3328_power_off(struct inno_hdmi_phy *inno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) inno_update_bits(inno, 0xb2, RK3328_TMDS_DRIVER_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) inno_update_bits(inno, 0xb0, RK3328_BANDGAP_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) inno_update_bits(inno, 0xaa, RK3328_POST_PLL_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) RK3328_POST_PLL_POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) /* Disable PHY IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) inno_write(inno, 0x05, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) inno_write(inno, 0x07, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) static const struct inno_hdmi_phy_ops rk3328_hdmi_phy_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .init = inno_hdmi_phy_rk3328_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .power_on = inno_hdmi_phy_rk3328_power_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .power_off = inno_hdmi_phy_rk3328_power_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static const struct inno_hdmi_phy_drv_data rk3228_hdmi_phy_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) .ops = &rk3228_hdmi_phy_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) .clk_ops = &inno_hdmi_phy_rk3228_clk_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) .phy_cfg_table = rk3228_phy_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) static const struct inno_hdmi_phy_drv_data rk3328_hdmi_phy_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) .ops = &rk3328_hdmi_phy_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) .clk_ops = &inno_hdmi_phy_rk3328_clk_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) .phy_cfg_table = rk3328_phy_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) static const struct regmap_config inno_hdmi_phy_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) .max_register = 0x400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static void inno_hdmi_phy_action(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct inno_hdmi_phy *inno = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) clk_disable_unprepare(inno->refpclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) clk_disable_unprepare(inno->sysclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) static int inno_hdmi_phy_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct inno_hdmi_phy *inno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) struct phy_provider *phy_provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) inno = devm_kzalloc(&pdev->dev, sizeof(*inno), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (!inno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) inno->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) inno->plat_data = of_device_get_match_data(inno->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) if (!inno->plat_data || !inno->plat_data->ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) regs = devm_ioremap_resource(inno->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (IS_ERR(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return PTR_ERR(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) inno->sysclk = devm_clk_get(inno->dev, "sysclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (IS_ERR(inno->sysclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) ret = PTR_ERR(inno->sysclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) dev_err(inno->dev, "failed to get sysclk: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) inno->refpclk = devm_clk_get(inno->dev, "refpclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (IS_ERR(inno->refpclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) ret = PTR_ERR(inno->refpclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) dev_err(inno->dev, "failed to get ref clock: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) inno->refoclk = devm_clk_get(inno->dev, "refoclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (IS_ERR(inno->refoclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) ret = PTR_ERR(inno->refoclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) dev_err(inno->dev, "failed to get oscillator-ref clock: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) ret = clk_prepare_enable(inno->sysclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) dev_err(inno->dev, "Cannot enable inno phy sysclk: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * Refpclk needs to be on, on at least the rk3328 for still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * unknown reasons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ret = clk_prepare_enable(inno->refpclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) dev_err(inno->dev, "failed to enable refpclk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) clk_disable_unprepare(inno->sysclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) ret = devm_add_action_or_reset(inno->dev, inno_hdmi_phy_action,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) inno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) inno->regmap = devm_regmap_init_mmio(inno->dev, regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) &inno_hdmi_phy_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (IS_ERR(inno->regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return PTR_ERR(inno->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) /* only the newer rk3328 hdmiphy has an interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) inno->irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (inno->irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) ret = devm_request_threaded_irq(inno->dev, inno->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) inno_hdmi_phy_rk3328_hardirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) inno_hdmi_phy_rk3328_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) dev_name(inno->dev), inno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) inno->phy = devm_phy_create(inno->dev, NULL, &inno_hdmi_phy_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (IS_ERR(inno->phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) dev_err(inno->dev, "failed to create HDMI PHY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return PTR_ERR(inno->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) phy_set_drvdata(inno->phy, inno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) phy_set_bus_width(inno->phy, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (inno->plat_data->ops->init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) ret = inno->plat_data->ops->init(inno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ret = inno_hdmi_phy_clk_register(inno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) phy_provider = devm_of_phy_provider_register(inno->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) of_phy_simple_xlate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) return PTR_ERR_OR_ZERO(phy_provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) static int inno_hdmi_phy_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) of_clk_del_provider(pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) static const struct of_device_id inno_hdmi_phy_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) .compatible = "rockchip,rk3228-hdmi-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) .data = &rk3228_hdmi_phy_drv_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) .compatible = "rockchip,rk3328-hdmi-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) .data = &rk3328_hdmi_phy_drv_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }, { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) MODULE_DEVICE_TABLE(of, inno_hdmi_phy_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) static struct platform_driver inno_hdmi_phy_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) .probe = inno_hdmi_phy_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) .remove = inno_hdmi_phy_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) .name = "inno-hdmi-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) .of_match_table = inno_hdmi_phy_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) module_platform_driver(inno_hdmi_phy_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) MODULE_AUTHOR("Zheng Yang <zhengyang@rock-chips.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) MODULE_DESCRIPTION("Innosilion HDMI 2.0 Transmitter PHY Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) MODULE_LICENSE("GPL v2");