1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015 MediaTek Inc.
6 #include "phy-mtk-mipi-dsi.h"
8 inline struct mtk_mipi_tx
*mtk_mipi_tx_from_clk_hw(struct clk_hw
*hw
)
10 return container_of(hw
, struct mtk_mipi_tx
, pll_hw
);
13 void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx
*mipi_tx
, u32 offset
,
16 u32 temp
= readl(mipi_tx
->regs
+ offset
);
18 writel(temp
& ~bits
, mipi_tx
->regs
+ offset
);
21 void mtk_mipi_tx_set_bits(struct mtk_mipi_tx
*mipi_tx
, u32 offset
,
24 u32 temp
= readl(mipi_tx
->regs
+ offset
);
26 writel(temp
| bits
, mipi_tx
->regs
+ offset
);
29 void mtk_mipi_tx_update_bits(struct mtk_mipi_tx
*mipi_tx
, u32 offset
,
32 u32 temp
= readl(mipi_tx
->regs
+ offset
);
34 writel((temp
& ~mask
) | (data
& mask
), mipi_tx
->regs
+ offset
);
37 int mtk_mipi_tx_pll_set_rate(struct clk_hw
*hw
, unsigned long rate
,
38 unsigned long parent_rate
)
40 struct mtk_mipi_tx
*mipi_tx
= mtk_mipi_tx_from_clk_hw(hw
);
42 dev_dbg(mipi_tx
->dev
, "set rate: %lu Hz\n", rate
);
44 mipi_tx
->data_rate
= rate
;
49 unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw
*hw
,
50 unsigned long parent_rate
)
52 struct mtk_mipi_tx
*mipi_tx
= mtk_mipi_tx_from_clk_hw(hw
);
54 return mipi_tx
->data_rate
;
57 static int mtk_mipi_tx_power_on(struct phy
*phy
)
59 struct mtk_mipi_tx
*mipi_tx
= phy_get_drvdata(phy
);
62 /* Power up core and enable PLL */
63 ret
= clk_prepare_enable(mipi_tx
->pll
);
67 /* Enable DSI Lane LDO outputs, disable pad tie low */
68 mipi_tx
->driver_data
->mipi_tx_enable_signal(phy
);
72 static int mtk_mipi_tx_power_off(struct phy
*phy
)
74 struct mtk_mipi_tx
*mipi_tx
= phy_get_drvdata(phy
);
76 /* Enable pad tie low, disable DSI Lane LDO outputs */
77 mipi_tx
->driver_data
->mipi_tx_disable_signal(phy
);
79 /* Disable PLL and power down core */
80 clk_disable_unprepare(mipi_tx
->pll
);
85 static const struct phy_ops mtk_mipi_tx_ops
= {
86 .power_on
= mtk_mipi_tx_power_on
,
87 .power_off
= mtk_mipi_tx_power_off
,
91 static void mtk_mipi_tx_get_calibration_datal(struct mtk_mipi_tx
*mipi_tx
)
93 struct nvmem_cell
*cell
;
97 cell
= nvmem_cell_get(mipi_tx
->dev
, "calibration-data");
99 dev_info(mipi_tx
->dev
, "can't get nvmem_cell_get, ignore it\n");
102 buf
= (u32
*)nvmem_cell_read(cell
, &len
);
103 nvmem_cell_put(cell
);
106 dev_info(mipi_tx
->dev
, "can't get data, ignore it\n");
110 if (len
< 3 * sizeof(u32
)) {
111 dev_info(mipi_tx
->dev
, "invalid calibration data\n");
116 mipi_tx
->rt_code
[0] = ((buf
[0] >> 6 & 0x1f) << 5) |
117 (buf
[0] >> 11 & 0x1f);
118 mipi_tx
->rt_code
[1] = ((buf
[1] >> 27 & 0x1f) << 5) |
119 (buf
[0] >> 1 & 0x1f);
120 mipi_tx
->rt_code
[2] = ((buf
[1] >> 17 & 0x1f) << 5) |
121 (buf
[1] >> 22 & 0x1f);
122 mipi_tx
->rt_code
[3] = ((buf
[1] >> 7 & 0x1f) << 5) |
123 (buf
[1] >> 12 & 0x1f);
124 mipi_tx
->rt_code
[4] = ((buf
[2] >> 27 & 0x1f) << 5) |
125 (buf
[1] >> 2 & 0x1f);
129 static int mtk_mipi_tx_probe(struct platform_device
*pdev
)
131 struct device
*dev
= &pdev
->dev
;
132 struct mtk_mipi_tx
*mipi_tx
;
133 struct resource
*mem
;
134 const char *ref_clk_name
;
136 struct clk_init_data clk_init
= {
138 .parent_names
= (const char * const *)&ref_clk_name
,
139 .flags
= CLK_SET_RATE_GATE
,
142 struct phy_provider
*phy_provider
;
145 mipi_tx
= devm_kzalloc(dev
, sizeof(*mipi_tx
), GFP_KERNEL
);
149 mipi_tx
->driver_data
= of_device_get_match_data(dev
);
151 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
152 mipi_tx
->regs
= devm_ioremap_resource(dev
, mem
);
153 if (IS_ERR(mipi_tx
->regs
)) {
154 ret
= PTR_ERR(mipi_tx
->regs
);
155 dev_err(dev
, "Failed to get memory resource: %d\n", ret
);
159 ref_clk
= devm_clk_get(dev
, NULL
);
160 if (IS_ERR(ref_clk
)) {
161 ret
= PTR_ERR(ref_clk
);
162 dev_err(dev
, "Failed to get reference clock: %d\n", ret
);
166 ret
= of_property_read_u32(dev
->of_node
, "drive-strength-microamp",
167 &mipi_tx
->mipitx_drive
);
168 /* If can't get the "mipi_tx->mipitx_drive", set it default 0x8 */
170 mipi_tx
->mipitx_drive
= 4600;
172 /* check the mipitx_drive valid */
173 if (mipi_tx
->mipitx_drive
> 6000 || mipi_tx
->mipitx_drive
< 3000) {
174 dev_warn(dev
, "drive-strength-microamp is invalid %d, not in 3000 ~ 6000\n",
175 mipi_tx
->mipitx_drive
);
176 mipi_tx
->mipitx_drive
= clamp_val(mipi_tx
->mipitx_drive
, 3000,
180 ref_clk_name
= __clk_get_name(ref_clk
);
182 ret
= of_property_read_string(dev
->of_node
, "clock-output-names",
185 dev_err(dev
, "Failed to read clock-output-names: %d\n", ret
);
189 clk_init
.ops
= mipi_tx
->driver_data
->mipi_tx_clk_ops
;
191 mipi_tx
->pll_hw
.init
= &clk_init
;
192 mipi_tx
->pll
= devm_clk_register(dev
, &mipi_tx
->pll_hw
);
193 if (IS_ERR(mipi_tx
->pll
)) {
194 ret
= PTR_ERR(mipi_tx
->pll
);
195 dev_err(dev
, "Failed to register PLL: %d\n", ret
);
199 phy
= devm_phy_create(dev
, NULL
, &mtk_mipi_tx_ops
);
202 dev_err(dev
, "Failed to create MIPI D-PHY: %d\n", ret
);
205 phy_set_drvdata(phy
, mipi_tx
);
207 phy_provider
= devm_of_phy_provider_register(dev
, of_phy_simple_xlate
);
208 if (IS_ERR(phy_provider
)) {
209 ret
= PTR_ERR(phy_provider
);
215 mtk_mipi_tx_get_calibration_datal(mipi_tx
);
217 return of_clk_add_provider(dev
->of_node
, of_clk_src_simple_get
,
221 static int mtk_mipi_tx_remove(struct platform_device
*pdev
)
223 of_clk_del_provider(pdev
->dev
.of_node
);
227 static const struct of_device_id mtk_mipi_tx_match
[] = {
228 { .compatible
= "mediatek,mt2701-mipi-tx",
229 .data
= &mt2701_mipitx_data
},
230 { .compatible
= "mediatek,mt8173-mipi-tx",
231 .data
= &mt8173_mipitx_data
},
232 { .compatible
= "mediatek,mt8183-mipi-tx",
233 .data
= &mt8183_mipitx_data
},
237 struct platform_driver mtk_mipi_tx_driver
= {
238 .probe
= mtk_mipi_tx_probe
,
239 .remove
= mtk_mipi_tx_remove
,
241 .name
= "mediatek-mipi-tx",
242 .of_match_table
= mtk_mipi_tx_match
,
245 module_platform_driver(mtk_mipi_tx_driver
);
247 MODULE_DESCRIPTION("MediaTek MIPI TX Driver");
248 MODULE_LICENSE("GPL v2");