Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm/tegra/for-4.20-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next

drm/tegra: Changes for v4.20-rc1

This contains initial Tegra194 support as well as a couple of fixes for
DMA/IOMMU integration.

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Thierry Reding <thierry.reding@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180927205051.30017-1-thierry.reding@gmail.com

+233 -53
+73
drivers/gpu/drm/tegra/dc.c
··· 1988 1988 struct drm_plane *cursor = NULL; 1989 1989 int err; 1990 1990 1991 + /* 1992 + * XXX do not register DCs with no window groups because we cannot 1993 + * assign a primary plane to them, which in turn will cause KMS to 1994 + * crash. 1995 + */ 1996 + if (dc->soc->wgrps) { 1997 + bool has_wgrps = false; 1998 + unsigned int i; 1999 + 2000 + for (i = 0; i < dc->soc->num_wgrps; i++) { 2001 + const struct tegra_windowgroup_soc *wgrp = &dc->soc->wgrps[i]; 2002 + 2003 + if (wgrp->dc == dc->pipe && wgrp->num_windows > 0) { 2004 + has_wgrps = true; 2005 + break; 2006 + } 2007 + } 2008 + 2009 + if (!has_wgrps) 2010 + return 0; 2011 + } 2012 + 1991 2013 dc->syncpt = host1x_syncpt_request(client, flags); 1992 2014 if (!dc->syncpt) 1993 2015 dev_warn(dc->dev, "failed to allocate syncpoint\n"); ··· 2256 2234 .num_wgrps = ARRAY_SIZE(tegra186_dc_wgrps), 2257 2235 }; 2258 2236 2237 + static const struct tegra_windowgroup_soc tegra194_dc_wgrps[] = { 2238 + { 2239 + .index = 0, 2240 + .dc = 0, 2241 + .windows = (const unsigned int[]) { 0 }, 2242 + .num_windows = 1, 2243 + }, { 2244 + .index = 1, 2245 + .dc = 1, 2246 + .windows = (const unsigned int[]) { 1 }, 2247 + .num_windows = 1, 2248 + }, { 2249 + .index = 2, 2250 + .dc = 1, 2251 + .windows = (const unsigned int[]) { 2 }, 2252 + .num_windows = 1, 2253 + }, { 2254 + .index = 3, 2255 + .dc = 2, 2256 + .windows = (const unsigned int[]) { 3 }, 2257 + .num_windows = 1, 2258 + }, { 2259 + .index = 4, 2260 + .dc = 2, 2261 + .windows = (const unsigned int[]) { 4 }, 2262 + .num_windows = 1, 2263 + }, { 2264 + .index = 5, 2265 + .dc = 2, 2266 + .windows = (const unsigned int[]) { 5 }, 2267 + .num_windows = 1, 2268 + }, 2269 + }; 2270 + 2271 + static const struct tegra_dc_soc_info tegra194_dc_soc_info = { 2272 + .supports_background_color = true, 2273 + .supports_interlacing = true, 2274 + .supports_cursor = true, 2275 + .supports_block_linear = true, 2276 + .has_legacy_blending = false, 2277 + .pitch_align = 64, 2278 + .has_powergate = false, 2279 + .coupled_pm = false, 2280 + .has_nvdisplay = true, 2281 + .wgrps = tegra194_dc_wgrps, 2282 + .num_wgrps = ARRAY_SIZE(tegra194_dc_wgrps), 2283 + }; 2284 + 2259 2285 static const struct of_device_id tegra_dc_of_match[] = { 2260 2286 { 2287 + .compatible = "nvidia,tegra194-dc", 2288 + .data = &tegra194_dc_soc_info, 2289 + }, { 2261 2290 .compatible = "nvidia,tegra186-dc", 2262 2291 .data = &tegra186_dc_soc_info, 2263 2292 }, {
+1 -1
drivers/gpu/drm/tegra/dc.h
··· 300 300 #define SOR1_TIMING_CYA (1 << 27) 301 301 #define CURSOR_ENABLE (1 << 16) 302 302 303 - #define SOR_ENABLE(x) (1 << (25 + (x))) 303 + #define SOR_ENABLE(x) (1 << (25 + (((x) > 1) ? ((x) + 1) : (x)))) 304 304 305 305 #define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403 306 306 #define CURSOR_THRESHOLD(x) (((x) & 0x03) << 24)
+2 -1
drivers/gpu/drm/tegra/dpaux.c
··· 521 521 * is no possibility to perform the I2C mode configuration in the 522 522 * HDMI path. 523 523 */ 524 - err = tegra_dpaux_pad_config(dpaux, DPAUX_HYBRID_PADCTL_MODE_I2C); 524 + err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C); 525 525 if (err < 0) 526 526 return err; 527 527 ··· 639 639 }; 640 640 641 641 static const struct of_device_id tegra_dpaux_of_match[] = { 642 + { .compatible = "nvidia,tegra194-dpaux", }, 642 643 { .compatible = "nvidia,tegra186-dpaux", }, 643 644 { .compatible = "nvidia,tegra210-dpaux", }, 644 645 { .compatible = "nvidia,tegra124-dpaux", },
+17 -18
drivers/gpu/drm/tegra/drm.c
··· 15 15 #include <drm/drm_atomic.h> 16 16 #include <drm/drm_atomic_helper.h> 17 17 18 + #if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) 19 + #include <asm/dma-iommu.h> 20 + #endif 21 + 18 22 #include "drm.h" 19 23 #include "gem.h" 20 24 ··· 1072 1068 } 1073 1069 1074 1070 if (!shared || (shared && (group != tegra->group))) { 1071 + #if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) 1072 + if (client->dev->archdata.mapping) { 1073 + struct dma_iommu_mapping *mapping = 1074 + to_dma_iommu_mapping(client->dev); 1075 + arm_iommu_detach_device(client->dev); 1076 + arm_iommu_release_mapping(mapping); 1077 + } 1078 + #endif 1075 1079 err = iommu_attach_group(tegra->domain, group); 1076 1080 if (err < 0) { 1077 1081 iommu_group_put(group); ··· 1228 1216 static int host1x_drm_suspend(struct device *dev) 1229 1217 { 1230 1218 struct drm_device *drm = dev_get_drvdata(dev); 1231 - struct tegra_drm *tegra = drm->dev_private; 1232 1219 1233 - drm_kms_helper_poll_disable(drm); 1234 - tegra_drm_fb_suspend(drm); 1235 - 1236 - tegra->state = drm_atomic_helper_suspend(drm); 1237 - if (IS_ERR(tegra->state)) { 1238 - tegra_drm_fb_resume(drm); 1239 - drm_kms_helper_poll_enable(drm); 1240 - return PTR_ERR(tegra->state); 1241 - } 1242 - 1243 - return 0; 1220 + return drm_mode_config_helper_suspend(drm); 1244 1221 } 1245 1222 1246 1223 static int host1x_drm_resume(struct device *dev) 1247 1224 { 1248 1225 struct drm_device *drm = dev_get_drvdata(dev); 1249 - struct tegra_drm *tegra = drm->dev_private; 1250 1226 1251 - drm_atomic_helper_resume(drm, tegra->state); 1252 - tegra_drm_fb_resume(drm); 1253 - drm_kms_helper_poll_enable(drm); 1254 - 1255 - return 0; 1227 + return drm_mode_config_helper_resume(drm); 1256 1228 } 1257 1229 #endif 1258 1230 ··· 1271 1275 { .compatible = "nvidia,tegra186-sor", }, 1272 1276 { .compatible = "nvidia,tegra186-sor1", }, 1273 1277 { .compatible = "nvidia,tegra186-vic", }, 1278 + { .compatible = "nvidia,tegra194-display", }, 1279 + { .compatible = "nvidia,tegra194-dc", }, 1280 + { .compatible = "nvidia,tegra194-sor", }, 1274 1281 { /* sentinel */ } 1275 1282 }; 1276 1283
-4
drivers/gpu/drm/tegra/drm.h
··· 60 60 unsigned int pitch_align; 61 61 62 62 struct tegra_display_hub *hub; 63 - 64 - struct drm_atomic_state *state; 65 63 }; 66 64 67 65 struct tegra_drm_client; ··· 184 186 void tegra_drm_fb_free(struct drm_device *drm); 185 187 int tegra_drm_fb_init(struct drm_device *drm); 186 188 void tegra_drm_fb_exit(struct drm_device *drm); 187 - void tegra_drm_fb_suspend(struct drm_device *drm); 188 - void tegra_drm_fb_resume(struct drm_device *drm); 189 189 190 190 extern struct platform_driver tegra_display_hub_driver; 191 191 extern struct platform_driver tegra_dc_driver;
+1 -23
drivers/gpu/drm/tegra/fb.c
··· 356 356 /* Undo the special mapping we made in fbdev probe. */ 357 357 if (bo && bo->pages) { 358 358 vunmap(bo->vaddr); 359 - bo->vaddr = 0; 359 + bo->vaddr = NULL; 360 360 } 361 361 362 362 drm_framebuffer_remove(fbdev->fb); ··· 410 410 struct tegra_drm *tegra = drm->dev_private; 411 411 412 412 tegra_fbdev_exit(tegra->fbdev); 413 - #endif 414 - } 415 - 416 - void tegra_drm_fb_suspend(struct drm_device *drm) 417 - { 418 - #ifdef CONFIG_DRM_FBDEV_EMULATION 419 - struct tegra_drm *tegra = drm->dev_private; 420 - 421 - console_lock(); 422 - drm_fb_helper_set_suspend(&tegra->fbdev->base, 1); 423 - console_unlock(); 424 - #endif 425 - } 426 - 427 - void tegra_drm_fb_resume(struct drm_device *drm) 428 - { 429 - #ifdef CONFIG_DRM_FBDEV_EMULATION 430 - struct tegra_drm *tegra = drm->dev_private; 431 - 432 - console_lock(); 433 - drm_fb_helper_set_suspend(&tegra->fbdev->base, 0); 434 - console_unlock(); 435 413 #endif 436 414 }
+15 -4
drivers/gpu/drm/tegra/hub.c
··· 758 758 return err; 759 759 } 760 760 761 - hub->clk_dsc = devm_clk_get(&pdev->dev, "dsc"); 762 - if (IS_ERR(hub->clk_dsc)) { 763 - err = PTR_ERR(hub->clk_dsc); 764 - return err; 761 + if (hub->soc->supports_dsc) { 762 + hub->clk_dsc = devm_clk_get(&pdev->dev, "dsc"); 763 + if (IS_ERR(hub->clk_dsc)) { 764 + err = PTR_ERR(hub->clk_dsc); 765 + return err; 766 + } 765 767 } 766 768 767 769 hub->clk_hub = devm_clk_get(&pdev->dev, "hub"); ··· 892 890 893 891 static const struct tegra_display_hub_soc tegra186_display_hub = { 894 892 .num_wgrps = 6, 893 + .supports_dsc = true, 894 + }; 895 + 896 + static const struct tegra_display_hub_soc tegra194_display_hub = { 897 + .num_wgrps = 6, 898 + .supports_dsc = false, 895 899 }; 896 900 897 901 static const struct of_device_id tegra_display_hub_of_match[] = { 898 902 { 903 + .compatible = "nvidia,tegra194-display", 904 + .data = &tegra194_display_hub 905 + }, { 899 906 .compatible = "nvidia,tegra186-display", 900 907 .data = &tegra186_display_hub 901 908 }, {
+1
drivers/gpu/drm/tegra/hub.h
··· 38 38 39 39 struct tegra_display_hub_soc { 40 40 unsigned int num_wgrps; 41 + bool supports_dsc; 41 42 }; 42 43 43 44 struct tegra_display_hub {
+110
drivers/gpu/drm/tegra/sor.c
··· 282 282 } 283 283 }; 284 284 285 + static const struct tegra_sor_hdmi_settings tegra194_sor_hdmi_defaults[] = { 286 + { 287 + .frequency = 54000000, 288 + .vcocap = 0, 289 + .filter = 5, 290 + .ichpmp = 5, 291 + .loadadj = 3, 292 + .tmds_termadj = 0xf, 293 + .tx_pu_value = 0, 294 + .bg_temp_coef = 3, 295 + .bg_vref_level = 8, 296 + .avdd10_level = 4, 297 + .avdd14_level = 4, 298 + .sparepll = 0x54, 299 + .drive_current = { 0x3a, 0x3a, 0x3a, 0x33 }, 300 + .preemphasis = { 0x00, 0x00, 0x00, 0x00 }, 301 + }, { 302 + .frequency = 75000000, 303 + .vcocap = 1, 304 + .filter = 5, 305 + .ichpmp = 5, 306 + .loadadj = 3, 307 + .tmds_termadj = 0xf, 308 + .tx_pu_value = 0, 309 + .bg_temp_coef = 3, 310 + .bg_vref_level = 8, 311 + .avdd10_level = 4, 312 + .avdd14_level = 4, 313 + .sparepll = 0x44, 314 + .drive_current = { 0x3a, 0x3a, 0x3a, 0x33 }, 315 + .preemphasis = { 0x00, 0x00, 0x00, 0x00 }, 316 + }, { 317 + .frequency = 150000000, 318 + .vcocap = 3, 319 + .filter = 5, 320 + .ichpmp = 5, 321 + .loadadj = 3, 322 + .tmds_termadj = 15, 323 + .tx_pu_value = 0x66 /* 0 */, 324 + .bg_temp_coef = 3, 325 + .bg_vref_level = 8, 326 + .avdd10_level = 4, 327 + .avdd14_level = 4, 328 + .sparepll = 0x00, /* 0x34 */ 329 + .drive_current = { 0x3a, 0x3a, 0x3a, 0x37 }, 330 + .preemphasis = { 0x00, 0x00, 0x00, 0x00 }, 331 + }, { 332 + .frequency = 300000000, 333 + .vcocap = 3, 334 + .filter = 5, 335 + .ichpmp = 5, 336 + .loadadj = 3, 337 + .tmds_termadj = 15, 338 + .tx_pu_value = 64, 339 + .bg_temp_coef = 3, 340 + .bg_vref_level = 8, 341 + .avdd10_level = 4, 342 + .avdd14_level = 4, 343 + .sparepll = 0x34, 344 + .drive_current = { 0x3d, 0x3d, 0x3d, 0x33 }, 345 + .preemphasis = { 0x00, 0x00, 0x00, 0x00 }, 346 + }, { 347 + .frequency = 600000000, 348 + .vcocap = 3, 349 + .filter = 5, 350 + .ichpmp = 5, 351 + .loadadj = 3, 352 + .tmds_termadj = 12, 353 + .tx_pu_value = 96, 354 + .bg_temp_coef = 3, 355 + .bg_vref_level = 8, 356 + .avdd10_level = 4, 357 + .avdd14_level = 4, 358 + .sparepll = 0x34, 359 + .drive_current = { 0x3d, 0x3d, 0x3d, 0x33 }, 360 + .preemphasis = { 0x00, 0x00, 0x00, 0x00 }, 361 + } 362 + }; 363 + 285 364 struct tegra_sor_regs { 286 365 unsigned int head_state0; 287 366 unsigned int head_state1; ··· 2973 2894 .xbar_cfg = tegra124_sor_xbar_cfg, 2974 2895 }; 2975 2896 2897 + static const struct tegra_sor_regs tegra194_sor_regs = { 2898 + .head_state0 = 0x151, 2899 + .head_state1 = 0x155, 2900 + .head_state2 = 0x159, 2901 + .head_state3 = 0x15d, 2902 + .head_state4 = 0x161, 2903 + .head_state5 = 0x165, 2904 + .pll0 = 0x169, 2905 + .pll1 = 0x16a, 2906 + .pll2 = 0x16b, 2907 + .pll3 = 0x16c, 2908 + .dp_padctl0 = 0x16e, 2909 + .dp_padctl2 = 0x16f, 2910 + }; 2911 + 2912 + static const struct tegra_sor_soc tegra194_sor = { 2913 + .supports_edp = true, 2914 + .supports_lvds = false, 2915 + .supports_hdmi = true, 2916 + .supports_dp = true, 2917 + 2918 + .regs = &tegra194_sor_regs, 2919 + .has_nvdisplay = true, 2920 + 2921 + .num_settings = ARRAY_SIZE(tegra194_sor_hdmi_defaults), 2922 + .settings = tegra194_sor_hdmi_defaults, 2923 + 2924 + .xbar_cfg = tegra210_sor_xbar_cfg, 2925 + }; 2926 + 2976 2927 static const struct of_device_id tegra_sor_of_match[] = { 2928 + { .compatible = "nvidia,tegra194-sor", .data = &tegra194_sor }, 2977 2929 { .compatible = "nvidia,tegra186-sor1", .data = &tegra186_sor1 }, 2978 2930 { .compatible = "nvidia,tegra186-sor", .data = &tegra186_sor }, 2979 2931 { .compatible = "nvidia,tegra210-sor1", .data = &tegra210_sor1 },
+1 -1
drivers/gpu/host1x/bus.c
··· 331 331 struct bus_type host1x_bus_type = { 332 332 .name = "host1x", 333 333 .match = host1x_device_match, 334 - .dma_configure = host1x_dma_configure, 334 + .dma_configure = host1x_dma_configure, 335 335 .pm = &host1x_device_pm_ops, 336 336 }; 337 337
+12 -1
drivers/gpu/host1x/dev.c
··· 29 29 #include <trace/events/host1x.h> 30 30 #undef CREATE_TRACE_POINTS 31 31 32 + #if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) 33 + #include <asm/dma-iommu.h> 34 + #endif 35 + 32 36 #include "bus.h" 33 37 #include "channel.h" 34 38 #include "debug.h" ··· 221 217 dev_err(&pdev->dev, "failed to get reset: %d\n", err); 222 218 return err; 223 219 } 224 - 220 + #if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) 221 + if (host->dev->archdata.mapping) { 222 + struct dma_iommu_mapping *mapping = 223 + to_dma_iommu_mapping(host->dev); 224 + arm_iommu_detach_device(host->dev); 225 + arm_iommu_release_mapping(mapping); 226 + } 227 + #endif 225 228 if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) 226 229 goto skip_iommu; 227 230