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 int mtk_mipi_tx_pll_set_rate(struct clk_hw
*hw
, unsigned long rate
,
14 unsigned long parent_rate
)
16 struct mtk_mipi_tx
*mipi_tx
= mtk_mipi_tx_from_clk_hw(hw
);
18 dev_dbg(mipi_tx
->dev
, "set rate: %lu Hz\n", rate
);
20 mipi_tx
->data_rate
= rate
;
25 unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw
*hw
,
26 unsigned long parent_rate
)
28 struct mtk_mipi_tx
*mipi_tx
= mtk_mipi_tx_from_clk_hw(hw
);
30 return mipi_tx
->data_rate
;
33 static int mtk_mipi_tx_power_on(struct phy
*phy
)
35 struct mtk_mipi_tx
*mipi_tx
= phy_get_drvdata(phy
);
38 /* Power up core and enable PLL */
39 ret
= clk_prepare_enable(mipi_tx
->pll_hw
.clk
);
43 /* Enable DSI Lane LDO outputs, disable pad tie low */
44 mipi_tx
->driver_data
->mipi_tx_enable_signal(phy
);
48 static int mtk_mipi_tx_power_off(struct phy
*phy
)
50 struct mtk_mipi_tx
*mipi_tx
= phy_get_drvdata(phy
);
52 /* Enable pad tie low, disable DSI Lane LDO outputs */
53 mipi_tx
->driver_data
->mipi_tx_disable_signal(phy
);
55 /* Disable PLL and power down core */
56 clk_disable_unprepare(mipi_tx
->pll_hw
.clk
);
61 static const struct phy_ops mtk_mipi_tx_ops
= {
62 .power_on
= mtk_mipi_tx_power_on
,
63 .power_off
= mtk_mipi_tx_power_off
,
67 static void mtk_mipi_tx_get_calibration_datal(struct mtk_mipi_tx
*mipi_tx
)
69 struct nvmem_cell
*cell
;
73 cell
= nvmem_cell_get(mipi_tx
->dev
, "calibration-data");
75 dev_info(mipi_tx
->dev
, "can't get nvmem_cell_get, ignore it\n");
78 buf
= (u32
*)nvmem_cell_read(cell
, &len
);
82 dev_info(mipi_tx
->dev
, "can't get data, ignore it\n");
86 if (len
< 3 * sizeof(u32
)) {
87 dev_info(mipi_tx
->dev
, "invalid calibration data\n");
92 mipi_tx
->rt_code
[0] = ((buf
[0] >> 6 & 0x1f) << 5) |
93 (buf
[0] >> 11 & 0x1f);
94 mipi_tx
->rt_code
[1] = ((buf
[1] >> 27 & 0x1f) << 5) |
96 mipi_tx
->rt_code
[2] = ((buf
[1] >> 17 & 0x1f) << 5) |
97 (buf
[1] >> 22 & 0x1f);
98 mipi_tx
->rt_code
[3] = ((buf
[1] >> 7 & 0x1f) << 5) |
99 (buf
[1] >> 12 & 0x1f);
100 mipi_tx
->rt_code
[4] = ((buf
[2] >> 27 & 0x1f) << 5) |
101 (buf
[1] >> 2 & 0x1f);
105 static int mtk_mipi_tx_probe(struct platform_device
*pdev
)
107 struct device
*dev
= &pdev
->dev
;
108 struct mtk_mipi_tx
*mipi_tx
;
109 const char *ref_clk_name
;
111 struct clk_init_data clk_init
= {
113 .parent_names
= (const char * const *)&ref_clk_name
,
114 .flags
= CLK_SET_RATE_GATE
,
117 struct phy_provider
*phy_provider
;
120 mipi_tx
= devm_kzalloc(dev
, sizeof(*mipi_tx
), GFP_KERNEL
);
124 mipi_tx
->driver_data
= of_device_get_match_data(dev
);
125 if (!mipi_tx
->driver_data
)
128 mipi_tx
->regs
= devm_platform_ioremap_resource(pdev
, 0);
129 if (IS_ERR(mipi_tx
->regs
))
130 return PTR_ERR(mipi_tx
->regs
);
132 ref_clk
= devm_clk_get(dev
, NULL
);
134 return dev_err_probe(dev
, PTR_ERR(ref_clk
),
135 "Failed to get reference clock\n");
137 ret
= of_property_read_u32(dev
->of_node
, "drive-strength-microamp",
138 &mipi_tx
->mipitx_drive
);
139 /* If can't get the "mipi_tx->mipitx_drive", set it default 0x8 */
141 mipi_tx
->mipitx_drive
= 4600;
143 /* check the mipitx_drive valid */
144 if (mipi_tx
->mipitx_drive
> 6000 || mipi_tx
->mipitx_drive
< 3000) {
145 dev_warn(dev
, "drive-strength-microamp is invalid %d, not in 3000 ~ 6000\n",
146 mipi_tx
->mipitx_drive
);
147 mipi_tx
->mipitx_drive
= clamp_val(mipi_tx
->mipitx_drive
, 3000,
151 ref_clk_name
= __clk_get_name(ref_clk
);
153 ret
= of_property_read_string(dev
->of_node
, "clock-output-names",
156 return dev_err_probe(dev
, ret
, "Failed to read clock-output-names\n");
158 clk_init
.ops
= mipi_tx
->driver_data
->mipi_tx_clk_ops
;
160 mipi_tx
->pll_hw
.init
= &clk_init
;
161 ret
= devm_clk_hw_register(dev
, &mipi_tx
->pll_hw
);
163 return dev_err_probe(dev
, ret
, "Failed to register PLL\n");
165 phy
= devm_phy_create(dev
, NULL
, &mtk_mipi_tx_ops
);
167 return dev_err_probe(dev
, PTR_ERR(phy
), "Failed to create MIPI D-PHY\n");
169 phy_set_drvdata(phy
, mipi_tx
);
171 phy_provider
= devm_of_phy_provider_register(dev
, of_phy_simple_xlate
);
172 if (IS_ERR(phy_provider
))
173 return PTR_ERR(phy_provider
);
177 mtk_mipi_tx_get_calibration_datal(mipi_tx
);
179 return devm_of_clk_add_hw_provider(dev
, of_clk_hw_simple_get
, &mipi_tx
->pll_hw
);
182 static const struct of_device_id mtk_mipi_tx_match
[] = {
183 { .compatible
= "mediatek,mt2701-mipi-tx", .data
= &mt2701_mipitx_data
},
184 { .compatible
= "mediatek,mt8173-mipi-tx", .data
= &mt8173_mipitx_data
},
185 { .compatible
= "mediatek,mt8183-mipi-tx", .data
= &mt8183_mipitx_data
},
188 MODULE_DEVICE_TABLE(of
, mtk_mipi_tx_match
);
190 static struct platform_driver mtk_mipi_tx_driver
= {
191 .probe
= mtk_mipi_tx_probe
,
193 .name
= "mediatek-mipi-tx",
194 .of_match_table
= mtk_mipi_tx_match
,
197 module_platform_driver(mtk_mipi_tx_driver
);
199 MODULE_DESCRIPTION("MediaTek MIPI TX Driver");
200 MODULE_LICENSE("GPL v2");