drm/tegra: Update to Linux v6.16-rc1

Update the Tegra DRM driver to Linux v6.16-rc1. In Linux v6.16-rc1, the
drm_dp_link_power_up/down functions were moved from the Tegra DRM driver
into the main DRM code. Conftest is used to detect this change and the
appropriate updates are made to the Tegra DRM driver.

JIRA LINQPJ14-60

Change-Id: Id5449b22e8eda5ee70eb6aed09ce627e63e7722e
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3375214
(cherry picked from commit f8adc0c950eb4905d397b6e1d8e524b856945f0e)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3461883
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: Brad Griffis <bgriffis@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Jon Hunter
2025-06-11 09:44:44 +01:00
committed by mobile promotions
parent da9c8f46c4
commit e004561637
14 changed files with 83 additions and 22 deletions

View File

@@ -1329,10 +1329,16 @@ static struct drm_plane *tegra_dc_add_shared_planes(struct drm_device *drm,
if (wgrp->dc == dc->pipe) { if (wgrp->dc == dc->pipe) {
for (j = 0; j < wgrp->num_windows; j++) { for (j = 0; j < wgrp->num_windows; j++) {
unsigned int index = wgrp->windows[j]; unsigned int index = wgrp->windows[j];
enum drm_plane_type type;
if (primary)
type = DRM_PLANE_TYPE_OVERLAY;
else
type = DRM_PLANE_TYPE_PRIMARY;
plane = tegra_shared_plane_create(drm, dc, plane = tegra_shared_plane_create(drm, dc,
wgrp->index, wgrp->index,
index); index, type);
if (IS_ERR(plane)) if (IS_ERR(plane))
return plane; return plane;
@@ -1340,13 +1346,11 @@ static struct drm_plane *tegra_dc_add_shared_planes(struct drm_device *drm,
* Choose the first shared plane owned by this * Choose the first shared plane owned by this
* head as the primary plane. * head as the primary plane.
*/ */
if (!primary) { if (!primary)
plane->type = DRM_PLANE_TYPE_PRIMARY;
primary = plane; primary = plane;
} }
} }
} }
}
return primary; return primary;
} }
@@ -1397,7 +1401,10 @@ static void tegra_crtc_reset(struct drm_crtc *crtc)
if (crtc->state) if (crtc->state)
tegra_crtc_atomic_destroy_state(crtc, crtc->state); tegra_crtc_atomic_destroy_state(crtc, crtc->state);
if (state)
__drm_atomic_helper_crtc_reset(crtc, &state->base); __drm_atomic_helper_crtc_reset(crtc, &state->base);
else
__drm_atomic_helper_crtc_reset(crtc, NULL);
} }
static struct drm_crtc_state * static struct drm_crtc_state *

View File

