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

drm/tidss: implement WA for AM65xx erratum i2000

This patch implements WA for AM65xx erratum i2000, which causes YUV
formats to show wrong colors.

An earlier patch removed a partial WA:

a8d9d7da1546349f18eb2d6b6b3a04bdeb38719d ("drm/tidss: remove AM65x PG1 YUV erratum code")

The patch explains the reasoning for removal. The change in plans has
been that it has become clear that there are and will be users for PG1
SoCs and as such it's good to implement the WA for PG1s.

This patch adds the WA back so that it is only used on SR1.0 (which is
the new name for PG1). The previous WA code didn't check the SoC
revision, which this patch does.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200812112625.59897-1-tomi.valkeinen@ti.com
Reviewed-by: Jyri Sarha <jsarha@ti.com>

+32 -4
+28 -4
drivers/gpu/drm/tidss/tidss_dispc.c
··· 19 19 #include <linux/platform_device.h> 20 20 #include <linux/pm_runtime.h> 21 21 #include <linux/regmap.h> 22 + #include <linux/sys_soc.h> 22 23 23 24 #include <drm/drm_fourcc.h> 24 25 #include <drm/drm_fb_cma_helper.h> ··· 303 302 u32 num_fourccs; 304 303 305 304 u32 memory_bandwidth_limit; 305 + 306 + struct dispc_errata errata; 306 307 }; 307 308 308 309 static void dispc_write(struct dispc_device *dispc, u16 reg, u32 val) ··· 2644 2641 return 0; 2645 2642 } 2646 2643 2644 + static void dispc_init_errata(struct dispc_device *dispc) 2645 + { 2646 + static const struct soc_device_attribute am65x_sr10_soc_devices[] = { 2647 + { .family = "AM65X", .revision = "SR1.0" }, 2648 + { /* sentinel */ } 2649 + }; 2650 + 2651 + if (soc_device_match(am65x_sr10_soc_devices)) { 2652 + dispc->errata.i2000 = true; 2653 + dev_info(dispc->dev, "WA for erratum i2000: YUV formats disabled\n"); 2654 + } 2655 + } 2656 + 2647 2657 int dispc_init(struct tidss_device *tidss) 2648 2658 { 2649 2659 struct device *dev = tidss->dev; ··· 2680 2664 if (!dispc) 2681 2665 return -ENOMEM; 2682 2666 2667 + dispc->tidss = tidss; 2668 + dispc->dev = dev; 2669 + dispc->feat = feat; 2670 + 2671 + dispc_init_errata(dispc); 2672 + 2683 2673 dispc->fourccs = devm_kcalloc(dev, ARRAY_SIZE(dispc_color_formats), 2684 2674 sizeof(*dispc->fourccs), GFP_KERNEL); 2685 2675 if (!dispc->fourccs) 2686 2676 return -ENOMEM; 2687 2677 2688 2678 num_fourccs = 0; 2689 - for (i = 0; i < ARRAY_SIZE(dispc_color_formats); ++i) 2679 + for (i = 0; i < ARRAY_SIZE(dispc_color_formats); ++i) { 2680 + if (dispc->errata.i2000 && 2681 + dispc_fourcc_is_yuv(dispc_color_formats[i].fourcc)) { 2682 + continue; 2683 + } 2690 2684 dispc->fourccs[num_fourccs++] = dispc_color_formats[i].fourcc; 2685 + } 2691 2686 2692 2687 dispc->num_fourccs = num_fourccs; 2693 - dispc->tidss = tidss; 2694 - dispc->dev = dev; 2695 - dispc->feat = feat; 2696 2688 2697 2689 dispc_common_regmap = dispc->feat->common_regs; 2698 2690
+4
drivers/gpu/drm/tidss/tidss_dispc.h
··· 46 46 u32 xinc_max; 47 47 }; 48 48 49 + struct dispc_errata { 50 + bool i2000; /* DSS Does Not Support YUV Pixel Data Formats */ 51 + }; 52 + 49 53 enum dispc_vp_bus_type { 50 54 DISPC_VP_DPI, /* DPI output */ 51 55 DISPC_VP_OLDI, /* OLDI (LVDS) output */