OMAPDSS: DISPC: program dispc polarities to control module
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 5 Sep 2014 19:15:03 +0000 (19:15 +0000)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Wed, 4 Feb 2015 10:32:06 +0000 (12:32 +0200)
On DRA7xx, DISPC needs to write output signal polarities not only to a
DISPC register, like for all earlier DSS versions, but to control
module's CTRL_CORE_SMA_SW_1 register.

This patch adds support to write the polarities to control module.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
drivers/video/fbdev/omap2/dss/dispc.c

index 48429bab294a0697d3293b7686e7a24f3e2de20b..31b743c70272024fbe8e46553e59a674b0521404 100644 (file)
@@ -36,6 +36,9 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/sizes.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
 
 #include <video/omapdss.h>
 
@@ -117,6 +120,9 @@ static struct {
        const struct dispc_features *feat;
 
        bool is_enabled;
+
+       struct regmap *syscon_pol;
+       u32 syscon_pol_offset;
 } dispc;
 
 enum omap_color_component {
@@ -2958,6 +2964,25 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
                FLD_VAL(vsync_level, 12, 12);
 
        dispc_write_reg(DISPC_POL_FREQ(channel), l);
+
+       if (dispc.syscon_pol) {
+               const int shifts[] = {
+                       [OMAP_DSS_CHANNEL_LCD] = 0,
+                       [OMAP_DSS_CHANNEL_LCD2] = 1,
+                       [OMAP_DSS_CHANNEL_LCD3] = 2,
+               };
+
+               u32 mask, val;
+
+               mask = (1 << 0) | (1 << 3) | (1 << 6);
+               val = (rf << 0) | (ipc << 3) | (onoff << 6);
+
+               mask <<= 16 + shifts[channel];
+               val <<= 16 + shifts[channel];
+
+               regmap_update_bits(dispc.syscon_pol, dispc.syscon_pol_offset,
+                       mask, val);
+       }
 }
 
 /* change name to mode? */
@@ -3741,6 +3766,7 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
        u32 rev;
        int r = 0;
        struct resource *dispc_mem;
+       struct device_node *np = pdev->dev.of_node;
 
        dispc.pdev = pdev;
 
@@ -3767,6 +3793,20 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       if (np && of_property_read_bool(np, "syscon-pol")) {
+               dispc.syscon_pol = syscon_regmap_lookup_by_phandle(np, "syscon-pol");
+               if (IS_ERR(dispc.syscon_pol)) {
+                       dev_err(&pdev->dev, "failed to get syscon-pol regmap\n");
+                       return PTR_ERR(dispc.syscon_pol);
+               }
+
+               if (of_property_read_u32_index(np, "syscon-pol", 1,
+                               &dispc.syscon_pol_offset)) {
+                       dev_err(&pdev->dev, "failed to get syscon-pol offset\n");
+                       return -EINVAL;
+               }
+       }
+
        pm_runtime_enable(&pdev->dev);
 
        r = dispc_runtime_get();