@@ -263,6 +263,7 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
return 0; return 0;
} }
#if !defined(NV_DRM_DP_LINK_POWER_UP_PRESENT) /* Linux v6.16 */
/** /**
* drm_dp_link_power_up() - power up a DisplayPort link * drm_dp_link_power_up() - power up a DisplayPort link
* @aux: DisplayPort AUX channel * @aux: DisplayPort AUX channel
@@ -329,6 +330,7 @@ int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link)
return 0; return 0;
} }
#endif /* NV_DRM_DP_LINK_POWER_UP_PRESENT */
/** /**
* drm_dp_link_configure() - configure a DisplayPort link * drm_dp_link_configure() - configure a DisplayPort link

View File

@@ -164,8 +164,10 @@ int drm_dp_link_remove_rate(struct drm_dp_link *link, unsigned long rate);
void drm_dp_link_update_rates(struct drm_dp_link *link); void drm_dp_link_update_rates(struct drm_dp_link *link);
int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link);
#if !defined(NV_DRM_DP_LINK_POWER_UP_PRESENT) /* Linux v6.16 */
int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link);
int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link);
#endif
int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link);
int drm_dp_link_choose(struct drm_dp_link *link, int drm_dp_link_choose(struct drm_dp_link *link,
const struct drm_display_mode *mode, const struct drm_display_mode *mode,

View File

@@ -516,14 +516,9 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd"); dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
if (IS_ERR(dpaux->vdd)) { if (IS_ERR(dpaux->vdd)) {
if (PTR_ERR(dpaux->vdd) != -ENODEV) { if (PTR_ERR(dpaux->vdd) != -ENODEV)
if (PTR_ERR(dpaux->vdd) != -EPROBE_DEFER) return dev_err_probe(&pdev->dev, PTR_ERR(dpaux->vdd),
dev_err(&pdev->dev, "failed to get VDD supply\n");
"failed to get VDD supply: %ld\n",
PTR_ERR(dpaux->vdd));
return PTR_ERR(dpaux->vdd);
}
dpaux->vdd = NULL; dpaux->vdd = NULL;
} }

View File

@@ -1576,7 +1576,6 @@ static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi)
static int tegra_dsi_probe(struct platform_device *pdev) static int tegra_dsi_probe(struct platform_device *pdev)
{ {
struct tegra_dsi *dsi; struct tegra_dsi *dsi;
struct resource *regs;
int err; int err;
dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL); dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
@@ -1648,8 +1647,7 @@ static int tegra_dsi_probe(struct platform_device *pdev)
goto remove; goto remove;
} }
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); dsi->regs = devm_platform_ioremap_resource(pdev, 0);
dsi->regs = devm_ioremap_resource(&pdev->dev, regs);
if (IS_ERR(dsi->regs)) { if (IS_ERR(dsi->regs)) {
err = PTR_ERR(dsi->regs); err = PTR_ERR(dsi->regs);
goto remove; goto remove;

View File

@@ -30,6 +30,14 @@ int falcon_wait_idle(struct falcon *falcon)
(value == 0), 10, 100000); (value == 0), 10, 100000);
} }
static int falcon_dma_wait_not_full(struct falcon *falcon)
{
u32 value;
return readl_poll_timeout(falcon->regs + FALCON_DMATRFCMD, value,
!(value & FALCON_DMATRFCMD_FULL), 10, 100000);
}
static int falcon_dma_wait_idle(struct falcon *falcon) static int falcon_dma_wait_idle(struct falcon *falcon)
{ {
u32 value; u32 value;
@@ -44,6 +52,7 @@ static int falcon_copy_chunk(struct falcon *falcon,
enum falcon_memory target) enum falcon_memory target)
{ {
u32 cmd = FALCON_DMATRFCMD_SIZE_256B; u32 cmd = FALCON_DMATRFCMD_SIZE_256B;
int err;
if (target == FALCON_MEMORY_IMEM) if (target == FALCON_MEMORY_IMEM)
cmd |= FALCON_DMATRFCMD_IMEM; cmd |= FALCON_DMATRFCMD_IMEM;
@@ -56,11 +65,15 @@ static int falcon_copy_chunk(struct falcon *falcon,
*/ */
cmd |= FALCON_DMATRFCMD_DMACTX(1); cmd |= FALCON_DMATRFCMD_DMACTX(1);
err = falcon_dma_wait_not_full(falcon);
if (err < 0)
return err;
falcon_writel(falcon, offset, FALCON_DMATRFMOFFS); falcon_writel(falcon, offset, FALCON_DMATRFMOFFS);
falcon_writel(falcon, base, FALCON_DMATRFFBOFFS); falcon_writel(falcon, base, FALCON_DMATRFFBOFFS);
falcon_writel(falcon, cmd, FALCON_DMATRFCMD); falcon_writel(falcon, cmd, FALCON_DMATRFCMD);
return falcon_dma_wait_idle(falcon); return 0;
} }
static void falcon_copy_firmware_image(struct falcon *falcon, static void falcon_copy_firmware_image(struct falcon *falcon,
@@ -191,6 +204,11 @@ int falcon_boot(struct falcon *falcon)
falcon_copy_chunk(falcon, falcon->firmware.code.offset + offset, falcon_copy_chunk(falcon, falcon->firmware.code.offset + offset,
offset, FALCON_MEMORY_IMEM); offset, FALCON_MEMORY_IMEM);
/* wait for DMA to complete */
err = falcon_dma_wait_idle(falcon);
if (err < 0)
return err;
/* setup falcon interrupts */ /* setup falcon interrupts */
falcon_writel(falcon, FALCON_IRQMSET_EXT(0xff) | falcon_writel(falcon, FALCON_IRQMSET_EXT(0xff) |
FALCON_IRQMSET_SWGEN1 | FALCON_IRQMSET_SWGEN1 |

View File

@@ -47,6 +47,7 @@
#define FALCON_DMATRFMOFFS 0x00001114 #define FALCON_DMATRFMOFFS 0x00001114
#define FALCON_DMATRFCMD 0x00001118 #define FALCON_DMATRFCMD 0x00001118
#define FALCON_DMATRFCMD_FULL (1 << 0)
#define FALCON_DMATRFCMD_IDLE (1 << 1) #define FALCON_DMATRFCMD_IDLE (1 << 1)
#define FALCON_DMATRFCMD_IMEM (1 << 4) #define FALCON_DMATRFCMD_IMEM (1 << 4)
#define FALCON_DMATRFCMD_SIZE_256B (6 << 8) #define FALCON_DMATRFCMD_SIZE_256B (6 << 8)

View File

@@ -19,7 +19,6 @@
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_prime.h> #include <drm/drm_prime.h>
#include <drm/tegra_drm.h>
#include "drm.h" #include "drm.h"
#include "gem.h" #include "gem.h"

View File

@@ -757,9 +757,9 @@ static const struct drm_plane_helper_funcs tegra_shared_plane_helper_funcs = {
struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, struct drm_plane *tegra_shared_plane_create(struct drm_device *drm,
struct tegra_dc *dc, struct tegra_dc *dc,
unsigned int wgrp, unsigned int wgrp,
unsigned int index) unsigned int index,
enum drm_plane_type type)
{ {
enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY;
struct tegra_drm *tegra = drm->dev_private; struct tegra_drm *tegra = drm->dev_private;
struct tegra_display_hub *hub = tegra->hub; struct tegra_display_hub *hub = tegra->hub;
struct tegra_shared_plane *plane; struct tegra_shared_plane *plane;

View File

@@ -80,7 +80,8 @@ void tegra_display_hub_cleanup(struct tegra_display_hub *hub);
struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, struct drm_plane *tegra_shared_plane_create(struct drm_device *drm,
struct tegra_dc *dc, struct tegra_dc *dc,
unsigned int wgrp, unsigned int wgrp,
unsigned int index); unsigned int index,
enum drm_plane_type type);
int tegra_display_hub_atomic_check(struct drm_device *drm, int tegra_display_hub_atomic_check(struct drm_device *drm,
struct drm_atomic_state *state); struct drm_atomic_state *state);

View File

@@ -200,6 +200,11 @@ static const struct drm_encoder_helper_funcs tegra_rgb_encoder_helper_funcs = {
.atomic_check = tegra_rgb_encoder_atomic_check, .atomic_check = tegra_rgb_encoder_atomic_check,
}; };
static void tegra_dc_of_node_put(void *data)
{
of_node_put(data);
}
int tegra_dc_rgb_probe(struct tegra_dc *dc) int tegra_dc_rgb_probe(struct tegra_dc *dc)
{ {
struct device_node *np; struct device_node *np;
@@ -207,7 +212,14 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
int err; int err;
np = of_get_child_by_name(dc->dev->of_node, "rgb"); np = of_get_child_by_name(dc->dev->of_node, "rgb");
if (!np || !of_device_is_available(np)) if (!np)
return -ENODEV;
err = devm_add_action_or_reset(dc->dev, tegra_dc_of_node_put, np);
if (err < 0)
return err;
if (!of_device_is_available(np))
return -ENODEV; return -ENODEV;
rgb = devm_kzalloc(dc->dev, sizeof(*rgb), GFP_KERNEL); rgb = devm_kzalloc(dc->dev, sizeof(*rgb), GFP_KERNEL);

View File

@@ -2712,7 +2712,11 @@ static void tegra_sor_dp_disable(struct drm_encoder *encoder)
* the AUX transactions would just be timing out. * the AUX transactions would just be timing out.
*/ */
if (output->connector.status != connector_status_disconnected) { if (output->connector.status != connector_status_disconnected) {
#if defined(NV_DRM_DP_LINK_POWER_UP_PRESENT) /* Linux v6.16 */
err = drm_dp_link_power_down(sor->aux, sor->link.revision);
#else
err = drm_dp_link_power_down(sor->aux, &sor->link); err = drm_dp_link_power_down(sor->aux, &sor->link);
#endif
if (err < 0) if (err < 0)
dev_err(sor->dev, "failed to power down link: %d\n", dev_err(sor->dev, "failed to power down link: %d\n",
err); err);
@@ -2928,7 +2932,11 @@ static void tegra_sor_dp_enable(struct drm_encoder *encoder)
else else
dev_dbg(sor->dev, "link training succeeded\n"); dev_dbg(sor->dev, "link training succeeded\n");
#if defined(NV_DRM_DP_LINK_POWER_UP_PRESENT) /* Linux v6.16 */
err = drm_dp_link_power_up(sor->aux, sor->link.revision);
#else
err = drm_dp_link_power_up(sor->aux, &sor->link); err = drm_dp_link_power_up(sor->aux, &sor->link);
#endif
if (err < 0) if (err < 0)
dev_err(sor->dev, "failed to power up DP link: %d\n", err); dev_err(sor->dev, "failed to power up DP link: %d\n", err);

View File

@@ -129,6 +129,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_connector_helper_funcs_struct_mode_val
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_connector_has_override_edid NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_connector_has_override_edid
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_debugfs_remove_files_has_root_arg NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_debugfs_remove_files_has_root_arg
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_display_info_struct_has_source_physical_address NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_display_info_struct_has_source_physical_address
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_dp_link_power_up
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_driver_has_fbdev_probe NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_driver_has_fbdev_probe
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_driver_struct_has_date NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_driver_struct_has_date
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_driver_struct_has_irq_enabled_arg NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_driver_struct_has_irq_enabled_arg

View File

@@ -7217,6 +7217,23 @@ compile_test() {
compile_check_conftest "$CODE" "NV_DRM_DISPLAY_INFO_STRUCT_HAS_SOURCE_PHYSICAL_ADDRESS" "" "types" compile_check_conftest "$CODE" "NV_DRM_DISPLAY_INFO_STRUCT_HAS_SOURCE_PHYSICAL_ADDRESS" "" "types"
;; ;;
drm_dp_link_power_up)
#
# Determine if the function drm_dp_link_power_up is present
#
# This change was made in Linux v6.16 by commit 09cdda7a60f4 ("drm/dp: Pull
# drm_dp_link_power_up/down from Tegra to common drm_dp_helper").
#
CODE="
#undef CONFIG_ACPI
#include <drm/display/drm_dp_helper.h>
int conftest_drm_dp_link_power_up(void) {
drm_dp_link_power_up();
}"
compile_check_conftest "$CODE" "NV_DRM_DP_LINK_POWER_UP_PRESENT" "" "functions"
;;
drm_driver_has_fbdev_probe) drm_driver_has_fbdev_probe)
# #
# Determine if the 'drm_driver' structure has an 'fbdev_probe' # Determine if the 'drm_driver' structure has an 'fbdev_probe'