diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 179c8ac0..8783dca3 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -2397,7 +2398,6 @@ static int tegra_crtc_calculate_memory_bandwidth(struct drm_crtc *crtc, const struct tegra_plane_state *tegra_state; const struct drm_plane_state *plane_state; struct tegra_dc *dc = to_tegra_dc(crtc); - const struct drm_crtc_state *old_state; struct drm_crtc_state *new_state; struct tegra_plane *tegra; struct drm_plane *plane; @@ -2412,7 +2412,6 @@ static int tegra_crtc_calculate_memory_bandwidth(struct drm_crtc *crtc, return 0; new_state = drm_atomic_get_new_crtc_state(state, crtc); - old_state = drm_atomic_get_old_crtc_state(state, crtc); /* * For overlapping planes pixel's data is fetched for each plane at diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index e678e655..fec6386d 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -10,8 +10,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -462,7 +462,6 @@ static const struct pinmux_ops tegra_dpaux_pinmux_ops = { static int tegra_dpaux_probe(struct platform_device *pdev) { struct tegra_dpaux *dpaux; - struct resource *regs; u32 value; int err; @@ -476,14 +475,13 @@ static int tegra_dpaux_probe(struct platform_device *pdev) INIT_LIST_HEAD(&dpaux->list); dpaux->dev = &pdev->dev; - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dpaux->regs = devm_ioremap_resource(&pdev->dev, regs); + dpaux->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(dpaux->regs)) return PTR_ERR(dpaux->regs); dpaux->irq = platform_get_irq(pdev, 0); if (dpaux->irq < 0) - return -ENXIO; + return dpaux->irq; if (!pdev->dev.pm_domain) { dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux"); @@ -613,7 +611,6 @@ static int tegra_dpaux_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM static int tegra_dpaux_suspend(struct device *dev) { struct tegra_dpaux *dpaux = dev_get_drvdata(dev); @@ -672,10 +669,9 @@ disable_clk: clk_disable_unprepare(dpaux->clk); return err; } -#endif static const struct dev_pm_ops tegra_dpaux_pm_ops = { - SET_RUNTIME_PM_OPS(tegra_dpaux_suspend, tegra_dpaux_resume, NULL) + RUNTIME_PM_OPS(tegra_dpaux_suspend, tegra_dpaux_resume, NULL) }; static const struct tegra_dpaux_soc tegra124_dpaux_soc = { @@ -721,7 +717,7 @@ struct platform_driver tegra_dpaux_driver = { .driver = { .name = "tegra-dpaux", .of_match_table = tegra_dpaux_of_match, - .pm = &tegra_dpaux_pm_ops, + .pm = pm_ptr(&tegra_dpaux_pm_ops), }, .probe = tegra_dpaux_probe, .remove = tegra_dpaux_remove_wrapper, diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index d2adad60..f84e8928 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -814,7 +814,8 @@ int host1x_client_iommu_attach(struct host1x_client *client) * not the shared IOMMU domain, don't try to attach it to a different * domain. This allows using the IOMMU-backed DMA API. */ - if (domain && domain != tegra->domain) + if (domain && domain->type != IOMMU_DOMAIN_IDENTITY && + domain != tegra->domain) return 0; if (tegra->domain) { @@ -984,6 +985,10 @@ static bool host1x_drm_wants_iommu(struct host1x_device *dev) struct host1x *host1x = dev_get_drvdata(dev->dev.parent); struct iommu_domain *domain; + /* Our IOMMU usage policy doesn't currently play well with GART */ + if (of_machine_is_compatible("nvidia,tegra20")) + return false; + /* * If the Tegra DRM clients are backed by an IOMMU, push buffers are * likely to be allocated beyond the 32-bit boundary if sufficient @@ -1161,6 +1166,15 @@ static int host1x_drm_probe(struct host1x_device *dev) drm_mode_config_reset(drm); + /* + * Only take over from a potential firmware framebuffer if any CRTCs + * have been registered. This must not be a fatal error because there + * are other accelerators that are exposed via this driver. + * + * Another case where this happens is on Tegra234 where the display + * hardware is no longer part of the host1x complex, so this driver + * will not expose any modesetting features. + */ if (drm->mode_config.num_crtc > 0) { #if defined(NV_APERTURE_REMOVE_ALL_CONFLICTING_DEVICES_PRESENT) /* Linux v6.0 */ err = aperture_remove_all_conflicting_devices(tegra_drm_driver.name); @@ -1173,6 +1187,12 @@ static int host1x_drm_probe(struct host1x_device *dev) #endif if (err < 0) goto hub; + } else { + /* + * Indicate to userspace that this doesn't expose any display + * capabilities. + */ + drm->driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC); } err = drm_dev_register(drm, 0); diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index fd74e667..76223b78 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -138,9 +138,6 @@ int tegra_drm_unregister_client(struct tegra_drm *tegra, int host1x_client_iommu_attach(struct host1x_client *client); void host1x_client_iommu_detach(struct host1x_client *client); -int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm); -int tegra_drm_exit(struct tegra_drm *tegra); - void *tegra_drm_alloc(struct tegra_drm *tegra, size_t size, dma_addr_t *iova); void tegra_drm_free(struct tegra_drm *tegra, size_t size, void *virt, dma_addr_t iova); diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 382273f0..c4e94d6c 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -920,6 +920,15 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) u32 value; int err; + /* If the bootloader enabled DSI it needs to be disabled + * in order for the panel initialization commands to be + * properly sent. + */ + value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL); + + if (value & DSI_POWER_CONTROL_ENABLE) + tegra_dsi_disable(dsi); + err = tegra_dsi_prepare(dsi); if (err < 0) { dev_err(dsi->dev, "failed to prepare: %d\n", err); @@ -1597,28 +1606,24 @@ static int tegra_dsi_probe(struct platform_device *pdev) } dsi->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(dsi->clk)) { - dev_err(&pdev->dev, "cannot get DSI clock\n"); - return PTR_ERR(dsi->clk); - } + if (IS_ERR(dsi->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk), + "cannot get DSI clock\n"); dsi->clk_lp = devm_clk_get(&pdev->dev, "lp"); - if (IS_ERR(dsi->clk_lp)) { - dev_err(&pdev->dev, "cannot get low-power clock\n"); - return PTR_ERR(dsi->clk_lp); - } + if (IS_ERR(dsi->clk_lp)) + return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp), + "cannot get low-power clock\n"); dsi->clk_parent = devm_clk_get(&pdev->dev, "parent"); - if (IS_ERR(dsi->clk_parent)) { - dev_err(&pdev->dev, "cannot get parent clock\n"); - return PTR_ERR(dsi->clk_parent); - } + if (IS_ERR(dsi->clk_parent)) + return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_parent), + "cannot get parent clock\n"); dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi"); - if (IS_ERR(dsi->vdd)) { - dev_err(&pdev->dev, "cannot get VDD supply\n"); - return PTR_ERR(dsi->vdd); - } + if (IS_ERR(dsi->vdd)) + return dev_err_probe(&pdev->dev, PTR_ERR(dsi->vdd), + "cannot get VDD supply\n"); err = tegra_dsi_setup_clocks(dsi); if (err < 0) { diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index cab1b9ef..a719af1d 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -3,7 +3,7 @@ * Copyright (C) 2012-2013 Avionic Design GmbH * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. * - * Based on the KMS/FB CMA helpers + * Based on the KMS/FB DMA helpers * Copyright (C) 2012 Analog Devices Inc. */ diff --git a/drivers/gpu/drm/tegra/fbdev.c b/drivers/gpu/drm/tegra/fbdev.c index 2d5b1b3f..d741d6e4 100644 --- a/drivers/gpu/drm/tegra/fbdev.c +++ b/drivers/gpu/drm/tegra/fbdev.c @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -161,7 +162,8 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, #if defined(NV_DRM_MODE_CONFIG_STRUCT_HAS_FB_BASE_ARG) /* Linux v6.2 */ drm->mode_config.fb_base = (resource_size_t)bo->iova; #endif - info->screen_base = (void __iomem *)bo->vaddr + offset; + info->flags |= FBINFO_VIRTFB; + info->screen_buffer = bo->vaddr + offset; info->screen_size = size; info->fix.smem_start = (unsigned long)(bo->iova + offset); info->fix.smem_len = size; diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 761490b5..ef3a237a 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -183,21 +183,30 @@ static void *tegra_bo_mmap(struct host1x_bo *bo) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); #if defined(NV_LINUX_IOSYS_MAP_H_PRESENT) - struct iosys_map map = {0}; + struct iosys_map map = { 0 }; #else - struct dma_buf_map map = {0}; + struct dma_buf_map map = { 0 }; #endif + void *vaddr; int ret; - if (obj->vaddr) { + if (obj->vaddr) return obj->vaddr; - } else if (obj->dma_buf) { + + if (obj->dma_buf) { ret = dma_buf_vmap(obj->dma_buf, &map); - return ret ? NULL : map.vaddr; - } else { - return vmap(obj->pages, obj->num_pages, VM_MAP, - pgprot_writecombine(PAGE_KERNEL)); + if (ret < 0) + return ERR_PTR(ret); + + return map.vaddr; } + + vaddr = vmap(obj->pages, obj->num_pages, VM_MAP, + pgprot_writecombine(PAGE_KERNEL)); + if (!vaddr) + return ERR_PTR(-ENOMEM); + + return vaddr; } static void tegra_bo_munmap(struct host1x_bo *bo, void *addr) @@ -211,10 +220,11 @@ static void tegra_bo_munmap(struct host1x_bo *bo, void *addr) if (obj->vaddr) return; - else if (obj->dma_buf) + + if (obj->dma_buf) dma_buf_vunmap(obj->dma_buf, &map); - else - vunmap(addr); + + vunmap(addr); } static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo) diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c index ca49f279..f2f21aa8 100644 --- a/drivers/gpu/drm/tegra/gr2d.c +++ b/drivers/gpu/drm/tegra/gr2d.c @@ -298,7 +298,6 @@ static int gr2d_remove(struct platform_device *pdev) struct gr2d *gr2d = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); - host1x_client_unregister(&gr2d->client.base); return 0; diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index 78a402fa..b63ba3e7 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -570,7 +571,6 @@ static int gr3d_remove(struct platform_device *pdev) struct gr3d *gr3d = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); - host1x_client_unregister(&gr3d->client.base); return 0; diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 205b1108..18fdb56a 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -12,7 +12,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include +#include #include #include #include @@ -872,14 +875,7 @@ static int tegra_hdmi_reconfigure_audio(struct tegra_hdmi *hdmi) static bool tegra_output_is_hdmi(struct tegra_output *output) { - struct edid *edid; - - if (!output->connector.edid_blob_ptr) - return false; - - edid = (struct edid *)output->connector.edid_blob_ptr->data; - - return drm_detect_hdmi_monitor(edid); + return output->connector.display_info.is_hdmi; } static enum drm_connector_status @@ -1561,26 +1557,47 @@ static int tegra_hdmi_init(struct host1x_client *client) { struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); struct drm_device *drm = dev_get_drvdata(client->host); + struct drm_connector *connector; int err; hdmi->output.dev = client->dev; - drm_connector_init_with_ddc(drm, &hdmi->output.connector, - &tegra_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA, - hdmi->output.ddc); - drm_connector_helper_add(&hdmi->output.connector, - &tegra_hdmi_connector_helper_funcs); - hdmi->output.connector.dpms = DRM_MODE_DPMS_OFF; - drm_simple_encoder_init(drm, &hdmi->output.encoder, DRM_MODE_ENCODER_TMDS); drm_encoder_helper_add(&hdmi->output.encoder, &tegra_hdmi_encoder_helper_funcs); - drm_connector_attach_encoder(&hdmi->output.connector, - &hdmi->output.encoder); - drm_connector_register(&hdmi->output.connector); + if (hdmi->output.bridge) { + err = drm_bridge_attach(&hdmi->output.encoder, hdmi->output.bridge, + NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (err) { + dev_err(client->dev, "failed to attach bridge: %d\n", + err); + return err; + } + + connector = drm_bridge_connector_init(drm, &hdmi->output.encoder); + if (IS_ERR(connector)) { + dev_err(client->dev, + "failed to initialize bridge connector: %pe\n", + connector); + return PTR_ERR(connector); + } + + drm_connector_attach_encoder(connector, &hdmi->output.encoder); + } else { + drm_connector_init_with_ddc(drm, &hdmi->output.connector, + &tegra_hdmi_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA, + hdmi->output.ddc); + drm_connector_helper_add(&hdmi->output.connector, + &tegra_hdmi_connector_helper_funcs); + hdmi->output.connector.dpms = DRM_MODE_DPMS_OFF; + + drm_connector_attach_encoder(&hdmi->output.connector, + &hdmi->output.encoder); + drm_connector_register(&hdmi->output.connector); + } err = tegra_output_init(drm, &hdmi->output); if (err < 0) { @@ -1786,7 +1803,6 @@ static irqreturn_t tegra_hdmi_irq(int irq, void *data) static int tegra_hdmi_probe(struct platform_device *pdev) { struct tegra_hdmi *hdmi; - struct resource *regs; int err; hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); @@ -1848,8 +1864,7 @@ static int tegra_hdmi_probe(struct platform_device *pdev) if (err < 0) return err; - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hdmi->regs = devm_ioremap_resource(&pdev->dev, regs); + hdmi->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(hdmi->regs)) return PTR_ERR(hdmi->regs); diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index 48e23746..4b01b30d 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -1104,7 +1103,7 @@ static int tegra_display_hub_probe(struct platform_device *pdev) for (i = 0; i < hub->soc->num_wgrps; i++) { struct tegra_windowgroup *wgrp = &hub->wgrps[i]; - char id[8]; + char id[16]; snprintf(id, sizeof(id), "wgrp%u", i); mutex_init(&wgrp->lock); diff --git a/drivers/gpu/drm/tegra/nvdec.c b/drivers/gpu/drm/tegra/nvdec.c index f1dea0be..117f4b3f 100644 --- a/drivers/gpu/drm/tegra/nvdec.c +++ b/drivers/gpu/drm/tegra/nvdec.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -501,6 +500,8 @@ static int nvdec_load_falcon_firmware(struct nvdec *nvdec) return err; } else { virt = tegra_drm_alloc(tegra, size, &iova); + if (IS_ERR(virt)) + return PTR_ERR(virt); } nvdec->falcon.firmware.virt = virt; @@ -955,7 +956,6 @@ static int nvdec_remove(struct platform_device *pdev) host1x_actmon_unregister(&nvdec->client.base); host1x_client_unregister(&nvdec->client.base); - falcon_exit(&nvdec->falcon); return 0; diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index c83ab104..dc2dcb5c 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -137,10 +137,10 @@ int tegra_output_probe(struct tegra_output *output) } output->hpd_gpio = devm_fwnode_gpiod_get(output->dev, - of_fwnode_handle(output->of_node), - "nvidia,hpd", - GPIOD_IN, - "HDMI hotplug detect"); + of_fwnode_handle(output->of_node), + "nvidia,hpd", + GPIOD_IN, + "HDMI hotplug detect"); if (IS_ERR(output->hpd_gpio)) { if (PTR_ERR(output->hpd_gpio) != -ENOENT) return PTR_ERR(output->hpd_gpio); diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index ca9f03e3..15777c16 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -778,21 +778,17 @@ int tegra_plane_interconnect_init(struct tegra_plane *plane) plane->icc_mem = devm_of_icc_get(dev, icc_name); err = PTR_ERR_OR_ZERO(plane->icc_mem); - if (err) { - dev_err_probe(dev, err, "failed to get %s interconnect\n", - icc_name); - return err; - } + if (err) + return dev_err_probe(dev, err, "failed to get %s interconnect\n", + icc_name); /* plane B on T20/30 has a dedicated memory client for a 6-tap vertical filter */ if (plane->index == 1 && dc->soc->has_win_b_vfilter_mem_client) { plane->icc_mem_vfilter = devm_of_icc_get(dev, "winb-vfilter"); err = PTR_ERR_OR_ZERO(plane->icc_mem_vfilter); - if (err) { - dev_err_probe(dev, err, "failed to get %s interconnect\n", - "winb-vfilter"); - return err; - } + if (err) + return dev_err_probe(dev, err, "failed to get %s interconnect\n", + "winb-vfilter"); } return 0; diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index 79566c9e..fc66bbd9 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c @@ -99,6 +99,7 @@ static void tegra_rgb_encoder_disable(struct drm_encoder *encoder) static void tegra_rgb_encoder_enable(struct drm_encoder *encoder) { + struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; struct tegra_output *output = encoder_to_output(encoder); struct tegra_rgb *rgb = to_rgb(output); u32 value; @@ -108,10 +109,19 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder) value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL; tegra_dc_writel(rgb->dc, value, DC_DISP_DATA_ENABLE_OPTIONS); - /* XXX: parameterize? */ + /* configure H- and V-sync signal polarities */ value = tegra_dc_readl(rgb->dc, DC_COM_PIN_OUTPUT_POLARITY(1)); - value &= ~LVS_OUTPUT_POLARITY_LOW; - value &= ~LHS_OUTPUT_POLARITY_LOW; + + if (mode->flags & DRM_MODE_FLAG_NHSYNC) + value |= LHS_OUTPUT_POLARITY_LOW; + else + value &= ~LHS_OUTPUT_POLARITY_LOW; + + if (mode->flags & DRM_MODE_FLAG_NVSYNC) + value |= LVS_OUTPUT_POLARITY_LOW; + else + value &= ~LVS_OUTPUT_POLARITY_LOW; + tegra_dc_writel(rgb->dc, value, DC_COM_PIN_OUTPUT_POLARITY(1)); /* XXX: parameterize? */ diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index b26de9b8..cb365a31 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -601,6 +602,9 @@ static u8 tegra_clk_sor_pad_get_parent(struct clk_hw *hw) } static const struct clk_ops tegra_clk_sor_pad_ops = { +#if defined(NV_CLK_HW_DETERMINE_RATE_NO_REPARENT_PRESENT) /* Linux 6.4 */ + .determine_rate = clk_hw_determine_rate_no_reparent, +#endif .set_parent = tegra_clk_sor_pad_set_parent, .get_parent = tegra_clk_sor_pad_get_parent, }; @@ -1168,7 +1172,7 @@ static int tegra_sor_compute_config(struct tegra_sor *sor, struct drm_dp_link *link) { const u64 f = 100000, link_rate = link->rate * 1000; - const u64 pclk = mode->clock * 1000; + const u64 pclk = (u64)mode->clock * 1000; u64 input, output, watermark, num; struct tegra_sor_params params; u32 num_syms_per_line; @@ -1726,7 +1730,6 @@ static void tegra_sor_early_unregister(struct drm_connector *connector) connector->debugfs_entry, connector->dev->primary); #else - drm_debugfs_remove_files(sor->debugfs_files, count, connector->dev->primary); #endif @@ -3000,11 +3003,9 @@ static int tegra_sor_hdmi_probe(struct tegra_sor *sor) int err; sor->avdd_io_supply = devm_regulator_get(sor->dev, "avdd-io-hdmi-dp"); - if (IS_ERR(sor->avdd_io_supply)) { - dev_err(sor->dev, "cannot get AVDD I/O supply: %ld\n", - PTR_ERR(sor->avdd_io_supply)); - return PTR_ERR(sor->avdd_io_supply); - } + if (IS_ERR(sor->avdd_io_supply)) + return dev_err_probe(sor->dev, PTR_ERR(sor->avdd_io_supply), + "cannot get AVDD I/O supply\n"); err = tegra_sor_enable_regulator(sor, sor->avdd_io_supply); if (err < 0) { @@ -3014,11 +3015,9 @@ static int tegra_sor_hdmi_probe(struct tegra_sor *sor) } sor->vdd_pll_supply = devm_regulator_get(sor->dev, "vdd-hdmi-dp-pll"); - if (IS_ERR(sor->vdd_pll_supply)) { - dev_err(sor->dev, "cannot get VDD PLL supply: %ld\n", - PTR_ERR(sor->vdd_pll_supply)); - return PTR_ERR(sor->vdd_pll_supply); - } + if (IS_ERR(sor->vdd_pll_supply)) + return dev_err_probe(sor->dev, PTR_ERR(sor->vdd_pll_supply), + "cannot get VDD PLL supply\n"); err = tegra_sor_enable_regulator(sor, sor->vdd_pll_supply); if (err < 0) { @@ -3028,11 +3027,9 @@ static int tegra_sor_hdmi_probe(struct tegra_sor *sor) } sor->hdmi_supply = devm_regulator_get(sor->dev, "hdmi"); - if (IS_ERR(sor->hdmi_supply)) { - dev_err(sor->dev, "cannot get HDMI supply: %ld\n", - PTR_ERR(sor->hdmi_supply)); - return PTR_ERR(sor->hdmi_supply); - } + if (IS_ERR(sor->hdmi_supply)) + return dev_err_probe(sor->dev, PTR_ERR(sor->hdmi_supply), + "cannot get HDMI supply\n"); err = tegra_sor_enable_regulator(sor, sor->hdmi_supply); if (err < 0) { @@ -3754,7 +3751,6 @@ static int tegra_sor_probe(struct platform_device *pdev) { struct device_node *np; struct tegra_sor *sor; - struct resource *regs; int err; sor = devm_kzalloc(&pdev->dev, sizeof(*sor), GFP_KERNEL); @@ -3827,8 +3823,7 @@ static int tegra_sor_probe(struct platform_device *pdev) } } - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - sor->regs = devm_ioremap_resource(&pdev->dev, regs); + sor->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(sor->regs)) { err = PTR_ERR(sor->regs); goto remove; diff --git a/drivers/gpu/drm/tegra/submit.c b/drivers/gpu/drm/tegra/submit.c index 464800ff..b7dd0717 100644 --- a/drivers/gpu/drm/tegra/submit.c +++ b/drivers/gpu/drm/tegra/submit.c @@ -175,14 +175,9 @@ static void *alloc_copy_user_array(void __user *from, size_t count, size_t size) if (copy_len > 0x4000) return ERR_PTR(-E2BIG); - data = kvmalloc(copy_len, GFP_KERNEL); - if (!data) - return ERR_PTR(-ENOMEM); - - if (copy_from_user(data, from, copy_len)) { - kvfree(data); - return ERR_PTR(-EFAULT); - } + data = vmemdup_user(from, copy_len); + if (IS_ERR(data)) + return ERR_CAST(data); return data; } @@ -738,21 +733,13 @@ int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data, host1x_memory_context_get(job->memory_context); } } else if (context->client->ops->get_streamid_offset) { -#ifdef CONFIG_IOMMU_API - struct iommu_fwspec *spec; - /* * Job submission will need to temporarily change stream ID, * so need to tell it what to change it back to. */ - spec = dev_iommu_fwspec_get(context->client->base.dev); - if (spec && spec->num_ids > 0) - job->engine_fallback_streamid = spec->ids[0] & 0xffff; - else - job->engine_fallback_streamid = 0x7f; -#else - job->engine_fallback_streamid = 0x7f; -#endif + if (!tegra_dev_iommu_get_stream_id(context->client->base.dev, + &job->engine_fallback_streamid)) + job->engine_fallback_streamid = TEGRA_STREAM_ID_BYPASS; } /* Boot engine, if necessary. */ diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index 7da863a9..665713c8 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index fbfe38bd..ea7504e1 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -737,6 +737,10 @@ static void host1x_setup_virtualization_tables(struct host1x *host) static bool host1x_wants_iommu(struct host1x *host1x) { + /* Our IOMMU usage policy doesn't currently play well with GART */ + if (of_machine_is_compatible("nvidia,tegra20")) + return false; + /* * If we support addressing a maximum of 32 bits of physical memory * and if the host1x firewall is enabled, there's no need to enable