Skip to content

Commit 5f0ed4f

Browse files
committed
Merge tag 'mediatek-drm-next-5.8' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux into drm-next
Mediatek DRM Next for Linux 5.8 This include dpi pin mode swap, config mipi_tx current and impedance, and some fixup. Signed-off-by: Dave Airlie <[email protected]> From: Chun-Kuang Hu <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents c41219f + 3852489 commit 5f0ed4f

File tree

8 files changed

+143
-11
lines changed

8 files changed

+143
-11
lines changed

Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ Required properties:
1717
Documentation/devicetree/bindings/graph.txt. This port should be connected
1818
to the input port of an attached HDMI or LVDS encoder chip.
1919

20+
Optional properties:
21+
- pinctrl-names: Contain "default" and "sleep".
22+
2023
Example:
2124

2225
dpi0: dpi@1401d000 {
@@ -27,6 +30,9 @@ dpi0: dpi@1401d000 {
2730
<&mmsys CLK_MM_DPI_ENGINE>,
2831
<&apmixedsys CLK_APMIXED_TVDPLL>;
2932
clock-names = "pixel", "engine", "pll";
33+
pinctrl-names = "default", "sleep";
34+
pinctrl-0 = <&dpi_pin_func>;
35+
pinctrl-1 = <&dpi_pin_idle>;
3036

3137
port {
3238
dpi0_out: endpoint {

Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ Required properties:
3333
- #clock-cells: must be <0>;
3434
- #phy-cells: must be <0>.
3535

36+
Optional properties:
37+
- drive-strength-microamp: adjust driving current, should be 3000 ~ 6000. And
38+
the step is 200.
39+
- nvmem-cells: A phandle to the calibration data provided by a nvmem device. If
40+
unspecified default values shall be used.
41+
- nvmem-cell-names: Should be "calibration-data"
42+
3643
Example:
3744

3845
mipi_tx0: mipi-dphy@10215000 {
@@ -42,6 +49,9 @@ mipi_tx0: mipi-dphy@10215000 {
4249
clock-output-names = "mipi_tx0_pll";
4350
#clock-cells = <0>;
4451
#phy-cells = <0>;
52+
drive-strength-microamp = <4600>;
53+
nvmem-cells= <&mipi_tx_calibration>;
54+
nvmem-cell-names = "calibration-data";
4555
};
4656

4757
dsi0: dsi@1401b000 {

drivers/gpu/drm/mediatek/mtk_dpi.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
#include <linux/kernel.h>
1111
#include <linux/of.h>
1212
#include <linux/of_device.h>
13+
#include <linux/of_gpio.h>
1314
#include <linux/of_graph.h>
15+
#include <linux/pinctrl/consumer.h>
1416
#include <linux/platform_device.h>
1517
#include <linux/types.h>
1618

@@ -75,6 +77,9 @@ struct mtk_dpi {
7577
enum mtk_dpi_out_yc_map yc_map;
7678
enum mtk_dpi_out_bit_num bit_num;
7779
enum mtk_dpi_out_channel_swap channel_swap;
80+
struct pinctrl *pinctrl;
81+
struct pinctrl_state *pins_gpio;
82+
struct pinctrl_state *pins_dpi;
7883
int refcount;
7984
};
8085

@@ -380,6 +385,9 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
380385
if (--dpi->refcount != 0)
381386
return;
382387

388+
if (dpi->pinctrl && dpi->pins_gpio)
389+
pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
390+
383391
mtk_dpi_disable(dpi);
384392
clk_disable_unprepare(dpi->pixel_clk);
385393
clk_disable_unprepare(dpi->engine_clk);
@@ -404,6 +412,9 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
404412
goto err_pixel;
405413
}
406414

415+
if (dpi->pinctrl && dpi->pins_dpi)
416+
pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
417+
407418
mtk_dpi_enable(dpi);
408419
return 0;
409420

@@ -697,6 +708,26 @@ static int mtk_dpi_probe(struct platform_device *pdev)
697708
dpi->dev = dev;
698709
dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev);
699710

711+
dpi->pinctrl = devm_pinctrl_get(&pdev->dev);
712+
if (IS_ERR(dpi->pinctrl)) {
713+
dpi->pinctrl = NULL;
714+
dev_dbg(&pdev->dev, "Cannot find pinctrl!\n");
715+
}
716+
if (dpi->pinctrl) {
717+
dpi->pins_gpio = pinctrl_lookup_state(dpi->pinctrl, "sleep");
718+
if (IS_ERR(dpi->pins_gpio)) {
719+
dpi->pins_gpio = NULL;
720+
dev_dbg(&pdev->dev, "Cannot find pinctrl idle!\n");
721+
}
722+
if (dpi->pins_gpio)
723+
pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
724+
725+
dpi->pins_dpi = pinctrl_lookup_state(dpi->pinctrl, "default");
726+
if (IS_ERR(dpi->pins_dpi)) {
727+
dpi->pins_dpi = NULL;
728+
dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n");
729+
}
730+
}
700731
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
701732
dpi->regs = devm_ioremap_resource(dev, mem);
702733
if (IS_ERR(dpi->regs)) {

drivers/gpu/drm/mediatek/mtk_drm_gem.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@ struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
224224

225225
expected = sg_dma_address(sg->sgl);
226226
for_each_sg(sg->sgl, s, sg->nents, i) {
227+
if (!sg_dma_len(s))
228+
break;
229+
227230
if (sg_dma_address(s) != expected) {
228231
DRM_ERROR("sg_table is not contiguous");
229232
ret = -EINVAL;

drivers/gpu/drm/mediatek/mtk_hdmi.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -311,14 +311,10 @@ static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer,
311311
u8 checksum;
312312
int ctrl_frame_en = 0;
313313

314-
frame_type = *buffer;
315-
buffer += 1;
316-
frame_ver = *buffer;
317-
buffer += 1;
318-
frame_len = *buffer;
319-
buffer += 1;
320-
checksum = *buffer;
321-
buffer += 1;
314+
frame_type = *buffer++;
315+
frame_ver = *buffer++;
316+
frame_len = *buffer++;
317+
checksum = *buffer++;
322318
frame_data = buffer;
323319

324320
dev_dbg(hdmi->dev,
@@ -982,7 +978,7 @@ static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi,
982978
struct drm_display_mode *mode)
983979
{
984980
struct hdmi_avi_infoframe frame;
985-
u8 buffer[17];
981+
u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
986982
ssize_t err;
987983

988984
err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
@@ -1008,7 +1004,7 @@ static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi,
10081004
const char *product)
10091005
{
10101006
struct hdmi_spd_infoframe frame;
1011-
u8 buffer[29];
1007+
u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_SPD_INFOFRAME_SIZE];
10121008
ssize_t err;
10131009

10141010
err = hdmi_spd_infoframe_init(&frame, vendor, product);
@@ -1031,7 +1027,7 @@ static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi,
10311027
static int mtk_hdmi_setup_audio_infoframe(struct mtk_hdmi *hdmi)
10321028
{
10331029
struct hdmi_audio_infoframe frame;
1034-
u8 buffer[14];
1030+
u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
10351031
ssize_t err;
10361032

10371033
err = hdmi_audio_infoframe_init(&frame);

drivers/gpu/drm/mediatek/mtk_mipi_tx.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,44 @@ static const struct phy_ops mtk_mipi_tx_ops = {
8888
.owner = THIS_MODULE,
8989
};
9090

91+
static void mtk_mipi_tx_get_calibration_datal(struct mtk_mipi_tx *mipi_tx)
92+
{
93+
struct nvmem_cell *cell;
94+
size_t len;
95+
u32 *buf;
96+
97+
cell = nvmem_cell_get(mipi_tx->dev, "calibration-data");
98+
if (IS_ERR(cell)) {
99+
dev_info(mipi_tx->dev, "can't get nvmem_cell_get, ignore it\n");
100+
return;
101+
}
102+
buf = (u32 *)nvmem_cell_read(cell, &len);
103+
nvmem_cell_put(cell);
104+
105+
if (IS_ERR(buf)) {
106+
dev_info(mipi_tx->dev, "can't get data, ignore it\n");
107+
return;
108+
}
109+
110+
if (len < 3 * sizeof(u32)) {
111+
dev_info(mipi_tx->dev, "invalid calibration data\n");
112+
kfree(buf);
113+
return;
114+
}
115+
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);
126+
kfree(buf);
127+
}
128+
91129
static int mtk_mipi_tx_probe(struct platform_device *pdev)
92130
{
93131
struct device *dev = &pdev->dev;
@@ -125,6 +163,20 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
125163
return ret;
126164
}
127165

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 */
169+
if (ret < 0)
170+
mipi_tx->mipitx_drive = 4600;
171+
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,
177+
6000);
178+
}
179+
128180
ref_clk_name = __clk_get_name(ref_clk);
129181

130182
ret = of_property_read_string(dev->of_node, "clock-output-names",
@@ -160,6 +212,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
160212

161213
mipi_tx->dev = dev;
162214

215+
mtk_mipi_tx_get_calibration_datal(mipi_tx);
216+
163217
return of_clk_add_provider(dev->of_node, of_clk_src_simple_get,
164218
mipi_tx->pll);
165219
}

drivers/gpu/drm/mediatek/mtk_mipi_tx.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
#include <linux/delay.h>
1313
#include <linux/io.h>
1414
#include <linux/module.h>
15+
#include <linux/nvmem-consumer.h>
1516
#include <linux/of_device.h>
1617
#include <linux/platform_device.h>
1718
#include <linux/phy/phy.h>
19+
#include <linux/slab.h>
1820

1921
struct mtk_mipitx_data {
2022
const u32 mppll_preserve;
@@ -27,6 +29,8 @@ struct mtk_mipi_tx {
2729
struct device *dev;
2830
void __iomem *regs;
2931
u32 data_rate;
32+
u32 mipitx_drive;
33+
u32 rt_code[5];
3034
const struct mtk_mipitx_data *driver_data;
3135
struct clk_hw pll_hw;
3236
struct clk *pll;

drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#define RG_DSI_BG_CORE_EN BIT(7)
1818
#define RG_DSI_PAD_TIEL_SEL BIT(8)
1919

20+
#define MIPITX_VOLTAGE_SEL 0x0010
21+
#define RG_DSI_HSTX_LDO_REF_SEL (0xf << 6)
22+
2023
#define MIPITX_PLL_PWR 0x0028
2124
#define MIPITX_PLL_CON0 0x002c
2225
#define MIPITX_PLL_CON1 0x0030
@@ -25,6 +28,7 @@
2528
#define MIPITX_PLL_CON4 0x003c
2629
#define RG_DSI_PLL_IBIAS (3 << 10)
2730

31+
#define MIPITX_D2P_RTCODE 0x0100
2832
#define MIPITX_D2_SW_CTL_EN 0x0144
2933
#define MIPITX_D0_SW_CTL_EN 0x0244
3034
#define MIPITX_CK_CKMODE_EN 0x0328
@@ -105,6 +109,24 @@ static const struct clk_ops mtk_mipi_tx_pll_ops = {
105109
.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
106110
};
107111

112+
static void mtk_mipi_tx_config_calibration_data(struct mtk_mipi_tx *mipi_tx)
113+
{
114+
int i, j;
115+
116+
for (i = 0; i < 5; i++) {
117+
if ((mipi_tx->rt_code[i] & 0x1f) == 0)
118+
mipi_tx->rt_code[i] |= 0x10;
119+
120+
if ((mipi_tx->rt_code[i] >> 5 & 0x1f) == 0)
121+
mipi_tx->rt_code[i] |= 0x10 << 5;
122+
123+
for (j = 0; j < 10; j++)
124+
mtk_mipi_tx_update_bits(mipi_tx,
125+
MIPITX_D2P_RTCODE * (i + 1) + j * 4,
126+
1, mipi_tx->rt_code[i] >> j & 1);
127+
}
128+
}
129+
108130
static void mtk_mipi_tx_power_on_signal(struct phy *phy)
109131
{
110132
struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
@@ -123,6 +145,12 @@ static void mtk_mipi_tx_power_on_signal(struct phy *phy)
123145
mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
124146
mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
125147

148+
mtk_mipi_tx_update_bits(mipi_tx, MIPITX_VOLTAGE_SEL,
149+
RG_DSI_HSTX_LDO_REF_SEL,
150+
(mipi_tx->mipitx_drive - 3000) / 200 << 6);
151+
152+
mtk_mipi_tx_config_calibration_data(mipi_tx);
153+
126154
mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN);
127155
}
128156

0 commit comments

Comments
 (0)