diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-26 02:12:15 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-26 02:12:15 +0300 |
commit | c8cc58e289ed3b5bc50258f52776cf3dfa3bad66 (patch) | |
tree | fab95a9e92dd1b7ddec386294365ebd2ba130ec3 /drivers/gpu/drm/rockchip | |
parent | 736b378b29d89c8c3567fa4b2e948be5568aebb8 (diff) | |
parent | 289af45508ca890585f329376d16e08f41f75bd5 (diff) | |
download | linux-c8cc58e289ed3b5bc50258f52776cf3dfa3bad66.tar.xz |
Merge tag 'drm-next-2023-04-24' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"There is a new Qualcomm accel driver for their QAIC, dma-fence got a
deadline feature added, lots of refactoring around fbdev emulation,
and the usual pre-release hw enablements from AMD and Intel and fixes
everywhere.
New drivers:
- add QAIC acceleration driver
dma-buf:
- constify kobj_type structs
- Reject prime DMA-Buf attachment if get_sg_table is missing.
fbdev:
- cmdline parser fixes
- implement fbdev emulation for GEM DMA drivers
- always use shadow buffer in fbdev emulation helpers
dma-fence:
- add deadline hint to fences
- signal private stub fence
core:
- improve DisplayID 2.0 and EDID parsing
- add gem eviction function + callback
- prep to convert shmem helper to GEM resv lock
- move suballocator from radeon/amdgpu to core for Xe
- HPD polling fixes
- Documentation improvements
- Add atomic enable_plane callback
- use tgid instead of pid for client tracking
- DP: Add SDP Error Detection Configuration Register
- Add prime import/export to vram-helper
- use pci aperture helpers in more drivers
panel:
- Radxa 8/10HD support
- Samsung AMD495QA01 support
- Elida KD50T048A
- Sony TD4353
- Novatek NT36523
- STARRY 2081101QFH032011-53G
- B133UAN01.0
- AUO NE135FBM-N41
i915:
- More MTL enabling
- fix s/r problems with MEI/PXP
- Implement fb_dirty for PSR,FBC,DRRS fixes
- Fix eDP+DSI dual panel systems
- Fix issue #6333: "list_add corruption" and full system lockup from
performance monitoring
- Don't use stolen memory or BAR for ring buffers on LLC platforms
- Make sure DSM size has correct 1MiB granularity on Gen12+
- Whitelist COMMON_SLICE_CHICKEN3 for UMD access on Gen12+
- Add engine TLB invalidation for Meteorlake
- Fix GSC races on driver load/unload on Meteorlake+
- Make kobj_type structures constant
- Move fd_install after last use of fence
- wm/vblank refactoring
- display code refactoring
- Create GSC submission targeting HDCP and PXP usages on MTL+
- Enable HDCP2.x via GSC CS
- Fix context runtime accounting on sysfs fdinfo for heavy workloads
- Use i915 instead of dev_priv insied the file_priv structure
- Replace fake flex-array with flexible-array member
amdgpu:
- Make kobj structures const
- Generalize dmabuf import to work with KFD
- Add capped/uncapped workload handling for supported APUs
- Expose additional memory stats via fdinfo
- Register vga_switcheroo for apple-gmux
- Initial NBIO7.9, GC 9.4.3, GFXHUB 1.2, MMHUB 1.8 support
- Initial DC FAM infrastructure
- Link DC backlight to connector device rather than PCI device
- Add sysfs nodes for secondary VCN clocks
amdkfd:
- Make kobj structures const
- Support for exporting buffers via dmabuf
- Multi-VMA page migration fixes
- initial GC 9.4.3 support
radeon:
- iMac fix
- convert to client based fbdev emulation
habanalabs:
- Add opcodes to the CS ioctl to allow user to stall/resume specific
engines inside Gaudi2.
- INFO ioctl the amount of device memory that the driver and f/w
reserve for themselves.
- INFO ioctl a bit-mask of the available rotator engines
- INFO ioctl the register's address of the f/w that should be used to
trigger interrupts
- INFO ioctl two new opcodes to fetch information on h/w and f/w
events
- Enable graceful reset mechanism for compute-reset.
- Align to the latest firmware specs.
- Enforce the release order of the compute device and dma-buf.
msm:
- UBWC decoder programming rework
- SM8550, SM8450 bindings update
- uapi C++ fix
- a3xx and a4xx devfreq support
- GPU and GEM updates to avoid allocations which could trigger
reclaim (shrinker) in fence signaling path
- dma-fence deadline hint support and wait-boost
- a640/650 speed bin support
cirrus:
- convert to regular atomic helpers
- add damage clipping
mediatek:
- 10-bit overlay support
- mt8195 support
- Only trigger DRM HPD events if bridge is attached
- Change the aux retries times when receiving AUX_DEFER
rockchip:
- add 4K support
vc4:
- use drm_gem_objects
virtio:
- allow KMS support to be disabled
- add damage clipping
vmwgfx:
- buffer object lifetime fixes
exynos:
- move MIPI DSI driver to drm bridge for iMX sharing
- use kernel fbdev emulation
panfrost:
- add support for mali MT81xx devices
- add speed binning support
lima:
- add usage stats
tegra:
- fbdev client conversion
vkms:
- Add primary plane positioning support"
* tag 'drm-next-2023-04-24' of git://anongit.freedesktop.org/drm/drm: (1495 commits)
drm/i915/dp_mst: Fix active port PLL selection for secondary MST streams
drm/exynos: Implement fbdev emulation as in-kernel client
drm/exynos: Initialize fbdev DRM client
drm/exynos: Remove fb_helper from struct exynos_drm_private
drm/exynos: Remove struct exynos_drm_fbdev
drm/exynos: Remove exynos_gem from struct exynos_drm_fbdev
drm/i915: Fix memory leaks in i915 selftests
drm/i915: Make intel_get_crtc_new_encoder() less oopsy
drm/i915/gt: Avoid out-of-bounds access when loading HuC
drm/amdgpu: add some basic elements for multiple XCD case
drm/amdgpu: move vmhub out of amdgpu_ring_funcs (v4)
Revert "drm/amdgpu: enable ras for mp0 v13_0_10 on SRIOV"
drm/amdgpu: add common ip block for GC 9.4.3
drm/amd/display: Add logging when DP link training Clock recovery is Successful
drm/amdgpu: add common early init support for GC 9.4.3
drm/amdgpu: switch to v9_4_3 gfx_funcs callbacks for GC 9.4.3
drm/amd/display: Add logging when setting DP sink power state fails
drm/amdkfd: Add gfx_target_version for GC 9.4.3
drm/amdkfd: Enable HW_UPDATE_RPTR on GC 9.4.3
drm/amdgpu: reserve the old gc_11_0_*_mes.bin
...
Diffstat (limited to 'drivers/gpu/drm/rockchip')
-rw-r--r-- | drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 81 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_rgb.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_rgb.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 18 |
10 files changed, 162 insertions, 55 deletions
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c index 7901c3babc8c..917e79951aac 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -359,11 +359,6 @@ static inline void dsi_write(struct dw_mipi_dsi_rockchip *dsi, u32 reg, u32 val) writel(val, dsi->base + reg); } -static inline u32 dsi_read(struct dw_mipi_dsi_rockchip *dsi, u32 reg) -{ - return readl(dsi->base + reg); -} - static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi_rockchip *dsi, u8 test_code, u8 test_data) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 2f4b8f64cbad..112699949db9 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -74,6 +74,7 @@ struct rockchip_hdmi { struct regmap *regmap; struct rockchip_encoder encoder; const struct rockchip_hdmi_chip_data *chip_data; + const struct dw_hdmi_plat_data *plat_data; struct clk *ref_clk; struct clk *grf_clk; struct dw_hdmi *hdmi; @@ -161,6 +162,12 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { { 0x4064, 0x0003} }, }, { + 340000000, { + { 0x0040, 0x0003 }, + { 0x3b4c, 0x0003 }, + { 0x5a64, 0x0003 }, + }, + }, { ~0UL, { { 0x00a0, 0x000a }, { 0x2001, 0x000f }, @@ -186,6 +193,8 @@ static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { }, { 148500000, { 0x0000, 0x0038, 0x0038 }, }, { + 600000000, { 0x0000, 0x0000, 0x0000 }, + }, { ~0UL, { 0x0000, 0x0000, 0x0000}, } }; @@ -241,23 +250,39 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) } static enum drm_mode_status -dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data, +dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, const struct drm_display_info *info, const struct drm_display_mode *mode) { + struct rockchip_hdmi *hdmi = data; const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg; int pclk = mode->clock * 1000; - bool valid = false; + bool exact_match = hdmi->plat_data->phy_force_vendor; int i; + if (hdmi->ref_clk) { + int rpclk = clk_round_rate(hdmi->ref_clk, pclk); + + if (abs(rpclk - pclk) > pclk / 1000) + return MODE_NOCLOCK; + } + for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) { - if (pclk == mpll_cfg[i].mpixelclock) { - valid = true; - break; - } + /* + * For vendor specific phys force an exact match of the pixelclock + * to preserve the original behaviour of the driver. + */ + if (exact_match && pclk == mpll_cfg[i].mpixelclock) + return MODE_OK; + /* + * The Synopsys phy can work with pixelclocks up to the value given + * in the corresponding mpll_cfg entry. + */ + if (!exact_match && pclk <= mpll_cfg[i].mpixelclock) + return MODE_OK; } - return (valid) ? MODE_OK : MODE_BAD; + return MODE_BAD; } static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) @@ -546,8 +571,10 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, return -ENOMEM; hdmi->dev = &pdev->dev; + hdmi->plat_data = plat_data; hdmi->chip_data = plat_data->phy_data; plat_data->phy_data = hdmi; + plat_data->priv_data = hdmi; encoder = &hdmi->encoder.encoder; encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); @@ -640,6 +667,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); dw_hdmi_unbind(hdmi->hdmi); + drm_encoder_cleanup(&hdmi->encoder.encoder); clk_disable_unprepare(hdmi->ref_clk); regulator_disable(hdmi->avdd_1v8); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index 8ea09d915c3c..b8f8b45ebf59 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -261,9 +261,6 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj, else ret = rockchip_drm_gem_object_mmap_dma(obj, vma); - if (ret) - drm_gem_vm_close(vma); - return ret; } @@ -518,8 +515,14 @@ int rockchip_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); if (rk_obj->pages) { - void *vaddr = vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP, - pgprot_writecombine(PAGE_KERNEL)); + void *vaddr; + + if (rk_obj->kvaddr) + vaddr = rk_obj->kvaddr; + else + vaddr = vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP, + pgprot_writecombine(PAGE_KERNEL)); + if (!vaddr) return -ENOMEM; iosys_map_set_vaddr(map, vaddr); @@ -539,7 +542,8 @@ void rockchip_gem_prime_vunmap(struct drm_gem_object *obj, struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); if (rk_obj->pages) { - vunmap(map->vaddr); + if (map->vaddr != rk_obj->kvaddr) + vunmap(map->vaddr); return; } diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index fa1f4ee6d195..d8f5e064a1ba 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -316,13 +316,10 @@ static int vop_convert_afbc_format(uint32_t format) case DRM_FORMAT_RGB565: case DRM_FORMAT_BGR565: return AFBC_FMT_RGB565; - /* either of the below should not be reachable */ default: - DRM_WARN_ONCE("unsupported AFBC format[%08x]\n", format); + DRM_DEBUG_KMS("unsupported AFBC format[%08x]\n", format); return -EINVAL; } - - return -EINVAL; } static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src, @@ -1174,6 +1171,17 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc) spin_unlock_irqrestore(&vop->irq_lock, flags); } +static enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) +{ + struct vop *vop = to_vop(crtc); + + if (vop->data->max_output.width && mode->hdisplay > vop->data->max_output.width) + return MODE_BAD_HVALUE; + + return MODE_OK; +} + static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -1585,6 +1593,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc, } static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = { + .mode_valid = vop_crtc_mode_valid, .mode_fixup = vop_crtc_mode_fixup, .atomic_check = vop_crtc_atomic_check, .atomic_begin = vop_crtc_atomic_begin, @@ -2221,7 +2230,7 @@ static int vop_bind(struct device *dev, struct device *master, void *data) goto err_disable_pm_runtime; if (vop->data->feature & VOP_FEATURE_INTERNAL_RGB) { - vop->rgb = rockchip_rgb_init(dev, &vop->crtc, vop->drm_dev); + vop->rgb = rockchip_rgb_init(dev, &vop->crtc, vop->drm_dev, 0); if (IS_ERR(vop->rgb)) { ret = PTR_ERR(vop->rgb); goto err_disable_pm_runtime; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index 8502849833d9..5f56e0597df8 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -42,6 +42,11 @@ enum vop_data_format { VOP_FMT_YUV444SP, }; +struct vop_rect { + int width; + int height; +}; + struct vop_reg { uint32_t mask; uint16_t offset; @@ -225,6 +230,7 @@ struct vop_data { const struct vop_win_data *win; unsigned int win_size; unsigned int lut_size; + struct vop_rect max_output; #define VOP_FEATURE_OUTPUT_RGB10 BIT(0) #define VOP_FEATURE_INTERNAL_RGB BIT(1) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 293c228a83f9..ca73b8ccc29f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -38,6 +38,7 @@ #include "rockchip_drm_gem.h" #include "rockchip_drm_fb.h" #include "rockchip_drm_vop2.h" +#include "rockchip_rgb.h" /* * VOP2 architecture @@ -211,6 +212,9 @@ struct vop2 { struct clk *hclk; struct clk *aclk; + /* optional internal rgb encoder */ + struct rockchip_rgb *rgb; + /* must be put at the end of the struct */ struct vop2_win win[]; }; @@ -1438,6 +1442,8 @@ static void rk3568_set_intf_mux(struct vop2_video_port *vp, int id, die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX; die |= RK3568_SYS_DSP_INFACE_EN_RGB | FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id); + dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL; + dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags); if (polflags & POLFLAG_DCLK_INV) regmap_write(vop2->grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3)); else @@ -2249,7 +2255,7 @@ static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2) #define NR_LAYERS 6 -static int vop2_create_crtc(struct vop2 *vop2) +static int vop2_create_crtcs(struct vop2 *vop2) { const struct vop2_data *vop2_data = vop2->data; struct drm_device *drm = vop2->drm; @@ -2299,7 +2305,7 @@ static int vop2_create_crtc(struct vop2 *vop2) nvp = 0; for (i = 0; i < vop2->registered_num_wins; i++) { struct vop2_win *win = &vop2->win[i]; - u32 possible_crtcs; + u32 possible_crtcs = 0; if (vop2->data->soc_id == 3566) { /* @@ -2374,15 +2380,44 @@ static int vop2_create_crtc(struct vop2 *vop2) return 0; } -static void vop2_destroy_crtc(struct drm_crtc *crtc) +static void vop2_destroy_crtcs(struct vop2 *vop2) { - of_node_put(crtc->port); + struct drm_device *drm = vop2->drm; + struct list_head *crtc_list = &drm->mode_config.crtc_list; + struct list_head *plane_list = &drm->mode_config.plane_list; + struct drm_crtc *crtc, *tmpc; + struct drm_plane *plane, *tmpp; + + list_for_each_entry_safe(plane, tmpp, plane_list, head) + drm_plane_cleanup(plane); /* * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane() * references the CRTC. */ - drm_crtc_cleanup(crtc); + list_for_each_entry_safe(crtc, tmpc, crtc_list, head) { + of_node_put(crtc->port); + drm_crtc_cleanup(crtc); + } +} + +static int vop2_find_rgb_encoder(struct vop2 *vop2) +{ + struct device_node *node = vop2->dev->of_node; + struct device_node *endpoint; + int i; + + for (i = 0; i < vop2->data->nr_vps; i++) { + endpoint = of_graph_get_endpoint_by_regs(node, i, + ROCKCHIP_VOP2_EP_RGB0); + if (!endpoint) + continue; + + of_node_put(endpoint); + return i; + } + + return -ENOENT; } static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = { @@ -2625,7 +2660,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) return -ENODEV; /* Allocate vop2 struct and its vop2_win array */ - alloc_size = sizeof(*vop2) + sizeof(*vop2->win) * vop2_data->win_size; + alloc_size = struct_size(vop2, win, vop2_data->win_size); vop2 = devm_kzalloc(dev, alloc_size, GFP_KERNEL); if (!vop2) return -ENOMEM; @@ -2648,6 +2683,8 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) vop2->len = resource_size(res); vop2->map = devm_regmap_init_mmio(dev, vop2->regs, &vop2_regmap_config); + if (IS_ERR(vop2->map)) + return PTR_ERR(vop2->map); ret = vop2_win_init(vop2); if (ret) @@ -2686,33 +2723,45 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - ret = vop2_create_crtc(vop2); + ret = vop2_create_crtcs(vop2); if (ret) return ret; + ret = vop2_find_rgb_encoder(vop2); + if (ret >= 0) { + vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc, + vop2->drm, ret); + if (IS_ERR(vop2->rgb)) { + if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) { + ret = PTR_ERR(vop2->rgb); + goto err_crtcs; + } + vop2->rgb = NULL; + } + } + rockchip_drm_dma_init_device(vop2->drm, vop2->dev); pm_runtime_enable(&pdev->dev); return 0; + +err_crtcs: + vop2_destroy_crtcs(vop2); + + return ret; } static void vop2_unbind(struct device *dev, struct device *master, void *data) { struct vop2 *vop2 = dev_get_drvdata(dev); - struct drm_device *drm = vop2->drm; - struct list_head *plane_list = &drm->mode_config.plane_list; - struct list_head *crtc_list = &drm->mode_config.crtc_list; - struct drm_crtc *crtc, *tmpc; - struct drm_plane *plane, *tmpp; pm_runtime_disable(dev); - list_for_each_entry_safe(plane, tmpp, plane_list, head) - drm_plane_cleanup(plane); + if (vop2->rgb) + rockchip_rgb_fini(vop2->rgb); - list_for_each_entry_safe(crtc, tmpc, crtc_list, head) - vop2_destroy_crtc(crtc); + vop2_destroy_crtcs(vop2); } const struct component_ops vop2_component_ops = { diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h index c727093a06d6..f1234a151130 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h @@ -27,11 +27,6 @@ enum win_dly_mode { VOP2_DLY_MODE_MAX, }; -struct vop_rect { - int width; - int height; -}; - enum vop2_scale_up_mode { VOP2_SCALE_UP_NRST_NBOR, VOP2_SCALE_UP_BIL, diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c index 75eb7cca3d82..c677b71ae516 100644 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.c +++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c @@ -22,13 +22,11 @@ #include "rockchip_drm_vop.h" #include "rockchip_rgb.h" -#define encoder_to_rgb(c) container_of(c, struct rockchip_rgb, encoder) - struct rockchip_rgb { struct device *dev; struct drm_device *drm_dev; struct drm_bridge *bridge; - struct drm_encoder encoder; + struct rockchip_encoder encoder; struct drm_connector connector; int output_mode; }; @@ -74,7 +72,8 @@ struct drm_encoder_helper_funcs rockchip_rgb_encoder_helper_funcs = { struct rockchip_rgb *rockchip_rgb_init(struct device *dev, struct drm_crtc *crtc, - struct drm_device *drm_dev) + struct drm_device *drm_dev, + int video_port) { struct rockchip_rgb *rgb; struct drm_encoder *encoder; @@ -92,7 +91,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, rgb->dev = dev; rgb->drm_dev = drm_dev; - port = of_graph_get_port_by_id(dev->of_node, 0); + port = of_graph_get_port_by_id(dev->of_node, video_port); if (!port) return ERR_PTR(-EINVAL); @@ -105,8 +104,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, continue; child_count++; - ret = drm_of_find_panel_or_bridge(dev->of_node, 0, endpoint_id, - &panel, &bridge); + ret = drm_of_find_panel_or_bridge(dev->of_node, video_port, + endpoint_id, &panel, &bridge); if (!ret) { of_node_put(endpoint); break; @@ -125,7 +124,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, return ERR_PTR(ret); } - encoder = &rgb->encoder; + encoder = &rgb->encoder.encoder; encoder->possible_crtcs = drm_crtc_mask(crtc); ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_NONE); @@ -161,6 +160,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, goto err_free_encoder; } + rgb->encoder.crtc_endpoint_id = endpoint_id; + ret = drm_connector_attach_encoder(connector, encoder); if (ret < 0) { DRM_DEV_ERROR(drm_dev->dev, @@ -182,6 +183,6 @@ void rockchip_rgb_fini(struct rockchip_rgb *rgb) { drm_panel_bridge_remove(rgb->bridge); drm_connector_cleanup(&rgb->connector); - drm_encoder_cleanup(&rgb->encoder); + drm_encoder_cleanup(&rgb->encoder.encoder); } EXPORT_SYMBOL_GPL(rockchip_rgb_fini); diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.h b/drivers/gpu/drm/rockchip/rockchip_rgb.h index 27b9635124bc..1bd4e20e91eb 100644 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.h +++ b/drivers/gpu/drm/rockchip/rockchip_rgb.h @@ -8,12 +8,14 @@ #ifdef CONFIG_ROCKCHIP_RGB struct rockchip_rgb *rockchip_rgb_init(struct device *dev, struct drm_crtc *crtc, - struct drm_device *drm_dev); + struct drm_device *drm_dev, + int video_port); void rockchip_rgb_fini(struct rockchip_rgb *rgb); #else static inline struct rockchip_rgb *rockchip_rgb_init(struct device *dev, struct drm_crtc *crtc, - struct drm_device *drm_dev) + struct drm_device *drm_dev, + int video_port) { return NULL; } diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 014f99e8928e..20ac7811c5eb 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -181,6 +181,7 @@ static const struct vop_data rk3036_vop = { .output = &rk3036_output, .win = rk3036_vop_win_data, .win_size = ARRAY_SIZE(rk3036_vop_win_data), + .max_output = { 1920, 1080 }, }; static const struct vop_win_phy rk3126_win1_data = { @@ -213,6 +214,7 @@ static const struct vop_data rk3126_vop = { .output = &rk3036_output, .win = rk3126_vop_win_data, .win_size = ARRAY_SIZE(rk3126_vop_win_data), + .max_output = { 1920, 1080 }, }; static const int px30_vop_intrs[] = { @@ -340,6 +342,7 @@ static const struct vop_data px30_vop_big = { .output = &px30_output, .win = px30_vop_big_win_data, .win_size = ARRAY_SIZE(px30_vop_big_win_data), + .max_output = { 1920, 1080 }, }; static const struct vop_win_data px30_vop_lit_win_data[] = { @@ -356,6 +359,7 @@ static const struct vop_data px30_vop_lit = { .output = &px30_output, .win = px30_vop_lit_win_data, .win_size = ARRAY_SIZE(px30_vop_lit_win_data), + .max_output = { 1920, 1080 }, }; static const struct vop_scl_regs rk3066_win_scl = { @@ -479,6 +483,7 @@ static const struct vop_data rk3066_vop = { .output = &rk3066_output, .win = rk3066_vop_win_data, .win_size = ARRAY_SIZE(rk3066_vop_win_data), + .max_output = { 1920, 1080 }, }; static const struct vop_scl_regs rk3188_win_scl = { @@ -585,6 +590,7 @@ static const struct vop_data rk3188_vop = { .win = rk3188_vop_win_data, .win_size = ARRAY_SIZE(rk3188_vop_win_data), .feature = VOP_FEATURE_INTERNAL_RGB, + .max_output = { 2048, 1536 }, }; static const struct vop_scl_extension rk3288_win_full_scl_ext = { @@ -732,6 +738,12 @@ static const struct vop_data rk3288_vop = { .win = rk3288_vop_win_data, .win_size = ARRAY_SIZE(rk3288_vop_win_data), .lut_size = 1024, + /* + * This is the maximum resolution for the VOPB, the VOPL can only do + * 2560x1600, but we can't distinguish them as they have the same + * compatible. + */ + .max_output = { 3840, 2160 }, }; static const int rk3368_vop_intrs[] = { @@ -833,6 +845,7 @@ static const struct vop_data rk3368_vop = { .misc = &rk3368_misc, .win = rk3368_vop_win_data, .win_size = ARRAY_SIZE(rk3368_vop_win_data), + .max_output = { 4096, 2160 }, }; static const struct vop_intr rk3366_vop_intr = { @@ -854,6 +867,7 @@ static const struct vop_data rk3366_vop = { .misc = &rk3368_misc, .win = rk3368_vop_win_data, .win_size = ARRAY_SIZE(rk3368_vop_win_data), + .max_output = { 4096, 2160 }, }; static const struct vop_output rk3399_output = { @@ -984,6 +998,7 @@ static const struct vop_data rk3399_vop_big = { .win_size = ARRAY_SIZE(rk3399_vop_win_data), .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data, .lut_size = 1024, + .max_output = { 4096, 2160 }, }; static const struct vop_win_data rk3399_vop_lit_win_data[] = { @@ -1010,6 +1025,7 @@ static const struct vop_data rk3399_vop_lit = { .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data), .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data, .lut_size = 256, + .max_output = { 2560, 1600 }, }; static const struct vop_win_data rk3228_vop_win_data[] = { @@ -1029,6 +1045,7 @@ static const struct vop_data rk3228_vop = { .misc = &rk3368_misc, .win = rk3228_vop_win_data, .win_size = ARRAY_SIZE(rk3228_vop_win_data), + .max_output = { 4096, 2160 }, }; static const struct vop_modeset rk3328_modeset = { @@ -1100,6 +1117,7 @@ static const struct vop_data rk3328_vop = { .misc = &rk3328_misc, .win = rk3328_vop_win_data, .win_size = ARRAY_SIZE(rk3328_vop_win_data), + .max_output = { 4096, 2160 }, }; static const struct of_device_id vop_driver_dt_match[] = { |