File Index
Files and directories
Sign in
FILE

dw-mipi-dsi2-rockchip.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Copyright (C) 2024 Rockchip Electronics Co., Ltd.
  4 * Author:
  5 *      Guochun Huang <hero.huang@rock-chips.com>
  6 *      Heiko Stuebner <heiko.stuebner@cherry.de>
  7 */
  8
  9#include <linux/bitfield.h>
 10#include <linux/clk.h>
 11#include <linux/component.h>
 12#include <linux/media-bus-format.h>
 13#include <linux/mod_devicetable.h>
 14#include <linux/module.h>
 15#include <linux/of.h>
 16#include <linux/pm_runtime.h>
 17#include <linux/platform_device.h>
 18#include <linux/regmap.h>
 19#include <linux/reset.h>
 20#include <linux/mfd/syscon.h>
 21#include <linux/phy/phy.h>
 22
 23#include <drm/bridge/dw_mipi_dsi2.h>
 24#include <drm/drm_mipi_dsi.h>
 25#include <drm/drm_of.h>
 26#include <drm/drm_simple_kms_helper.h>
 27
 28#include <uapi/linux/videodev2.h>
 29
 30#include "rockchip_drm_drv.h"
 31
 32#define PSEC_PER_SEC			1000000000000LL
 33
 34struct dsigrf_reg {
 35	u16 offset;
 36	u16 lsb;
 37	u16 msb;
 38};
 39
 40enum grf_reg_fields {
 41	TXREQCLKHS_EN,
 42	GATING_EN,
 43	IPI_SHUTDN,
 44	IPI_COLORM,
 45	IPI_COLOR_DEPTH,
 46	IPI_FORMAT,
 47	MAX_FIELDS,
 48};
 49
 50#define IPI_DEPTH_5_6_5_BITS		0x02
 51#define IPI_DEPTH_6_BITS		0x03
 52#define IPI_DEPTH_8_BITS		0x05
 53#define IPI_DEPTH_10_BITS		0x06
 54
 55struct rockchip_dw_dsi2_chip_data {
 56	u32 reg;
 57	const struct dsigrf_reg *grf_regs;
 58	unsigned long long max_bit_rate_per_lane;
 59};
 60
 61struct dw_mipi_dsi2_rockchip {
 62	struct device *dev;
 63	struct rockchip_encoder encoder;
 64	struct regmap *regmap;
 65
 66	unsigned int lane_mbps; /* per lane */
 67	u32 format;
 68
 69	struct regmap *grf_regmap;
 70	struct phy *phy;
 71	union phy_configure_opts phy_opts;
 72
 73	struct dw_mipi_dsi2 *dmd;
 74	struct dw_mipi_dsi2_plat_data pdata;
 75	const struct rockchip_dw_dsi2_chip_data *cdata;
 76};
 77
 78static inline struct dw_mipi_dsi2_rockchip *to_dsi2(struct drm_encoder *encoder)
 79{
 80	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
 81
 82	return container_of(rkencoder, struct dw_mipi_dsi2_rockchip, encoder);
 83}
 84
 85static void grf_field_write(struct dw_mipi_dsi2_rockchip *dsi2, enum grf_reg_fields index,
 86			    unsigned int val)
 87{
 88	const struct dsigrf_reg *field = &dsi2->cdata->grf_regs[index];
 89
 90	if (!field)
 91		return;
 92
 93	regmap_write(dsi2->grf_regmap, field->offset,
 94		     (val << field->lsb) | (GENMASK(field->msb, field->lsb) << 16));
 95}
 96
 97static int dw_mipi_dsi2_phy_init(void *priv_data)
 98{
 99	return 0;
100}
101
102static void dw_mipi_dsi2_phy_power_on(void *priv_data)
103{
104	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
105	int ret;
106
107	ret = phy_set_mode(dsi2->phy, PHY_MODE_MIPI_DPHY);
108	if (ret) {
109		dev_err(dsi2->dev, "Failed to set phy mode: %d\n", ret);
110		return;
111	}
112
113	phy_configure(dsi2->phy, &dsi2->phy_opts);
114	phy_power_on(dsi2->phy);
115}
116
117static void dw_mipi_dsi2_phy_power_off(void *priv_data)
118{
119	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
120
121	phy_power_off(dsi2->phy);
122}
123
124static int
125dw_mipi_dsi2_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
126			   unsigned long mode_flags, u32 lanes, u32 format,
127			   unsigned int *lane_mbps)
128{
129	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
130	u64 max_lane_rate, target_phyclk;
131	unsigned int lane_rate_kbps;
132	int bpp;
133
134	max_lane_rate = dsi2->cdata->max_bit_rate_per_lane;
135
136	dsi2->format = format;
137	bpp = mipi_dsi_pixel_format_to_bpp(format);
138	if (bpp < 0) {
139		dev_err(dsi2->dev, "failed to get bpp for pixel format %d\n", format);
140		return bpp;
141	}
142
143	lane_rate_kbps = mode->clock * bpp / lanes;
144
145	/*
146	 * Set BW a little larger only in video burst mode in
147	 * consideration of the protocol overhead and HS mode
148	 * switching to BLLP mode, take 1 / 0.9, since Mbps must
149	 * big than bandwidth of RGB
150	 */
151	if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
152		lane_rate_kbps = (lane_rate_kbps * 10) / 9;
153
154	if (lane_rate_kbps > max_lane_rate) {
155		dev_err(dsi2->dev, "DPHY clock frequency is out of range\n");
156		return -ERANGE;
157	}
158
159	dsi2->lane_mbps = lane_rate_kbps / 1000;
160	*lane_mbps = dsi2->lane_mbps;
161
162	if (dsi2->phy) {
163		target_phyclk = DIV_ROUND_CLOSEST_ULL(lane_rate_kbps * lanes * 1000, bpp);
164		phy_mipi_dphy_get_default_config(target_phyclk, bpp, lanes,
165						 &dsi2->phy_opts.mipi_dphy);
166	}
167
168	return 0;
169}
170
171static void dw_mipi_dsi2_phy_get_iface(void *priv_data, struct dw_mipi_dsi2_phy_iface *iface)
172{
173	/* PPI width is fixed to 16 bits in DCPHY */
174	iface->ppi_width = 16;
175	iface->phy_type = DW_MIPI_DSI2_DPHY;
176}
177
178static int
179dw_mipi_dsi2_phy_get_timing(void *priv_data, unsigned int lane_mbps,
180			    struct dw_mipi_dsi2_phy_timing *timing)
181{
182	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
183	struct phy_configure_opts_mipi_dphy *cfg = &dsi2->phy_opts.mipi_dphy;
184	unsigned long long tmp, ui;
185	unsigned long long hstx_clk;
186
187	hstx_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
188
189	ui = ALIGN(PSEC_PER_SEC, hstx_clk);
190	do_div(ui, hstx_clk);
191
192	/* PHY_LP2HS_TIME = (TLPX + THS-PREPARE + THS-ZERO) / Tphy_hstx_clk */
193	tmp = cfg->lpx + cfg->hs_prepare + cfg->hs_zero;
194	tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui);
195	timing->data_lp2hs = tmp;
196
197	/* PHY_HS2LP_TIME = (THS-TRAIL + THS-EXIT) / Tphy_hstx_clk */
198	tmp = cfg->hs_trail + cfg->hs_exit;
199	tmp = DIV_ROUND_CLOSEST_ULL(tmp << 16, ui);
200	timing->data_hs2lp = tmp;
201
202	return 0;
203}
204
205static const struct dw_mipi_dsi2_phy_ops dw_mipi_dsi2_rockchip_phy_ops = {
206	.init = dw_mipi_dsi2_phy_init,
207	.power_on = dw_mipi_dsi2_phy_power_on,
208	.power_off = dw_mipi_dsi2_phy_power_off,
209	.get_interface = dw_mipi_dsi2_phy_get_iface,
210	.get_lane_mbps = dw_mipi_dsi2_get_lane_mbps,
211	.get_timing = dw_mipi_dsi2_phy_get_timing,
212};
213
214static void dw_mipi_dsi2_encoder_atomic_enable(struct drm_encoder *encoder,
215					       struct drm_atomic_state *state)
216{
217	struct dw_mipi_dsi2_rockchip *dsi2 = to_dsi2(encoder);
218	u32 color_depth;
219
220	switch (dsi2->format) {
221	case MIPI_DSI_FMT_RGB666:
222	case MIPI_DSI_FMT_RGB666_PACKED:
223		color_depth = IPI_DEPTH_6_BITS;
224		break;
225	case MIPI_DSI_FMT_RGB565:
226		color_depth = IPI_DEPTH_5_6_5_BITS;
227		break;
228	case MIPI_DSI_FMT_RGB888:
229		color_depth = IPI_DEPTH_8_BITS;
230		break;
231	default:
232		/* Should've been caught by atomic_check */
233		WARN_ON(1);
234		return;
235	}
236
237	grf_field_write(dsi2, IPI_COLOR_DEPTH, color_depth);
238}
239
240static int
241dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder,
242				  struct drm_crtc_state *crtc_state,
243				  struct drm_connector_state *conn_state)
244{
245	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
246	struct dw_mipi_dsi2_rockchip *dsi2 = to_dsi2(encoder);
247	struct drm_connector *connector = conn_state->connector;
248	struct drm_display_info *info = &connector->display_info;
249
250	switch (dsi2->format) {
251	case MIPI_DSI_FMT_RGB666:
252	case MIPI_DSI_FMT_RGB666_PACKED:
253		s->output_mode = ROCKCHIP_OUT_MODE_P666;
254		break;
255	case MIPI_DSI_FMT_RGB565:
256		s->output_mode = ROCKCHIP_OUT_MODE_P565;
257		break;
258	case MIPI_DSI_FMT_RGB888:
259		s->output_mode = ROCKCHIP_OUT_MODE_P888;
260		break;
261	default:
262		WARN_ON(1);
263		return -EINVAL;
264	}
265
266	if (info->num_bus_formats)
267		s->bus_format = info->bus_formats[0];
268	else
269		s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
270
271	s->output_type = DRM_MODE_CONNECTOR_DSI;
272	s->bus_flags = info->bus_flags;
273	s->color_space = V4L2_COLORSPACE_DEFAULT;
274
275	return 0;
276}
277
278static const struct drm_encoder_helper_funcs
279dw_mipi_dsi2_encoder_helper_funcs = {
280	.atomic_enable = dw_mipi_dsi2_encoder_atomic_enable,
281	.atomic_check = dw_mipi_dsi2_encoder_atomic_check,
282};
283
284static int rockchip_dsi2_drm_create_encoder(struct dw_mipi_dsi2_rockchip *dsi2,
285					    struct drm_device *drm_dev)
286{
287	struct drm_encoder *encoder = &dsi2->encoder.encoder;
288	int ret;
289
290	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
291							     dsi2->dev->of_node);
292
293	ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_DSI);
294	if (ret) {
295		dev_err(dsi2->dev, "Failed to initialize encoder with drm\n");
296		return ret;
297	}
298
299	drm_encoder_helper_add(encoder, &dw_mipi_dsi2_encoder_helper_funcs);
300
301	return 0;
302}
303
304static int dw_mipi_dsi2_rockchip_bind(struct device *dev, struct device *master,
305				      void *data)
306{
307	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
308	struct drm_device *drm_dev = data;
309	int ret;
310
311	ret = rockchip_dsi2_drm_create_encoder(dsi2, drm_dev);
312	if (ret)
313		return dev_err_probe(dev, ret, "Failed to create drm encoder\n");
314
315	rockchip_drm_encoder_set_crtc_endpoint_id(&dsi2->encoder,
316						  dev->of_node, 0, 0);
317
318	ret = dw_mipi_dsi2_bind(dsi2->dmd, &dsi2->encoder.encoder);
319	if (ret)
320		return dev_err_probe(dev, ret, "Failed to bind\n");
321
322	return 0;
323}
324
325static void dw_mipi_dsi2_rockchip_unbind(struct device *dev, struct device *master,
326					 void *data)
327{
328	struct dw_mipi_dsi2_rockchip *dsi2 = dev_get_drvdata(dev);
329
330	dw_mipi_dsi2_unbind(dsi2->dmd);
331}
332
333static const struct component_ops dw_mipi_dsi2_rockchip_ops = {
334	.bind	= dw_mipi_dsi2_rockchip_bind,
335	.unbind	= dw_mipi_dsi2_rockchip_unbind,
336};
337
338static int dw_mipi_dsi2_rockchip_host_attach(void *priv_data,
339					     struct mipi_dsi_device *device)
340{
341	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
342	int ret;
343
344	ret = component_add(dsi2->dev, &dw_mipi_dsi2_rockchip_ops);
345	if (ret)
346		return dev_err_probe(dsi2->dev, ret, "Failed to register component\n");
347
348	return 0;
349}
350
351static int dw_mipi_dsi2_rockchip_host_detach(void *priv_data,
352					     struct mipi_dsi_device *device)
353{
354	struct dw_mipi_dsi2_rockchip *dsi2 = priv_data;
355
356	component_del(dsi2->dev, &dw_mipi_dsi2_rockchip_ops);
357
358	return 0;
359}
360
361static const struct dw_mipi_dsi2_host_ops dw_mipi_dsi2_rockchip_host_ops = {
362	.attach = dw_mipi_dsi2_rockchip_host_attach,
363	.detach = dw_mipi_dsi2_rockchip_host_detach,
364};
365
366static const struct regmap_config dw_mipi_dsi2_rockchip_regmap_config = {
367	.name = "dsi2-host",
368	.reg_bits = 32,
369	.val_bits = 32,
370	.reg_stride = 4,
371	.fast_io = true,
372};
373
374static int dw_mipi_dsi2_rockchip_probe(struct platform_device *pdev)
375{
376	struct device *dev = &pdev->dev;
377	struct device_node *np = dev->of_node;
378	const struct rockchip_dw_dsi2_chip_data *cdata =
379						of_device_get_match_data(dev);
380	struct dw_mipi_dsi2_rockchip *dsi2;
381	struct resource *res;
382	void __iomem *base;
383	int i;
384
385	dsi2 = devm_kzalloc(dev, sizeof(*dsi2), GFP_KERNEL);
386	if (!dsi2)
387		return -ENOMEM;
388
389	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
390	if (IS_ERR(base))
391		return dev_err_probe(dev, PTR_ERR(base), "Unable to get dsi registers\n");
392
393	dsi2->regmap = devm_regmap_init_mmio(dev, base, &dw_mipi_dsi2_rockchip_regmap_config);
394	if (IS_ERR(dsi2->regmap))
395		return dev_err_probe(dev, PTR_ERR(dsi2->regmap), "failed to init register map\n");
396
397	i = 0;
398	while (cdata[i].reg) {
399		if (cdata[i].reg == res->start) {
400			dsi2->cdata = &cdata[i];
401			break;
402		}
403
404		i++;
405	}
406
407	if (!dsi2->cdata)
408		return dev_err_probe(dev, -EINVAL, "No dsi-config for %s node\n", np->name);
409
410	dsi2->grf_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
411	if (IS_ERR(dsi2->grf_regmap))
412		return dev_err_probe(dsi2->dev, PTR_ERR(dsi2->grf_regmap), "Unable to get grf\n");
413
414	dsi2->phy = devm_phy_optional_get(dev, "dcphy");
415	if (IS_ERR(dsi2->phy))
416		return dev_err_probe(dev, PTR_ERR(dsi2->phy), "failed to get mipi phy\n");
417
418	dsi2->dev = dev;
419	dsi2->pdata.regmap = dsi2->regmap;
420	dsi2->pdata.max_data_lanes = 4;
421	dsi2->pdata.phy_ops = &dw_mipi_dsi2_rockchip_phy_ops;
422	dsi2->pdata.host_ops = &dw_mipi_dsi2_rockchip_host_ops;
423	dsi2->pdata.priv_data = dsi2;
424	platform_set_drvdata(pdev, dsi2);
425
426	dsi2->dmd = dw_mipi_dsi2_probe(pdev, &dsi2->pdata);
427	if (IS_ERR(dsi2->dmd))
428		return dev_err_probe(dev, PTR_ERR(dsi2->dmd), "Failed to probe dw_mipi_dsi2\n");
429
430	return 0;
431}
432
433static void dw_mipi_dsi2_rockchip_remove(struct platform_device *pdev)
434{
435	struct dw_mipi_dsi2_rockchip *dsi2 = platform_get_drvdata(pdev);
436
437	dw_mipi_dsi2_remove(dsi2->dmd);
438}
439
440static const struct dsigrf_reg rk3576_dsi_grf_reg_fields[MAX_FIELDS] = {
441	[TXREQCLKHS_EN]		= { 0x0028, 1,  1 },
442	[GATING_EN]		= { 0x0028, 0,  0 },
443	[IPI_SHUTDN]		= { 0x0028, 3,  3 },
444	[IPI_COLORM]		= { 0x0028, 2,  2 },
445	[IPI_COLOR_DEPTH]	= { 0x0028, 8, 11 },
446	[IPI_FORMAT]		= { 0x0028, 4,  7 },
447};
448
449static const struct dsigrf_reg rk3588_dsi0_grf_reg_fields[MAX_FIELDS] = {
450	[TXREQCLKHS_EN]		= { 0x0000, 11, 11 },
451	[GATING_EN]		= { 0x0000, 10, 10 },
452	[IPI_SHUTDN]		= { 0x0000,  9,  9 },
453	[IPI_COLORM]		= { 0x0000,  8,  8 },
454	[IPI_COLOR_DEPTH]	= { 0x0000,  4,  7 },
455	[IPI_FORMAT]		= { 0x0000,  0,  3 },
456};
457
458static const struct dsigrf_reg rk3588_dsi1_grf_reg_fields[MAX_FIELDS] = {
459	[TXREQCLKHS_EN]		= { 0x0004, 11, 11 },
460	[GATING_EN]		= { 0x0004, 10, 10 },
461	[IPI_SHUTDN]		= { 0x0004,  9,  9 },
462	[IPI_COLORM]		= { 0x0004,  8,  8 },
463	[IPI_COLOR_DEPTH]	= { 0x0004,  4,  7 },
464	[IPI_FORMAT]		= { 0x0004,  0,  3 },
465};
466
467static const struct rockchip_dw_dsi2_chip_data rk3576_chip_data[] = {
468	{
469		.reg = 0x27d80000,
470		.grf_regs = rk3576_dsi_grf_reg_fields,
471		.max_bit_rate_per_lane = 2500000ULL,
472	},
473	{ /* sentinel */ }
474};
475
476static const struct rockchip_dw_dsi2_chip_data rk3588_chip_data[] = {
477	{
478		.reg = 0xfde20000,
479		.grf_regs = rk3588_dsi0_grf_reg_fields,
480		.max_bit_rate_per_lane = 4500000ULL,
481	},
482	{
483		.reg = 0xfde30000,
484		.grf_regs = rk3588_dsi1_grf_reg_fields,
485		.max_bit_rate_per_lane = 4500000ULL,
486	}
487};
488
489static const struct of_device_id dw_mipi_dsi2_rockchip_dt_ids[] = {
490	{
491		.compatible = "rockchip,rk3576-mipi-dsi2",
492		.data = &rk3576_chip_data,
493	}, {
494		.compatible = "rockchip,rk3588-mipi-dsi2",
495		.data = &rk3588_chip_data,
496	},
497	{}
498};
499MODULE_DEVICE_TABLE(of, dw_mipi_dsi2_rockchip_dt_ids);
500
501struct platform_driver dw_mipi_dsi2_rockchip_driver = {
502	.probe	= dw_mipi_dsi2_rockchip_probe,
503	.remove = dw_mipi_dsi2_rockchip_remove,
504	.driver = {
505		.of_match_table = dw_mipi_dsi2_rockchip_dt_ids,
506		.name = "dw-mipi-dsi2",
507	},
508};
~/ Read-only file preview.