diff options
Diffstat (limited to 'drivers/gpu/drm/renesas')
-rw-r--r-- | drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rz-du/Kconfig | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c | 44 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c | 123 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 360 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h | 56 | ||||
-rw-r--r-- | drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c | 3 |
14 files changed, 577 insertions, 89 deletions
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c b/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c index 79b67c406bd6..93ba115d654f 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_cmm.c @@ -32,11 +32,6 @@ struct rcar_cmm { } lut; }; -static inline int rcar_cmm_read(struct rcar_cmm *rcmm, u32 reg) -{ - return ioread32(rcmm->base + reg); -} - static inline void rcar_cmm_write(struct rcar_cmm *rcmm, u32 reg, u32 data) { iowrite32(data, rcmm->base + reg); diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c index 70d8ad065bfa..216219accfd9 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c @@ -426,6 +426,7 @@ int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, static struct drm_framebuffer * rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, + const struct drm_format_info *info, const struct drm_mode_fb_cmd2 *mode_cmd) { struct rcar_du_device *rcdu = to_rcar_du_device(dev); @@ -490,7 +491,7 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, } } - return drm_gem_fb_create(dev, file_priv, mode_cmd); + return drm_gem_fb_create(dev, file_priv, info, mode_cmd); } /* ----------------------------------------------------------------------------- @@ -705,7 +706,7 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu) ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name, cells, i, &args); if (ret < 0) - goto error; + goto done; /* * Add the VSP to the list or update the corresponding existing @@ -743,13 +744,11 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu) vsp->dev = rcdu; ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask); - if (ret < 0) - goto error; + if (ret) + goto done; } - return 0; - -error: +done: for (i = 0; i < ARRAY_SIZE(vsps); ++i) of_node_put(vsps[i].np); diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.h index f9893d7d6dfc..e9e59c5e70d5 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.h +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.h @@ -16,7 +16,7 @@ struct rcar_du_format_info; struct rcar_du_group; /* - * The RCAR DU has 8 hardware planes, shared between primary and overlay planes. + * The R-Car DU has 8 hardware planes, shared between primary and overlay planes. * As using overlay planes requires at least one of the CRTCs being enabled, no * more than 7 overlay planes can be available. We thus create 1 primary plane * per CRTC and 7 overlay planes, for a total of up to 9 KMS planes. diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c b/drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c index 380a855b832a..af58b814e588 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c @@ -634,6 +634,7 @@ static bool rcar_lvds_mode_fixup(struct drm_bridge *bridge, } static int rcar_lvds_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) { struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); @@ -641,7 +642,7 @@ static int rcar_lvds_attach(struct drm_bridge *bridge, if (!lvds->next_bridge) return 0; - return drm_bridge_attach(bridge->encoder, lvds->next_bridge, bridge, + return drm_bridge_attach(encoder, lvds->next_bridge, bridge, flags); } @@ -877,9 +878,10 @@ static int rcar_lvds_probe(struct platform_device *pdev) struct rcar_lvds *lvds; int ret; - lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL); - if (lvds == NULL) - return -ENOMEM; + lvds = devm_drm_bridge_alloc(&pdev->dev, struct rcar_lvds, bridge, + &rcar_lvds_bridge_ops); + if (IS_ERR(lvds)) + return PTR_ERR(lvds); platform_set_drvdata(pdev, lvds); @@ -894,7 +896,6 @@ static int rcar_lvds_probe(struct platform_device *pdev) if (ret < 0) return ret; - lvds->bridge.funcs = &rcar_lvds_bridge_ops; lvds->bridge.of_node = pdev->dev.of_node; lvds->mmio = devm_platform_ioremap_resource(pdev, 0); diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c index d1e626068065..1af4c73f7a88 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi.c @@ -799,11 +799,12 @@ static void rcar_mipi_dsi_stop_video(struct rcar_mipi_dsi *dsi) */ static int rcar_mipi_dsi_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) { struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge); - return drm_bridge_attach(bridge->encoder, dsi->next_bridge, bridge, + return drm_bridge_attach(encoder, dsi->next_bridge, bridge, flags); } @@ -917,7 +918,6 @@ static int rcar_mipi_dsi_host_attach(struct mipi_dsi_host *host, } /* Initialize the DRM bridge. */ - dsi->bridge.funcs = &rcar_mipi_dsi_bridge_ops; dsi->bridge.of_node = dsi->dev->of_node; drm_bridge_add(&dsi->bridge); @@ -1003,9 +1003,10 @@ static int rcar_mipi_dsi_probe(struct platform_device *pdev) struct rcar_mipi_dsi *dsi; int ret; - dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL); - if (dsi == NULL) - return -ENOMEM; + dsi = devm_drm_bridge_alloc(&pdev->dev, struct rcar_mipi_dsi, bridge, + &rcar_mipi_dsi_bridge_ops); + if (IS_ERR(dsi)) + return PTR_ERR(dsi); platform_set_drvdata(pdev, dsi); diff --git a/drivers/gpu/drm/renesas/rz-du/Kconfig b/drivers/gpu/drm/renesas/rz-du/Kconfig index 7c1817240846..e57536fd6f4d 100644 --- a/drivers/gpu/drm/renesas/rz-du/Kconfig +++ b/drivers/gpu/drm/renesas/rz-du/Kconfig @@ -14,10 +14,15 @@ config DRM_RZG2L_DU Choose this option if you have an RZ/G2L alike chipset. If M is selected the module will be called rzg2l-du-drm. -config DRM_RZG2L_MIPI_DSI - tristate "RZ/G2L MIPI DSI Encoder Support" - depends on DRM && DRM_BRIDGE && OF - depends on ARCH_RENESAS || COMPILE_TEST - select DRM_MIPI_DSI +config DRM_RZG2L_USE_MIPI_DSI + bool "RZ/G2L MIPI DSI Encoder Support" + depends on DRM_BRIDGE && OF + depends on DRM_RZG2L_DU || COMPILE_TEST + default DRM_RZG2L_DU help Enable support for the RZ/G2L Display Unit embedded MIPI DSI encoders. + +config DRM_RZG2L_MIPI_DSI + def_tristate DRM_RZG2L_DU + depends on DRM_RZG2L_USE_MIPI_DSI + select DRM_MIPI_DSI diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c index cbd9b9841267..e1aa6a719529 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c @@ -50,9 +50,20 @@ static const struct rzg2l_du_device_info rzg2l_du_r9a07g044_info = { } }; +static const struct rzg2l_du_device_info rzg2l_du_r9a09g057_info = { + .channels_mask = BIT(0), + .routes = { + [RZG2L_DU_OUTPUT_DSI0] = { + .possible_outputs = BIT(0), + .port = 0, + }, + }, +}; + static const struct of_device_id rzg2l_du_of_table[] = { { .compatible = "renesas,r9a07g043u-du", .data = &rzg2l_du_r9a07g043u_info }, { .compatible = "renesas,r9a07g044-du", .data = &rzg2l_du_r9a07g044_info }, + { .compatible = "renesas,r9a09g057-du", .data = &rzg2l_du_r9a09g057_info }, { /* sentinel */ } }; @@ -79,7 +90,7 @@ DEFINE_DRM_GEM_DMA_FOPS(rzg2l_du_fops); static const struct drm_driver rzg2l_du_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, - .dumb_create = rzg2l_du_dumb_create, + DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(rzg2l_du_dumb_create), DRM_FBDEV_DMA_DRIVER_OPS, .fops = &rzg2l_du_fops, .name = "rzg2l-du", diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c index 564ab4cb3d37..5e6dd16705e6 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c @@ -22,6 +22,26 @@ * Encoder */ +static unsigned int rzg2l_du_encoder_count_ports(struct device_node *node) +{ + struct device_node *ports; + struct device_node *port; + unsigned int num_ports = 0; + + ports = of_get_child_by_name(node, "ports"); + if (!ports) + ports = of_node_get(node); + + for_each_child_of_node(ports, port) { + if (of_node_name_eq(port, "port")) + num_ports++; + } + + of_node_put(ports); + + return num_ports; +} + static const struct drm_encoder_funcs rzg2l_du_encoder_funcs = { }; @@ -50,10 +70,26 @@ int rzg2l_du_encoder_init(struct rzg2l_du_device *rcdu, struct drm_bridge *bridge; int ret; - /* Locate the DRM bridge from the DT node. */ - bridge = of_drm_find_bridge(enc_node); - if (!bridge) - return -EPROBE_DEFER; + /* + * Locate the DRM bridge from the DT node. For the DPAD outputs, if the + * DT node has a single port, assume that it describes a panel and + * create a panel bridge. + */ + if (output == RZG2L_DU_OUTPUT_DPAD0 && rzg2l_du_encoder_count_ports(enc_node) == 1) { + struct drm_panel *panel = of_drm_find_panel(enc_node); + + if (IS_ERR(panel)) + return PTR_ERR(panel); + + bridge = devm_drm_panel_bridge_add_typed(rcdu->dev, panel, + DRM_MODE_CONNECTOR_DPI); + if (IS_ERR(bridge)) + return PTR_ERR(bridge); + } else { + bridge = of_drm_find_bridge(enc_node); + if (!bridge) + return -EPROBE_DEFER; + } dev_dbg(rcdu->dev, "initializing encoder %pOF for output %s\n", enc_node, rzg2l_du_output_name(output)); diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c index 90c6269ccd29..87f171145a23 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.c @@ -36,23 +36,129 @@ static const struct rzg2l_du_format_info rzg2l_du_format_infos[] = { { - .fourcc = DRM_FORMAT_XRGB8888, - .v4l2 = V4L2_PIX_FMT_XBGR32, - .bpp = 32, + .fourcc = DRM_FORMAT_RGB332, + .v4l2 = V4L2_PIX_FMT_RGB332, .planes = 1, .hsub = 1, }, { - .fourcc = DRM_FORMAT_ARGB8888, - .v4l2 = V4L2_PIX_FMT_ABGR32, - .bpp = 32, + .fourcc = DRM_FORMAT_ARGB4444, + .v4l2 = V4L2_PIX_FMT_ARGB444, + .planes = 1, + .hsub = 1, + }, { + .fourcc = DRM_FORMAT_XRGB4444, + .v4l2 = V4L2_PIX_FMT_XRGB444, + .planes = 1, + .hsub = 1, + }, { + .fourcc = DRM_FORMAT_ARGB1555, + .v4l2 = V4L2_PIX_FMT_ARGB555, + .planes = 1, + .hsub = 1, + }, { + .fourcc = DRM_FORMAT_XRGB1555, + .v4l2 = V4L2_PIX_FMT_XRGB555, + .planes = 1, + }, { + .fourcc = DRM_FORMAT_RGB565, + .v4l2 = V4L2_PIX_FMT_RGB565, + .planes = 1, + .hsub = 1, + }, { + .fourcc = DRM_FORMAT_BGR888, + .v4l2 = V4L2_PIX_FMT_RGB24, .planes = 1, .hsub = 1, }, { .fourcc = DRM_FORMAT_RGB888, .v4l2 = V4L2_PIX_FMT_BGR24, - .bpp = 24, .planes = 1, .hsub = 1, + }, { + .fourcc = DRM_FORMAT_BGRA8888, + .v4l2 = V4L2_PIX_FMT_ARGB32, + .planes = 1, + .hsub = 1, + }, { + .fourcc = DRM_FORMAT_BGRX8888, + .v4l2 = V4L2_PIX_FMT_XRGB32, + .planes = 1, + .hsub = 1, + }, { + .fourcc = DRM_FORMAT_ARGB8888, + .v4l2 = V4L2_PIX_FMT_ABGR32, + .planes = 1, + .hsub = 1, + }, { + .fourcc = DRM_FORMAT_XRGB8888, + .v4l2 = V4L2_PIX_FMT_XBGR32, + .planes = 1, + .hsub = 1, + }, { + .fourcc = DRM_FORMAT_UYVY, + .v4l2 = V4L2_PIX_FMT_UYVY, + .planes = 1, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_YUYV, + .v4l2 = V4L2_PIX_FMT_YUYV, + .planes = 1, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_YVYU, + .v4l2 = V4L2_PIX_FMT_YVYU, + .planes = 1, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_NV12, + .v4l2 = V4L2_PIX_FMT_NV12M, + .planes = 2, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_NV21, + .v4l2 = V4L2_PIX_FMT_NV21M, + .planes = 2, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_NV16, + .v4l2 = V4L2_PIX_FMT_NV16M, + .planes = 2, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_NV61, + .v4l2 = V4L2_PIX_FMT_NV61M, + .planes = 2, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_YUV420, + .v4l2 = V4L2_PIX_FMT_YUV420M, + .planes = 3, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_YVU420, + .v4l2 = V4L2_PIX_FMT_YVU420M, + .planes = 3, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_YUV422, + .v4l2 = V4L2_PIX_FMT_YUV422M, + .planes = 3, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_YVU422, + .v4l2 = V4L2_PIX_FMT_YVU422M, + .planes = 3, + .hsub = 2, + }, { + .fourcc = DRM_FORMAT_YUV444, + .v4l2 = V4L2_PIX_FMT_YUV444M, + .planes = 3, + .hsub = 1, + }, { + .fourcc = DRM_FORMAT_YVU444, + .v4l2 = V4L2_PIX_FMT_YVU444M, + .planes = 3, + .hsub = 1, } }; @@ -85,6 +191,7 @@ int rzg2l_du_dumb_create(struct drm_file *file, struct drm_device *dev, static struct drm_framebuffer * rzg2l_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, + const struct drm_format_info *info, const struct drm_mode_fb_cmd2 *mode_cmd) { const struct rzg2l_du_format_info *format; @@ -108,7 +215,7 @@ rzg2l_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, return ERR_PTR(-EINVAL); } - return drm_gem_fb_create(dev, file_priv, mode_cmd); + return drm_gem_fb_create(dev, file_priv, info, mode_cmd); } /* ----------------------------------------------------------------------------- diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.h index 876e97cfbf45..e2c599f115c6 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.h +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_kms.h @@ -23,7 +23,6 @@ struct sg_table; struct rzg2l_du_format_info { u32 fourcc; u32 v4l2; - unsigned int bpp; unsigned int planes; unsigned int hsub; }; diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c index 8643ff2eec46..040d4e4aff00 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c @@ -340,6 +340,15 @@ int rzg2l_du_vsp_init(struct rzg2l_du_vsp *vsp, struct device_node *np, drm_plane_helper_add(&plane->plane, &rzg2l_du_vsp_plane_helper_funcs); + + drm_plane_create_alpha_property(&plane->plane); + drm_plane_create_zpos_property(&plane->plane, i, 0, + num_planes - 1); + + drm_plane_create_blend_mode_property(&plane->plane, + BIT(DRM_MODE_BLEND_PIXEL_NONE) | + BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE)); } return 0; diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c index 4550c6d84796..f87337c3cbb5 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c @@ -4,10 +4,14 @@ * * Copyright (C) 2022 Renesas Electronics Corporation */ + +#include <linux/bitfield.h> #include <linux/clk.h> #include <linux/delay.h> +#include <linux/dma-mapping.h> #include <linux/io.h> #include <linux/iopoll.h> +#include <linux/math.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_graph.h> @@ -15,6 +19,7 @@ #include <linux/pm_runtime.h> #include <linux/reset.h> #include <linux/slab.h> +#include <linux/units.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> @@ -23,13 +28,37 @@ #include <drm/drm_of.h> #include <drm/drm_panel.h> #include <drm/drm_probe_helper.h> +#include <video/mipi_display.h> #include "rzg2l_mipi_dsi_regs.h" +#define RZG2L_DCS_BUF_SIZE 128 /* Maximum DCS buffer size in external memory. */ + +#define RZ_MIPI_DSI_FEATURE_16BPP BIT(0) + +struct rzg2l_mipi_dsi; + +struct rzg2l_mipi_dsi_hw_info { + int (*dphy_init)(struct rzg2l_mipi_dsi *dsi, u64 hsfreq_millihz); + void (*dphy_startup_late_init)(struct rzg2l_mipi_dsi *dsi); + void (*dphy_exit)(struct rzg2l_mipi_dsi *dsi); + int (*dphy_conf_clks)(struct rzg2l_mipi_dsi *dsi, unsigned long mode_freq, + u64 *hsfreq_millihz); + unsigned int (*dphy_mode_clk_check)(struct rzg2l_mipi_dsi *dsi, + unsigned long mode_freq); + u32 phy_reg_offset; + u32 link_reg_offset; + unsigned long min_dclk; + unsigned long max_dclk; + u8 features; +}; + struct rzg2l_mipi_dsi { struct device *dev; void __iomem *mmio; + const struct rzg2l_mipi_dsi_hw_info *info; + struct reset_control *rstc; struct reset_control *arstc; struct reset_control *prstc; @@ -44,6 +73,10 @@ struct rzg2l_mipi_dsi { unsigned int num_data_lanes; unsigned int lanes; unsigned long mode_flags; + + /* DCS buffer pointers when using external memory. */ + dma_addr_t dcs_buf_phys; + u8 *dcs_buf_virt; }; static inline struct rzg2l_mipi_dsi * @@ -75,7 +108,7 @@ struct rzg2l_mipi_dsi_timings { static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { { - .hsfreq_max = 80000, + .hsfreq_max = 80000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 13, @@ -89,7 +122,7 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { .tlpx = 6, }, { - .hsfreq_max = 125000, + .hsfreq_max = 125000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 12, @@ -103,7 +136,7 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { .tlpx = 6, }, { - .hsfreq_max = 250000, + .hsfreq_max = 250000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 12, @@ -117,7 +150,7 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { .tlpx = 6, }, { - .hsfreq_max = 360000, + .hsfreq_max = 360000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 10, @@ -131,7 +164,7 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { .tlpx = 6, }, { - .hsfreq_max = 720000, + .hsfreq_max = 720000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 9, @@ -145,7 +178,7 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { .tlpx = 6, }, { - .hsfreq_max = 1500000, + .hsfreq_max = 1500000000, .t_init = 79801, .tclk_prepare = 8, .ths_prepare = 9, @@ -162,22 +195,22 @@ static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { static void rzg2l_mipi_dsi_phy_write(struct rzg2l_mipi_dsi *dsi, u32 reg, u32 data) { - iowrite32(data, dsi->mmio + reg); + iowrite32(data, dsi->mmio + dsi->info->phy_reg_offset + reg); } static void rzg2l_mipi_dsi_link_write(struct rzg2l_mipi_dsi *dsi, u32 reg, u32 data) { - iowrite32(data, dsi->mmio + LINK_REG_OFFSET + reg); + iowrite32(data, dsi->mmio + dsi->info->link_reg_offset + reg); } static u32 rzg2l_mipi_dsi_phy_read(struct rzg2l_mipi_dsi *dsi, u32 reg) { - return ioread32(dsi->mmio + reg); + return ioread32(dsi->mmio + dsi->info->phy_reg_offset + reg); } static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi *dsi, u32 reg) { - return ioread32(dsi->mmio + LINK_REG_OFFSET + reg); + return ioread32(dsi->mmio + dsi->info->link_reg_offset + reg); } /* ----------------------------------------------------------------------------- @@ -185,8 +218,9 @@ static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi *dsi, u32 reg) */ static int rzg2l_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi *dsi, - unsigned long hsfreq) + u64 hsfreq_millihz) { + unsigned long hsfreq = DIV_ROUND_CLOSEST_ULL(hsfreq_millihz, MILLI); const struct rzg2l_mipi_dsi_timings *dphy_timings; unsigned int i; u32 dphyctrl0; @@ -255,20 +289,17 @@ static void rzg2l_mipi_dsi_dphy_exit(struct rzg2l_mipi_dsi *dsi) reset_control_assert(dsi->rstc); } -static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, - const struct drm_display_mode *mode) +static int rzg2l_dphy_conf_clks(struct rzg2l_mipi_dsi *dsi, unsigned long mode_freq, + u64 *hsfreq_millihz) { - unsigned long hsfreq; + unsigned long vclk_rate; unsigned int bpp; - u32 txsetr; - u32 clstptsetr; - u32 lptrnstsetr; - u32 clkkpt; - u32 clkbfht; - u32 clkstpt; - u32 golpbkt; - int ret; + clk_set_rate(dsi->vclk, mode_freq * KILO); + vclk_rate = clk_get_rate(dsi->vclk); + if (vclk_rate != mode_freq * KILO) + dev_dbg(dsi->dev, "Requested vclk rate %lu, actual %lu mismatch\n", + mode_freq * KILO, vclk_rate); /* * Relationship between hsclk and vclk must follow * vclk * bpp = hsclk * 8 * lanes @@ -277,18 +308,39 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, * hsclk: DSI HS Byte clock frequency (Hz) * lanes: number of data lanes * - * hsclk(bit) = hsclk(byte) * 8 + * hsclk(bit) = hsclk(byte) * 8 = hsfreq */ bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); - hsfreq = (mode->clock * bpp * 8) / (8 * dsi->lanes); + *hsfreq_millihz = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(vclk_rate, bpp * MILLI), + dsi->lanes); + + return 0; +} + +static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, + const struct drm_display_mode *mode) +{ + unsigned long hsfreq; + u64 hsfreq_millihz; + u32 txsetr; + u32 clstptsetr; + u32 lptrnstsetr; + u32 clkkpt; + u32 clkbfht; + u32 clkstpt; + u32 golpbkt; + u32 dsisetr; + int ret; ret = pm_runtime_resume_and_get(dsi->dev); if (ret < 0) return ret; - clk_set_rate(dsi->vclk, mode->clock * 1000); + ret = dsi->info->dphy_conf_clks(dsi, mode->clock, &hsfreq_millihz); + if (ret < 0) + goto err_phy; - ret = rzg2l_mipi_dsi_dphy_init(dsi, hsfreq); + ret = dsi->info->dphy_init(dsi, hsfreq_millihz); if (ret < 0) goto err_phy; @@ -296,6 +348,10 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, txsetr = TXSETR_DLEN | TXSETR_NUMLANEUSE(dsi->lanes - 1) | TXSETR_CLEN; rzg2l_mipi_dsi_link_write(dsi, TXSETR, txsetr); + if (dsi->info->dphy_startup_late_init) + dsi->info->dphy_startup_late_init(dsi); + + hsfreq = DIV_ROUND_CLOSEST_ULL(hsfreq_millihz, MILLI); /* * Global timings characteristic depends on high speed Clock Frequency * Currently MIPI DSI-IF just supports maximum FHD@60 with: @@ -304,12 +360,12 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, * - data lanes: maximum 4 lanes * Therefore maximum hsclk will be 891 Mbps. */ - if (hsfreq > 445500) { + if (hsfreq > 445500000) { clkkpt = 12; clkbfht = 15; clkstpt = 48; golpbkt = 75; - } else if (hsfreq > 250000) { + } else if (hsfreq > 250000000) { clkkpt = 7; clkbfht = 8; clkstpt = 27; @@ -328,10 +384,19 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, lptrnstsetr = LPTRNSTSETR_GOLPBKT(golpbkt); rzg2l_mipi_dsi_link_write(dsi, LPTRNSTSETR, lptrnstsetr); + /* + * Increase MRPSZ as the default value of 1 will result in long read + * commands payload not being saved to memory. + */ + dsisetr = rzg2l_mipi_dsi_link_read(dsi, DSISETR); + dsisetr &= ~DSISETR_MRPSZ; + dsisetr |= FIELD_PREP(DSISETR_MRPSZ, RZG2L_DCS_BUF_SIZE); + rzg2l_mipi_dsi_link_write(dsi, DSISETR, dsisetr); + return 0; err_phy: - rzg2l_mipi_dsi_dphy_exit(dsi); + dsi->info->dphy_exit(dsi); pm_runtime_put(dsi->dev); return ret; @@ -339,7 +404,7 @@ err_phy: static void rzg2l_mipi_dsi_stop(struct rzg2l_mipi_dsi *dsi) { - rzg2l_mipi_dsi_dphy_exit(dsi); + dsi->info->dphy_exit(dsi); pm_runtime_put(dsi->dev); } @@ -479,7 +544,7 @@ static int rzg2l_mipi_dsi_start_video(struct rzg2l_mipi_dsi *dsi) u32 status; int ret; - /* Configuration for Blanking sequence and start video input*/ + /* Configuration for Blanking sequence and start video input */ vich1set0r = VICH1SET0R_HFPNOLP | VICH1SET0R_HBPNOLP | VICH1SET0R_HSANOLP | VICH1SET0R_VSTART; rzg2l_mipi_dsi_link_write(dsi, VICH1SET0R, vich1set0r); @@ -523,16 +588,17 @@ err: */ static int rzg2l_mipi_dsi_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) { struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge); - return drm_bridge_attach(bridge->encoder, dsi->next_bridge, bridge, + return drm_bridge_attach(encoder, dsi->next_bridge, bridge, flags); } -static void rzg2l_mipi_dsi_atomic_enable(struct drm_bridge *bridge, - struct drm_atomic_state *state) +static void rzg2l_mipi_dsi_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge); const struct drm_display_mode *mode; @@ -549,6 +615,13 @@ static void rzg2l_mipi_dsi_atomic_enable(struct drm_bridge *bridge, return; rzg2l_mipi_dsi_set_display_timing(dsi, mode); +} + +static void rzg2l_mipi_dsi_atomic_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) +{ + struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge); + int ret; ret = rzg2l_mipi_dsi_start_hs_clock(dsi); if (ret < 0) @@ -581,9 +654,22 @@ rzg2l_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, const struct drm_display_mode *mode) { - if (mode->clock > 148500) + struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge); + + if (mode->clock > dsi->info->max_dclk) return MODE_CLOCK_HIGH; + if (mode->clock < dsi->info->min_dclk) + return MODE_CLOCK_LOW; + + if (dsi->info->dphy_mode_clk_check) { + enum drm_mode_status status; + + status = dsi->info->dphy_mode_clk_check(dsi, mode->clock); + if (status != MODE_OK) + return status; + } + return MODE_OK; } @@ -592,6 +678,7 @@ static const struct drm_bridge_funcs rzg2l_mipi_dsi_bridge_ops = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_pre_enable = rzg2l_mipi_dsi_atomic_pre_enable, .atomic_enable = rzg2l_mipi_dsi_atomic_enable, .atomic_disable = rzg2l_mipi_dsi_atomic_disable, .mode_valid = rzg2l_mipi_dsi_bridge_mode_valid, @@ -616,8 +703,16 @@ static int rzg2l_mipi_dsi_host_attach(struct mipi_dsi_host *host, switch (mipi_dsi_pixel_format_to_bpp(device->format)) { case 24: + break; case 18: break; + case 16: + if (!(dsi->info->features & RZ_MIPI_DSI_FEATURE_16BPP)) { + dev_err(dsi->dev, "Unsupported format 0x%04x\n", + device->format); + return -EINVAL; + } + break; default: dev_err(dsi->dev, "Unsupported format 0x%04x\n", device->format); return -EINVAL; @@ -650,9 +745,168 @@ static int rzg2l_mipi_dsi_host_detach(struct mipi_dsi_host *host, return 0; } +static ssize_t rzg2l_mipi_dsi_read_response(struct rzg2l_mipi_dsi *dsi, + const struct mipi_dsi_msg *msg) +{ + u8 *msg_rx = msg->rx_buf; + u8 datatype; + u32 result; + u16 size; + + result = rzg2l_mipi_dsi_link_read(dsi, RXRSS0R); + if (result & RXRSS0R_RXPKTDFAIL) { + dev_err(dsi->dev, "packet rx data did not save correctly\n"); + return -EPROTO; + } + + if (result & RXRSS0R_RXFAIL) { + dev_err(dsi->dev, "packet rx failure\n"); + return -EPROTO; + } + + if (!(result & RXRSS0R_RXSUC)) + return -EPROTO; + + datatype = FIELD_GET(RXRSS0R_DT, result); + + switch (datatype) { + case 0: + dev_dbg(dsi->dev, "ACK\n"); + return 0; + case MIPI_DSI_RX_END_OF_TRANSMISSION: + dev_dbg(dsi->dev, "EoTp\n"); + return 0; + case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT: + dev_dbg(dsi->dev, "Acknowledge and error report: $%02x%02x\n", + (u8)FIELD_GET(RXRSS0R_DATA1, result), + (u8)FIELD_GET(RXRSS0R_DATA0, result)); + return 0; + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE: + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE: + msg_rx[0] = FIELD_GET(RXRSS0R_DATA0, result); + return 1; + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE: + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE: + msg_rx[0] = FIELD_GET(RXRSS0R_DATA0, result); + msg_rx[1] = FIELD_GET(RXRSS0R_DATA1, result); + return 2; + case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE: + case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE: + size = FIELD_GET(RXRSS0R_WC, result); + + if (size > msg->rx_len) { + dev_err(dsi->dev, "rx buffer too small"); + return -ENOSPC; + } + + memcpy(msg_rx, dsi->dcs_buf_virt, size); + return size; + default: + dev_err(dsi->dev, "unhandled response type: %02x\n", datatype); + return -EPROTO; + } +} + +static ssize_t rzg2l_mipi_dsi_host_transfer(struct mipi_dsi_host *host, + const struct mipi_dsi_msg *msg) +{ + struct rzg2l_mipi_dsi *dsi = host_to_rzg2l_mipi_dsi(host); + struct mipi_dsi_packet packet; + bool need_bta; + u32 value; + int ret; + + ret = mipi_dsi_create_packet(&packet, msg); + if (ret < 0) + return ret; + + /* Terminate operation after this descriptor is finished */ + value = SQCH0DSC0AR_NXACT_TERM; + + if (msg->flags & MIPI_DSI_MSG_REQ_ACK) { + need_bta = true; /* Message with explicitly requested ACK */ + value |= FIELD_PREP(SQCH0DSC0AR_BTA, SQCH0DSC0AR_BTA_NON_READ); + } else if (msg->rx_buf && msg->rx_len > 0) { + need_bta = true; /* Read request */ + value |= FIELD_PREP(SQCH0DSC0AR_BTA, SQCH0DSC0AR_BTA_READ); + } else { + need_bta = false; + value |= FIELD_PREP(SQCH0DSC0AR_BTA, SQCH0DSC0AR_BTA_NONE); + } + + /* Set transmission speed */ + if (msg->flags & MIPI_DSI_MSG_USE_LPM) + value |= SQCH0DSC0AR_SPD_LOW; + else + value |= SQCH0DSC0AR_SPD_HIGH; + + /* Write TX packet header */ + value |= FIELD_PREP(SQCH0DSC0AR_DT, packet.header[0]) | + FIELD_PREP(SQCH0DSC0AR_DATA0, packet.header[1]) | + FIELD_PREP(SQCH0DSC0AR_DATA1, packet.header[2]); + + if (mipi_dsi_packet_format_is_long(msg->type)) { + value |= SQCH0DSC0AR_FMT_LONG; + + if (packet.payload_length > RZG2L_DCS_BUF_SIZE) { + dev_err(dsi->dev, "Packet Tx payload size (%d) too large", + (unsigned int)packet.payload_length); + return -ENOSPC; + } + + /* Copy TX packet payload data to memory space */ + memcpy(dsi->dcs_buf_virt, packet.payload, packet.payload_length); + } else { + value |= SQCH0DSC0AR_FMT_SHORT; + } + + rzg2l_mipi_dsi_link_write(dsi, SQCH0DSC0AR, value); + + /* + * Write: specify payload data source location, only used for + * long packet. + * Read: specify payload data storage location of response + * packet. Note: a read packet is always a short packet. + * If the response packet is a short packet or a long packet + * with WC = 0 (no payload), DTSEL is meaningless. + */ + rzg2l_mipi_dsi_link_write(dsi, SQCH0DSC0BR, SQCH0DSC0BR_DTSEL_MEM_SPACE); + + /* + * Set SQCHxSR.AACTFIN bit when descriptor actions are finished. + * Read: set Rx result save slot number to 0 (ACTCODE). + */ + rzg2l_mipi_dsi_link_write(dsi, SQCH0DSC0CR, SQCH0DSC0CR_FINACT); + + /* Set rx/tx payload data address, only relevant for long packet. */ + rzg2l_mipi_dsi_link_write(dsi, SQCH0DSC0DR, (u32)dsi->dcs_buf_phys); + + /* Start sequence 0 operation */ + value = rzg2l_mipi_dsi_link_read(dsi, SQCH0SET0R); + value |= SQCH0SET0R_START; + rzg2l_mipi_dsi_link_write(dsi, SQCH0SET0R, value); + + /* Wait for operation to finish */ + ret = read_poll_timeout(rzg2l_mipi_dsi_link_read, + value, value & SQCH0SR_ADESFIN, + 2000, 20000, false, dsi, SQCH0SR); + if (ret == 0) { + /* Success: clear status bit */ + rzg2l_mipi_dsi_link_write(dsi, SQCH0SCR, SQCH0SCR_ADESFIN); + + if (need_bta) + ret = rzg2l_mipi_dsi_read_response(dsi, msg); + else + ret = packet.payload_length; + } + + return ret; +} + static const struct mipi_dsi_host_ops rzg2l_mipi_dsi_host_ops = { .attach = rzg2l_mipi_dsi_host_attach, .detach = rzg2l_mipi_dsi_host_detach, + .transfer = rzg2l_mipi_dsi_host_transfer, }; /* ----------------------------------------------------------------------------- @@ -700,13 +954,16 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev) u32 txsetr; int ret; - dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL); - if (!dsi) - return -ENOMEM; + dsi = devm_drm_bridge_alloc(&pdev->dev, struct rzg2l_mipi_dsi, bridge, + &rzg2l_mipi_dsi_bridge_ops); + if (IS_ERR(dsi)) + return PTR_ERR(dsi); platform_set_drvdata(pdev, dsi); dsi->dev = &pdev->dev; + dsi->info = of_device_get_match_data(&pdev->dev); + ret = drm_of_get_data_lanes_count_ep(dsi->dev->of_node, 1, 0, 1, 4); if (ret < 0) return dev_err_probe(dsi->dev, ret, @@ -722,7 +979,7 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev) if (IS_ERR(dsi->vclk)) return PTR_ERR(dsi->vclk); - dsi->rstc = devm_reset_control_get_exclusive(dsi->dev, "rst"); + dsi->rstc = devm_reset_control_get_optional_exclusive(dsi->dev, "rst"); if (IS_ERR(dsi->rstc)) return dev_err_probe(dsi->dev, PTR_ERR(dsi->rstc), "failed to get rst\n"); @@ -750,17 +1007,16 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev) * mode->clock and format are not available. So initialize DPHY with * timing parameters for 80Mbps. */ - ret = rzg2l_mipi_dsi_dphy_init(dsi, 80000); + ret = dsi->info->dphy_init(dsi, 80000000ULL * MILLI); if (ret < 0) goto err_phy; txsetr = rzg2l_mipi_dsi_link_read(dsi, TXSETR); dsi->num_data_lanes = min(((txsetr >> 16) & 3) + 1, num_data_lanes); - rzg2l_mipi_dsi_dphy_exit(dsi); + dsi->info->dphy_exit(dsi); pm_runtime_put(dsi->dev); /* Initialize the DRM bridge. */ - dsi->bridge.funcs = &rzg2l_mipi_dsi_bridge_ops; dsi->bridge.of_node = dsi->dev->of_node; /* Init host device */ @@ -770,10 +1026,15 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev) if (ret < 0) goto err_pm_disable; + dsi->dcs_buf_virt = dma_alloc_coherent(dsi->host.dev, RZG2L_DCS_BUF_SIZE, + &dsi->dcs_buf_phys, GFP_KERNEL); + if (!dsi->dcs_buf_virt) + return -ENOMEM; + return 0; err_phy: - rzg2l_mipi_dsi_dphy_exit(dsi); + dsi->info->dphy_exit(dsi); pm_runtime_put(dsi->dev); err_pm_disable: pm_runtime_disable(dsi->dev); @@ -784,12 +1045,23 @@ static void rzg2l_mipi_dsi_remove(struct platform_device *pdev) { struct rzg2l_mipi_dsi *dsi = platform_get_drvdata(pdev); + dma_free_coherent(dsi->host.dev, RZG2L_DCS_BUF_SIZE, dsi->dcs_buf_virt, + dsi->dcs_buf_phys); mipi_dsi_host_unregister(&dsi->host); pm_runtime_disable(&pdev->dev); } +static const struct rzg2l_mipi_dsi_hw_info rzg2l_mipi_dsi_info = { + .dphy_init = rzg2l_mipi_dsi_dphy_init, + .dphy_exit = rzg2l_mipi_dsi_dphy_exit, + .dphy_conf_clks = rzg2l_dphy_conf_clks, + .link_reg_offset = 0x10000, + .min_dclk = 5803, + .max_dclk = 148500, +}; + static const struct of_device_id rzg2l_mipi_dsi_of_table[] = { - { .compatible = "renesas,rzg2l-mipi-dsi" }, + { .compatible = "renesas,rzg2l-mipi-dsi", .data = &rzg2l_mipi_dsi_info, }, { /* sentinel */ } }; diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h index 1dbc16ec64a4..d8082a87d874 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h @@ -41,8 +41,6 @@ #define DSIDPHYTIM3_THS_ZERO(x) ((x) << 0) /* --------------------------------------------------------*/ -/* Link Registers */ -#define LINK_REG_OFFSET 0x10000 /* Link Status Register */ #define LINKSR 0x10 @@ -81,6 +79,20 @@ #define RSTSR_SWRSTLP (1 << 1) #define RSTSR_SWRSTHS (1 << 0) +/* DSI Set Register */ +#define DSISETR 0x120 +#define DSISETR_MRPSZ GENMASK(15, 0) + +/* Rx Result Save Slot 0 Register */ +#define RXRSS0R 0x240 +#define RXRSS0R_RXPKTDFAIL BIT(28) +#define RXRSS0R_RXFAIL BIT(27) +#define RXRSS0R_RXSUC BIT(25) +#define RXRSS0R_DT GENMASK(21, 16) +#define RXRSS0R_DATA1 GENMASK(15, 8) +#define RXRSS0R_DATA0 GENMASK(7, 0) +#define RXRSS0R_WC GENMASK(15, 0) /* Word count for long packet. */ + /* Clock Lane Stop Time Set Register */ #define CLSTPTSETR 0x314 #define CLSTPTSETR_CLKKPT(x) ((x) << 24) @@ -148,4 +160,44 @@ #define VICH1HPSETR_HFP(x) (((x) & 0x1fff) << 16) #define VICH1HPSETR_HBP(x) (((x) & 0x1fff) << 0) +/* Sequence Channel 0 Set 0 Register */ +#define SQCH0SET0R 0x5c0 +#define SQCH0SET0R_START BIT(0) + +/* Sequence Channel 0 Status Register */ +#define SQCH0SR 0x5d0 +#define SQCH0SR_ADESFIN BIT(8) + +/* Sequence Channel 0 Status Clear Register */ +#define SQCH0SCR 0x5d4 +#define SQCH0SCR_ADESFIN BIT(8) + +/* Sequence Channel 0 Descriptor 0-A Register */ +#define SQCH0DSC0AR 0x780 +#define SQCH0DSC0AR_NXACT_TERM 0 /* Bit 28 */ +#define SQCH0DSC0AR_BTA GENMASK(27, 26) +#define SQCH0DSC0AR_BTA_NONE 0 +#define SQCH0DSC0AR_BTA_NON_READ 1 +#define SQCH0DSC0AR_BTA_READ 2 +#define SQCH0DSC0AR_BTA_ONLY 3 +#define SQCH0DSC0AR_SPD_HIGH 0 +#define SQCH0DSC0AR_SPD_LOW BIT(25) +#define SQCH0DSC0AR_FMT_SHORT 0 +#define SQCH0DSC0AR_FMT_LONG BIT(24) +#define SQCH0DSC0AR_DT GENMASK(21, 16) +#define SQCH0DSC0AR_DATA1 GENMASK(15, 8) +#define SQCH0DSC0AR_DATA0 GENMASK(7, 0) + +/* Sequence Channel 0 Descriptor 0-B Register */ +#define SQCH0DSC0BR 0x784 +#define SQCH0DSC0BR_DTSEL_MEM_SPACE BIT(24) /* Use external memory */ + +/* Sequence Channel 0 Descriptor 0-C Register */ +#define SQCH0DSC0CR 0x788 +#define SQCH0DSC0CR_FINACT BIT(0) +#define SQCH0DSC0CR_AUXOP BIT(22) + +/* Sequence Channel 0 Descriptor 0-D Register */ +#define SQCH0DSC0DR 0x78c + #endif /* __RZG2L_MIPI_DSI_REGS_H__ */ diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c index 4202ab00fb0c..fd9460da1789 100644 --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c @@ -117,6 +117,7 @@ const struct shmob_drm_format_info *shmob_drm_format_info(u32 fourcc) static struct drm_framebuffer * shmob_drm_fb_create(struct drm_device *dev, struct drm_file *file_priv, + const struct drm_format_info *info, const struct drm_mode_fb_cmd2 *mode_cmd) { const struct shmob_drm_format_info *format; @@ -144,7 +145,7 @@ shmob_drm_fb_create(struct drm_device *dev, struct drm_file *file_priv, } } - return drm_gem_fb_create(dev, file_priv, mode_cmd); + return drm_gem_fb_create(dev, file_priv, info, mode_cmd); } static const struct drm_mode_config_funcs shmob_drm_mode_config_funcs = { |