* [PATCH 1/9] OMAPDSS: DSI: improve DSI clock calcs for DISPC
From: Tomi Valkeinen @ 2012-09-24 13:58 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1348495119-8262-1-git-send-email-tomi.valkeinen@ti.com>
Commit ee144e645a081daad5de1ccac77f0a0e98e6a67b added
dsi_pll_calc_ddrfreq() which calculates PLL dividers based on given DSI
bus clock speed. The function works ok, but it can be improved for the
DISPC clock calc.
The current version calculates the clock going from the PLL to the DISPC
simply by setting the clock as close to DISPC maximum as possible, and
the pixel clock is calculated based on that.
This patch changes the function to calculate DISPC clock more
dynamically, iterating through different DISPC clocks and pixel clock
values, and thus we'll get more suitable pixel clocks.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 144 ++++++++++++++++++++++++++++++++---------
1 file changed, 113 insertions(+), 31 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 8d815e3..8d47fb7 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1454,26 +1454,17 @@ found:
}
static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev,
- unsigned long req_clk, struct dsi_clock_info *cinfo)
+ unsigned long req_clkin4ddr, struct dsi_clock_info *cinfo)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct dsi_clock_info cur, best;
- unsigned long dss_sys_clk, max_dss_fck, max_dsi_fck;
- unsigned long req_clkin4ddr;
DSSDBG("dsi_pll_calc_ddrfreq\n");
- dss_sys_clk = clk_get_rate(dsi->sys_clk);
-
- max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
- max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
-
memset(&best, 0, sizeof(best));
memset(&cur, 0, sizeof(cur));
- cur.clkin = dss_sys_clk;
-
- req_clkin4ddr = req_clk * 4;
+ cur.clkin = clk_get_rate(dsi->sys_clk);
for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
cur.fint = cur.clkin / cur.regn;
@@ -1503,18 +1494,107 @@ static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev,
}
}
found:
- best.regm_dispc = DIV_ROUND_UP(best.clkin4ddr, max_dss_fck);
- best.dsi_pll_hsdiv_dispc_clk = best.clkin4ddr / best.regm_dispc;
-
- best.regm_dsi = DIV_ROUND_UP(best.clkin4ddr, max_dsi_fck);
- best.dsi_pll_hsdiv_dsi_clk = best.clkin4ddr / best.regm_dsi;
-
if (cinfo)
*cinfo = best;
return 0;
}
+static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev,
+ struct dsi_clock_info *cinfo)
+{
+ unsigned long max_dsi_fck;
+
+ max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
+
+ cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck);
+ cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi;
+}
+
+static int dsi_pll_calc_dispc_fck(struct platform_device *dsidev,
+ unsigned long req_pck, struct dsi_clock_info *cinfo,
+ struct dispc_clock_info *dispc_cinfo)
+{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ unsigned regm_dispc, best_regm_dispc;
+ unsigned long dispc_clk, best_dispc_clk;
+ int min_fck_per_pck;
+ unsigned long max_dss_fck;
+ struct dispc_clock_info best_dispc;
+ bool match;
+
+ max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+
+ min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
+
+ if (min_fck_per_pck &&
+ req_pck * min_fck_per_pck > max_dss_fck) {
+ DSSERR("Requested pixel clock not possible with the current "
+ "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
+ "the constraint off.\n");
+ min_fck_per_pck = 0;
+ }
+
+retry:
+ best_regm_dispc = 0;
+ best_dispc_clk = 0;
+ memset(&best_dispc, 0, sizeof(best_dispc));
+ match = false;
+
+ for (regm_dispc = 1; regm_dispc < dsi->regm_dispc_max; ++regm_dispc) {
+ struct dispc_clock_info cur_dispc;
+
+ dispc_clk = cinfo->clkin4ddr / regm_dispc;
+
+ /* this will narrow down the search a bit,
+ * but still give pixclocks below what was
+ * requested */
+ if (dispc_clk < req_pck)
+ break;
+
+ if (dispc_clk > max_dss_fck)
+ continue;
+
+ if (min_fck_per_pck && dispc_clk < req_pck * min_fck_per_pck)
+ continue;
+
+ match = true;
+
+ dispc_find_clk_divs(req_pck, dispc_clk, &cur_dispc);
+
+ if (abs(cur_dispc.pck - req_pck) <
+ abs(best_dispc.pck - req_pck)) {
+ best_regm_dispc = regm_dispc;
+ best_dispc_clk = dispc_clk;
+ best_dispc = cur_dispc;
+
+ if (cur_dispc.pck = req_pck)
+ goto found;
+ }
+ }
+
+ if (!match) {
+ if (min_fck_per_pck) {
+ DSSERR("Could not find suitable clock settings.\n"
+ "Turning FCK/PCK constraint off and"
+ "trying again.\n");
+ min_fck_per_pck = 0;
+ goto retry;
+ }
+
+ DSSERR("Could not find suitable clock settings.\n");
+
+ return -EINVAL;
+ }
+found:
+ cinfo->regm_dispc = best_regm_dispc;
+ cinfo->dsi_pll_hsdiv_dispc_clk = best_dispc_clk;
+
+ *dispc_cinfo = best_dispc;
+
+ return 0;
+}
+
int dsi_pll_set_clock_div(struct platform_device *dsidev,
struct dsi_clock_info *cinfo)
{
@@ -4188,33 +4268,35 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
mutex_lock(&dsi->lock);
- r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk, &cinfo);
+ /* Calculate PLL output clock */
+ r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk * 4, &cinfo);
if (r)
goto err;
- dssdev->clocks.dsi.regn = cinfo.regn;
- dssdev->clocks.dsi.regm = cinfo.regm;
- dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
- dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
+ /* Calculate PLL's DSI clock */
+ dsi_pll_calc_dsi_fck(dsidev, &cinfo);
+ /* Calculate PLL's DISPC clock and pck & lck divs */
+ pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
+ DSSDBG("finding dispc dividers for pck %lu\n", pck);
+ r = dsi_pll_calc_dispc_fck(dsidev, pck, &cinfo, &dispc_cinfo);
+ if (r)
+ goto err;
+ /* Calculate LP clock */
dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk;
lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2);
- dssdev->clocks.dsi.lp_clk_div = lp_clk_div;
-
- /* pck = TxByteClkHS * datalanes * 8 / bitsperpixel */
-
- pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
-
- DSSDBG("finding dispc dividers for pck %lu\n", pck);
+ dssdev->clocks.dsi.regn = cinfo.regn;
+ dssdev->clocks.dsi.regm = cinfo.regm;
+ dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
+ dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
- dispc_find_clk_divs(pck, cinfo.dsi_pll_hsdiv_dispc_clk, &dispc_cinfo);
+ dssdev->clocks.dsi.lp_clk_div = lp_clk_div;
dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div;
dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div;
-
dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK;
dssdev->clocks.dispc.channel.lcd_clk_src --
1.7.9.5
^ permalink raw reply related
* [PATCH 0/9] OMAPDSS: OMAP5 related patches
From: Tomi Valkeinen @ 2012-09-24 13:58 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
Hi,
This series adds basic OMAP5 DSS functionality, mainly related to DSS core, DPI
and DSI.
Tomi
Archit Taneja (1):
OMAPDSS: Add basic omap5 features to dss and dispc
Tomi Valkeinen (8):
OMAPDSS: DSI: improve DSI clock calcs for DISPC
OMAPDSS: move dss feats to the end of dss.c
OMAPDSS: Add support for DPI source selection
OMAPDSS: DSI: Add FEAT_DSI_PLL_SELFREQDCO
OMAPDSS: DSI: Add FEAT_DSI_PLL_REFSEL
OMAPDSS: DSI: Add new linebuffer size for OMAP5
OMAPDSS: DSI: Add code to disable PHY DCC
OMAPDSS: DSI: make OMAP2_DSS_DSI depend on ARCH_OMAP5
drivers/video/omap2/dss/Kconfig | 2 +-
drivers/video/omap2/dss/dispc.c | 2 +
drivers/video/omap2/dss/dpi.c | 5 +
drivers/video/omap2/dss/dsi.c | 167 +++++++++++++++++++++++++-------
drivers/video/omap2/dss/dss.c | 121 ++++++++++++++++++-----
drivers/video/omap2/dss/dss.h | 1 +
drivers/video/omap2/dss/dss_features.c | 96 ++++++++++++++++++
drivers/video/omap2/dss/dss_features.h | 3 +
8 files changed, 337 insertions(+), 60 deletions(-)
--
1.7.9.5
^ permalink raw reply
* Re: [PATCH v4] of: Add videomode helper
From: Rob Herring @ 2012-09-24 13:42 UTC (permalink / raw)
To: Steffen Trumtrar
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Laurent Pinchart,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Sascha Hauer
In-Reply-To: <1348042843-24673-1-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
On 09/19/2012 03:20 AM, Steffen Trumtrar wrote:
> This patch adds a helper function for parsing videomodes from the devicetree.
> The videomode can be either converted to a struct drm_display_mode or a
> struct fb_videomode.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> ---
>
> Hi!
>
> changes since v3:
> - print error messages
> - free alloced memory
> - general cleanup
>
> Regards
> Steffen
>
> .../devicetree/bindings/video/displaymode | 74 +++++
> drivers/of/Kconfig | 5 +
> drivers/of/Makefile | 1 +
> drivers/of/of_videomode.c | 283 ++++++++++++++++++++
> include/linux/of_videomode.h | 56 ++++
> 5 files changed, 419 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/video/displaymode
> create mode 100644 drivers/of/of_videomode.c
> create mode 100644 include/linux/of_videomode.h
>
> diff --git a/Documentation/devicetree/bindings/video/displaymode b/Documentation/devicetree/bindings/video/displaymode
> new file mode 100644
> index 0000000..990ca52
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/displaymode
> @@ -0,0 +1,74 @@
> +videomode bindings
> +=========
> +
> +Required properties:
> + - hactive, vactive: Display resolution
> + - hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters
> + in pixels
> + vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in
> + lines
> + - clock: displayclock in Hz
A major piece missing is the LCD controller to display interface width
and component ordering.
> +
> +Optional properties:
> + - width-mm, height-mm: Display dimensions in mm
> + - hsync-active-high (bool): Hsync pulse is active high
> + - vsync-active-high (bool): Vsync pulse is active high
> + - interlaced (bool): This is an interlaced mode
> + - doublescan (bool): This is a doublescan mode
> +
> +There are different ways of describing a display mode. The devicetree representation
> +corresponds to the one commonly found in datasheets for displays.
> +The description of the display and its mode is split in two parts: first the display
> +properties like size in mm and (optionally) multiple subnodes with the supported modes.
> +
> +Example:
> +
> + display@0 {
It would be useful to have a compatible string here. We may not always
know the panel type or have a fixed panel though. We could define
"generic-lcd" or something for cases where the panel type is unknown.
> + width-mm = <800>;
> + height-mm = <480>;
> + modes {
> + mode0: mode@0 {
> + /* 1920x1080p24 */
> + clock = <52000000>;
> + hactive = <1920>;
> + vactive = <1080>;
> + hfront-porch = <25>;
> + hback-porch = <25>;
> + hsync-len = <25>;
> + vback-porch = <2>;
> + vfront-porch = <2>;
> + vsync-len = <2>;
> + hsync-active-high;
> + };
> + };
> + };
> +
> +Every property also supports the use of ranges, so the commonly used datasheet
> +description with <min typ max>-tuples can be used.
> +
> +Example:
> +
> + mode1: mode@1 {
> + /* 1920x1080p24 */
> + clock = <148500000>;
> + hactive = <1920>;
> + vactive = <1080>;
> + hsync-len = <0 44 60>;
> + hfront-porch = <80 88 95>;
> + hback-porch = <100 148 160>;
> + vfront-porch = <0 4 6>;
> + vback-porch = <0 36 50>;
> + vsync-len = <0 5 6>;
> + };
> +
> +The videomode can be linked to a connector via phandles. The connector has to
> +support the display- and default-mode-property to link to and select a mode.
Could also be phandle in the lcd controller node? What are the '-' for?
Is "display-blah" a valid name or something?
"default-mode" is pretty generic. How about display-mode or
display-default-mode?
Rob
> +
> +Example:
> +
> + hdmi@00120000 {
> + status = "okay";
> + display = <&benq>;
> + default-mode = <&mode1>;
> + };
> +
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index dfba3e6..a3acaa3 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -83,4 +83,9 @@ config OF_MTD
> depends on MTD
> def_bool y
>
> +config OF_VIDEOMODE
> + def_bool y
> + help
> + helper to parse videomodes from the devicetree
> +
> endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index e027f44..80e6db3 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o
> obj-$(CONFIG_OF_PCI) += of_pci.o
> obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
> obj-$(CONFIG_OF_MTD) += of_mtd.o
> +obj-$(CONFIG_OF_VIDEOMODE) += of_videomode.o
> diff --git a/drivers/of/of_videomode.c b/drivers/of/of_videomode.c
> new file mode 100644
> index 0000000..52bfc74
> --- /dev/null
> +++ b/drivers/of/of_videomode.c
> @@ -0,0 +1,283 @@
> +/*
> + * OF helpers for parsing display modes
> + *
> + * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
> + * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
> + *
> + * This file is released under the GPLv2
> + */
> +#include <linux/of.h>
> +#include <linux/fb.h>
> +#include <linux/export.h>
> +#include <linux/slab.h>
> +#include <drm/drmP.h>
> +#include <drm/drm_crtc.h>
> +#include <linux/of_videomode.h>
> +
> +static u32 of_video_get_value(struct mode_property *prop)
> +{
> + return (prop->min >= prop->typ) ? prop->min : prop->typ;
> +}
> +
> +/* read property into new mode_property */
> +static int of_video_parse_property(struct device_node *np, char *name,
> + struct mode_property *result)
> +{
> + struct property *prop;
> + int length;
> + int cells;
> + int ret;
> +
> + prop = of_find_property(np, name, &length);
> + if (!prop) {
> + pr_err("%s: could not find property %s\n", __func__,
> + name);
> + return -EINVAL;
> + }
> +
> + cells = length / sizeof(u32);
> +
> + memset(result, 0, sizeof(*result));
> +
> + ret = of_property_read_u32_array(np, name, &result->min, cells);
> +
> + return ret;
> +}
> +
> +static int of_video_free(struct display *disp)
> +{
> + int i;
> +
> + for (i=0; i<disp->num_modes; i++)
> + kfree(disp->modes[i]);
> + kfree(disp->modes);
> +
> + return 0;
> +}
> +
> +int videomode_to_display_mode(struct display *disp, struct drm_display_mode *dmode, int index)
> +{
> + struct videomode *vm;
> +
> + memset(dmode, 0, sizeof(*dmode));
> +
> + if (index > disp->num_modes) {
> + pr_err("%s: wrong index: %d from %d\n", __func__, index, disp->num_modes);
> + return -EINVAL;
> + }
> +
> + vm = disp->modes[index];
> +
> + dmode->hdisplay = of_video_get_value(&vm->hactive);
> + dmode->hsync_start = of_video_get_value(&vm->hactive) + of_video_get_value(&vm->hfront_porch);
> + dmode->hsync_end = of_video_get_value(&vm->hactive) + of_video_get_value(&vm->hfront_porch)
> + + of_video_get_value(&vm->hsync_len);
> + dmode->htotal = of_video_get_value(&vm->hactive) + of_video_get_value(&vm->hfront_porch)
> + + of_video_get_value(&vm->hsync_len) + of_video_get_value(&vm->hback_porch);
> +
> + dmode->vdisplay = of_video_get_value(&vm->vactive);
> + dmode->vsync_start = of_video_get_value(&vm->vactive) + of_video_get_value(&vm->vfront_porch);
> + dmode->vsync_end = of_video_get_value(&vm->vactive) + of_video_get_value(&vm->vfront_porch)
> + + of_video_get_value(&vm->vsync_len);
> + dmode->vtotal = of_video_get_value(&vm->vactive) + of_video_get_value(&vm->vfront_porch) +
> + of_video_get_value(&vm->vsync_len) + of_video_get_value(&vm->vback_porch);
> +
> + dmode->width_mm = disp->width_mm;
> + dmode->height_mm = disp->height_mm;
> +
> + dmode->clock = of_video_get_value(&vm->clock) / 1000;
> +
> + if (vm->hah)
> + dmode->flags |= DRM_MODE_FLAG_PHSYNC;
> + else
> + dmode->flags |= DRM_MODE_FLAG_NHSYNC;
> + if (vm->vah)
> + dmode->flags |= DRM_MODE_FLAG_PVSYNC;
> + else
> + dmode->flags |= DRM_MODE_FLAG_NVSYNC;
> + if (vm->interlaced)
> + dmode->flags |= DRM_MODE_FLAG_INTERLACE;
> + if (vm->doublescan)
> + dmode->flags |= DRM_MODE_FLAG_DBLSCAN;
> +
> + drm_mode_set_name(dmode);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(videomode_to_display_mode);
> +
> +int videomode_to_fb_mode(struct display *disp, struct fb_videomode *fbmode, int index)
> +{
> + struct videomode *vm;
> +
> + memset(fbmode, 0, sizeof(*fbmode));
> +
> + if (index > disp->num_modes) {
> + pr_err("%s: wrong index: %d from %d\n", __func__, index, disp->num_modes);
> + return -EINVAL;
> + }
> +
> + vm = disp->modes[index];
> +
> + fbmode->xres = of_video_get_value(&vm->hactive);
> + fbmode->left_margin = of_video_get_value(&vm->hback_porch);
> + fbmode->right_margin = of_video_get_value(&vm->hfront_porch);
> + fbmode->hsync_len = of_video_get_value(&vm->hsync_len);
> +
> + fbmode->yres = of_video_get_value(&vm->vactive);
> + fbmode->upper_margin = of_video_get_value(&vm->vback_porch);
> + fbmode->lower_margin = of_video_get_value(&vm->vfront_porch);
> + fbmode->vsync_len = of_video_get_value(&vm->vsync_len);
> +
> + fbmode->pixclock = KHZ2PICOS(of_video_get_value(&vm->clock) / 1000);
> +
> + if (vm->hah)
> + fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
> + if (vm->vah)
> + fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
> + if (vm->interlaced)
> + fbmode->vmode |= FB_VMODE_INTERLACED;
> + if (vm->doublescan)
> + fbmode->vmode |= FB_VMODE_DOUBLE;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(videomode_to_fb_mode);
> +
> +int of_get_video_modes(struct device_node *np, struct display *disp)
> +{
> + struct device_node *display_np;
> + struct device_node *mode_np;
> + struct device_node *modes_np;
> + char *default_mode;
> +
> + int ret = 0;
> +
> + memset(disp, 0, sizeof(*disp));
> + disp->modes = kmalloc(sizeof(struct videomode*), GFP_KERNEL);
> +
> + if (!np) {
> + pr_err("%s: no node provided\n", __func__);
> + return -EINVAL;
> + }
> +
> + display_np = of_parse_phandle(np, "display", 0);
> +
> + if (!display_np) {
> + pr_err("%s: could not find display node\n", __func__);
> + return -EINVAL;
> + }
> +
> + of_property_read_u32(display_np, "width-mm", &disp->width_mm);
> + of_property_read_u32(display_np, "height-mm", &disp->height_mm);
> +
> + mode_np = of_parse_phandle(np, "default-mode", 0);
> +
> + if (!mode_np) {
> + pr_info("%s: no default-mode specified.\n", __func__);
> + mode_np = of_find_node_by_name(np, "mode");
> + }
> +
> + if (!mode_np) {
> + pr_err("%s: could not find any mode specification\n", __func__);
> + return -EINVAL;
> + }
> +
> + default_mode = (char *)mode_np->full_name;
> +
> + modes_np = of_find_node_by_name(np, "modes");
> + for_each_child_of_node(modes_np, mode_np) {
> + struct videomode *vm;
> +
> + vm = kmalloc(sizeof(struct videomode*), GFP_KERNEL);
> + disp->modes[disp->num_modes] = kmalloc(sizeof(struct videomode*), GFP_KERNEL);
> +
> + ret |= of_video_parse_property(mode_np, "hback-porch", &vm->hback_porch);
> + ret |= of_video_parse_property(mode_np, "hfront-porch", &vm->hfront_porch);
> + ret |= of_video_parse_property(mode_np, "hactive", &vm->hactive);
> + ret |= of_video_parse_property(mode_np, "hsync-len", &vm->hsync_len);
> + ret |= of_video_parse_property(mode_np, "vback-porch", &vm->vback_porch);
> + ret |= of_video_parse_property(mode_np, "vfront-porch", &vm->vfront_porch);
> + ret |= of_video_parse_property(mode_np, "vactive", &vm->vactive);
> + ret |= of_video_parse_property(mode_np, "vsync-len", &vm->vsync_len);
> + ret |= of_video_parse_property(mode_np, "clock", &vm->clock);
> +
> + if (ret)
> + return -EINVAL;
> +
> + vm->hah = of_property_read_bool(mode_np, "hsync-active-high");
> + vm->vah = of_property_read_bool(mode_np, "vsync-active-high");
> + vm->interlaced = of_property_read_bool(mode_np, "interlaced");
> + vm->doublescan = of_property_read_bool(mode_np, "doublescan");
> +
> + if (strcmp(default_mode,mode_np->full_name) = 0)
> + disp->default_mode = disp->num_modes;
> +
> + disp->modes[disp->num_modes] = vm;
> + disp->num_modes++;
> + }
> + of_node_put(display_np);
> +
> + pr_info("%s: found %d modelines. Using #%d as default\n", __func__,
> + disp->num_modes, disp->default_mode + 1);
> +
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_get_video_modes);
> +
> +int of_video_mode_exists(struct device_node *np)
> +{
> + struct device_node *display_np;
> + struct device_node *mode_np;
> +
> + if (!np)
> + return -EINVAL;
> +
> + display_np = of_parse_phandle(np, "display", 0);
> +
> + if (!display_np)
> + return -EINVAL;
> +
> + mode_np = of_parse_phandle(np, "default-mode", 0);
> +
> + if (mode_np)
> + return 0;
> +
> + return -EINVAL;
> +}
> +EXPORT_SYMBOL_GPL(of_video_mode_exists);
> +
> +int of_get_display_mode(struct device_node *np, struct drm_display_mode *dmode, int index)
> +{
> + struct display disp;
> +
> + of_get_video_modes(np, &disp);
> +
> + if (index = OF_MODE_SELECTION)
> + index = disp.default_mode;
> + if (dmode)
> + videomode_to_display_mode(&disp, dmode, index);
> +
> + of_video_free(&disp);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_get_display_mode);
> +
> +int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fbmode, int index)
> +{
> + struct display disp;
> +
> + of_get_video_modes(np, &disp);
> +
> + if (index = OF_MODE_SELECTION)
> + index = disp.default_mode;
> + if (fbmode)
> + videomode_to_fb_mode(&disp, fbmode, index);
> +
> + of_video_free(&disp);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_get_fb_videomode);
> diff --git a/include/linux/of_videomode.h b/include/linux/of_videomode.h
> new file mode 100644
> index 0000000..5571ce3
> --- /dev/null
> +++ b/include/linux/of_videomode.h
> @@ -0,0 +1,56 @@
> +/*
> + * Copyright 2012 Sascha Hauer <s.hauer@pengutronix.de>
> + * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
> + *
> + * OF helpers for videomodes.
> + *
> + * This file is released under the GPLv2
> + */
> +
> +#ifndef __LINUX_OF_VIDEOMODE_H
> +#define __LINUX_OF_VIDEOMODE_H
> +
> +#define OF_MODE_SELECTION -1
> +
> +struct mode_property {
> + u32 min;
> + u32 typ;
> + u32 max;
> +};
> +
> +struct display {
> + u32 width_mm;
> + u32 height_mm;
> + struct videomode **modes;
> + int default_mode;
> + int num_modes;
> +};
> +
> +/* describe videomode in terms of hardware parameters */
> +struct videomode {
> + struct mode_property hback_porch;
> + struct mode_property hfront_porch;
> + struct mode_property hactive;
> + struct mode_property hsync_len;
> +
> + struct mode_property vback_porch;
> + struct mode_property vfront_porch;
> + struct mode_property vactive;
> + struct mode_property vsync_len;
> +
> + struct mode_property clock;
> +
> + bool hah;
> + bool vah;
> + bool interlaced;
> + bool doublescan;
> +};
> +
> +int of_video_mode_exists(struct device_node *np);
> +int videomode_to_display_mode(struct display *disp, struct drm_display_mode *dmode, int index);
> +int videomode_to_fb_mode(struct display *disp, struct fb_videomode *fbmode, int index);
> +int of_get_video_modes(struct device_node *np, struct display *disp);
> +int of_video_mode_exists(struct device_node *np);
> +int of_get_display_mode(struct device_node *np, struct drm_display_mode *dmode, int index);
> +int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fbmode, int index);
> +#endif /* __LINUX_OF_VIDEOMODE_H */
>
^ permalink raw reply
* Re: [PATCH] video: exynos_dp: Add device tree support to DP driver
From: Ajay kumar @ 2012-09-24 12:59 UTC (permalink / raw)
To: Jingoo Han
Cc: Ajay Kumar, FlorianSchandinat, linux-samsung-soc, linux-fbdev,
thomas.ab, Leela Krishna Amudala
In-Reply-To: <008d01cd9725$a096e480$e1c4ad80$%han@samsung.com>
Hi Jingoo,
I have addressed all your comments and have sent the V3 Patch.
Regards,
Ajay Kumar
On Thu, Sep 20, 2012 at 5:16 PM, Jingoo Han <jg1.han@samsung.com> wrote:
> On Friday, September 14, 2012 3:40 AM Ajay Kumar wrote
>>
>> This patch enables device tree based discovery support for DP driver.
>> The driver is modified to handle platform data in both the cases:
>> with DT and non-DT.
>>
>> DP-PHY should be regarded as a seperate device node while
>> being passed from device tree list, and device node for
>> DP should contain DP-PHY as child node with property name "dp-phy"
>> associated with it.
>
> Hi Ajay,
>
> Thank you for sending the patch for Device Tree support.
> I tested the patch with Exynos5250.
>
> As Leela Krishna Amudala mentioned, please post the documentation
> for the bindings.
>
> Also, I added some comments for minor fix.
>
> Best regards,
> Jingoo Han
>
>>
>> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
>> ---
>> drivers/video/exynos/exynos_dp_core.c | 156 +++++++++++++++++++++++++++++++--
>> drivers/video/exynos/exynos_dp_core.h | 2 +
>> 2 files changed, 151 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
>> index f57c915..15887bd 100644
>> --- a/drivers/video/exynos/exynos_dp_core.c
>> +++ b/drivers/video/exynos/exynos_dp_core.c
>> @@ -18,6 +18,7 @@
>> #include <linux/io.h>
>> #include <linux/interrupt.h>
>> #include <linux/delay.h>
>> +#include <linux/of.h>
>>
>> #include <video/exynos_dp.h>
>>
>> @@ -856,20 +857,117 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
>> return IRQ_HANDLED;
>> }
>>
>> +#ifdef CONFIG_OF
>> +struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
>> +{
>> + struct device_node *dp_node = dev->of_node;
>> + struct exynos_dp_platdata *pd;
>> + struct video_info *dp_video_config;
>> +
>> + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
>> + if (!pd) {
>> + dev_err(dev, "memory allocation for pdata failed\n");
>> + return ERR_PTR(-ENOMEM);
>> + }
>> + dp_video_config = devm_kzalloc(dev,
>> + sizeof(*dp_video_config), GFP_KERNEL);
>> +
>> + if (!dp_video_config) {
>> + dev_err(dev, "memory allocation for video config failed\n");
>> + return ERR_PTR(-ENOMEM);
>> + }
>> + pd->video_info = dp_video_config;
>> +
>> + if (of_get_property(dp_node, "samsung,h-sync-polarity", NULL))
>> + dp_video_config->h_sync_polarity = 1;
>> +
>> + if (of_get_property(dp_node, "samsung,v-sync-polarity", NULL))
>> + dp_video_config->v_sync_polarity = 1;
>> +
>> + if (of_get_property(dp_node, "samsung,interlaced", NULL))
>> + dp_video_config->interlaced = 1;
>> +
>> + of_property_read_u32(dp_node, "samsung,color_space",
>> + &dp_video_config->color_space);
>> +
>> + of_property_read_u32(dp_node, "samsung,dynamic_range",
>> + &dp_video_config->dynamic_range);
>> +
>> + of_property_read_u32(dp_node, "samsung,ycbcr_coeff",
>> + &dp_video_config->ycbcr_coeff);
>> +
>> + of_property_read_u32(dp_node, "samsung,color_depth",
>> + &dp_video_config->color_depth);
>> +
>> + of_property_read_u32(dp_node, "samsung,link_rate",
>> + &dp_video_config->link_rate);
>> +
>> + of_property_read_u32(dp_node, "samsung,lane_count",
>> + &dp_video_config->lane_count);
>> + return pd;
>> +}
>> +
>> +void exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
>> +{
>> + struct device_node *dp_phy_node;
>> +
>> + const __be32 *parp;
>> +
>> + u32 phy_base;
>> +
>> + void *virt_phy_base;
>
> Please, remove unnecessary spaces between variables.
>
>
>> +
>> + parp = of_get_property(dp->dev->of_node, "dp_phy", NULL);
>> + if (!parp) {
>> + dp->dp_phy_addr = NULL;
>> + return;
>> + }
>> +
>> + dp_phy_node = of_find_node_by_phandle(be32_to_cpup(parp));
>> + if (!dp_phy_node) {
>> + dp->dp_phy_addr = NULL;
>> + return;
>> + }
>> +
>> + of_property_read_u32(dp_phy_node, "samsung,dptx_phy_reg", &phy_base);
>> + of_property_read_u32(dp_phy_node, "samsung,enable_bit",
>> + &dp->enable_bit);
>> + virt_phy_base = ioremap(phy_base, SZ_4);
>> + if (!virt_phy_base) {
>> + dev_err(dp->dev, "failed to ioremap dp-phy\n");
>> + dp->dp_phy_addr = NULL;
>> + return;
>> + }
>> + dp->dp_phy_addr = virt_phy_base;
>> +}
>> +
>> +void dp_phy_init(struct exynos_dp_device *dp)
>
> Use exynos_dp_phy_init.
>
>> +{
>> + u32 reg;
>> +
>> + reg = __raw_readl(dp->dp_phy_addr);
>> + reg |= dp->enable_bit;
>> + __raw_writel(reg, dp->dp_phy_addr);
>> +}
>> +
>> +void dp_phy_exit(struct exynos_dp_device *dp)
>
> Use exynos_dp_phy_exit.
>
>> +{
>> + u32 reg;
>> +
>> + reg = __raw_readl(dp->dp_phy_addr);
>> + reg &= ~(dp->enable_bit);
>> + __raw_writel(reg, dp->dp_phy_addr);
>> +}
>> +#endif /* CONFIG_OF */
>> +
>> static int __devinit exynos_dp_probe(struct platform_device *pdev)
>> {
>> struct resource *res;
>> struct exynos_dp_device *dp;
>> - struct exynos_dp_platdata *pdata;
>> + struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
>>
>> int ret = 0;
>>
>> - pdata = pdev->dev.platform_data;
>> - if (!pdata) {
>> - dev_err(&pdev->dev, "no platform data\n");
>> - return -EINVAL;
>> - }
>> -
>> dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
>> GFP_KERNEL);
>> if (!dp) {
>> @@ -879,6 +982,19 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
>>
>> dp->dev = &pdev->dev;
>>
>> + if (pdev->dev.of_node) {
>> + pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
>> + if (IS_ERR(pdata))
>> + return PTR_ERR(pdata);
>> +
>> + exynos_dp_dt_parse_phydata(dp);
>> + }
>
> I would like to use the style as follows.
>
> if (pdev->dev.of_node) {
> DT case
> else
> Non-DT case
>
> Could you modify it as follows?
>
> + if (pdev->dev.of_node) {
> + pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
> + if (IS_ERR(pdata))
> + return PTR_ERR(pdata);
> +
> + exynos_dp_dt_parse_phydata(dp);
> + } else {
> + pdata = pdev->dev.platform_data;
> + }
>
>
>> +
>> + if (!pdata) {
>> + dev_err(&pdev->dev, "no platform data\n");
>> + return -EINVAL;
>> + }
>> +
>> dp->clock = devm_clk_get(&pdev->dev, "dp");
>> if (IS_ERR(dp->clock)) {
>> dev_err(&pdev->dev, "failed to get clock\n");
>> @@ -909,9 +1025,13 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
>> }
>>
>> dp->video_info = pdata->video_info;
>> if (pdata->phy_init)
>> pdata->phy_init();
>>
>> + if (pdev->dev.of_node)
>> + if (dp->dp_phy_addr)
>> + dp_phy_init(dp);
>> +
>
> Could you modify it as follows?
> phy_init() and dp_phy_init(dp) cannot be used simultaneously.
> So, it seems to be clearer.
>
> - if (pdata->phy_init)
> - pdata->phy_init();
> +
> + if (pdev->dev.of_node) {
> + if (dp->dp_phy_addr)
> + dp_phy_init(dp);
> + } else {
> + if (pdata->phy_init)
> + pdata->phy_init();
> + }
>
>
>> exynos_dp_init_dp(dp);
>>
>> ret = exynos_dp_detect_hpd(dp);
>> @@ -956,6 +1077,10 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
>> if (pdata && pdata->phy_exit)
>> pdata->phy_exit();
>>
>> + if (pdev->dev.of_node)
>> + if (dp->dp_phy_addr)
>> + dp_phy_exit(dp);
>> +
>
> Same as above.
>
>> clk_disable(dp->clock);
>>
>> return 0;
>> @@ -971,6 +1096,10 @@ static int exynos_dp_suspend(struct device *dev)
>> if (pdata && pdata->phy_exit)
>> pdata->phy_exit();
>>
>> + if (dev->of_node)
>> + if (dp->dp_phy_addr)
>> + dp_phy_exit(dp);
>> +
>
> Same as above.
>
>> clk_disable(dp->clock);
>>
>> return 0;
>> @@ -985,6 +1114,10 @@ static int exynos_dp_resume(struct device *dev)
>> if (pdata && pdata->phy_init)
>> pdata->phy_init();
>>
>> + if (dev->of_node)
>> + if (dp->dp_phy_addr)
>> + dp_phy_init(dp);
>> +
>
> Same as above.
>
>> clk_enable(dp->clock);
>>
>> exynos_dp_init_dp(dp);
>> @@ -1013,6 +1146,14 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
>> SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
>> };
>>
>> +#ifdef CONFIG_OF
>> +static const struct of_device_id exynos_dp_match[] = {
>> + { .compatible = "samsung,exynos5-dp" },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, exynos_dp_match);
>> +#endif
>> +
>> static struct platform_driver exynos_dp_driver = {
>> .probe = exynos_dp_probe,
>> .remove = __devexit_p(exynos_dp_remove),
>> @@ -1020,6 +1161,7 @@ static struct platform_driver exynos_dp_driver = {
>> .name = "exynos-dp",
>> .owner = THIS_MODULE,
>> .pm = &exynos_dp_pm_ops,
>> + .of_match_table = of_match_ptr(exynos_dp_match),
>> },
>> };
>>
>> diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
>> index 57b8a65..49b30cb 100644
>> --- a/drivers/video/exynos/exynos_dp_core.h
>> +++ b/drivers/video/exynos/exynos_dp_core.h
>> @@ -29,6 +29,8 @@ struct exynos_dp_device {
>> struct clk *clock;
>> unsigned int irq;
>> void __iomem *reg_base;
>> + void __iomem *dp_phy_addr;
>> + int enable_bit;
>
> How about replacing 'int' with 'unsigned int'?
> unsigned number would be better for the bit definition.
>
>>
>> struct video_info *video_info;
>> struct link_train link_train;
>> --
>> 1.7.0.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH V3] video: exynos_dp: Add device tree support to DP driver
From: Ajay Kumar @ 2012-09-24 12:45 UTC (permalink / raw)
To: linux-samsung-soc, linux-fbdev, jg1.han; +Cc: FlorianSchandinat, thomas.ab
This patch enables device tree based discovery support for DP driver.
The driver is modified to handle platform data in both the cases:
with DT and non-DT.
Documentation is also added for the DT bindings.
DP-PHY should be regarded as a seperate device node while
being passed from device tree list, and device node for
DP should contain DP-PHY as child node with property name "dp-phy"
associated with it.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
---
.../devicetree/bindings/video/exynos_dp.txt | 83 ++++++++++
drivers/video/exynos/exynos_dp_core.c | 168 ++++++++++++++++++--
drivers/video/exynos/exynos_dp_core.h | 2 +
3 files changed, 239 insertions(+), 14 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/exynos_dp.txt
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
new file mode 100644
index 0000000..c27f892
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -0,0 +1,83 @@
+Exynos Displayport driver should configure the displayport interface
+based on the type of panel connected to it.
+
+We use two nodes:
+ -dptx_phy node
+ -display-port-controller node
+
+For the dp-phy initialization, we use a dptx_phy node.
+Required properties for dptx_phy:
+ -compatible:
+ Should be "samsung,dp-phy".
+ -samsung,dptx_phy_reg:
+ Base address of DP PHY register.
+ -samsung,enable_bit:
+ The bit used to enable/disable DP PHY.
+
+For the Panel initialization, we read data from display-port-controller node.
+Required properties for display-port-controller:
+ -compatible:
+ Should be "samsung,exynos5-dp".
+ -reg:
+ physical base address of the controller and length
+ of memory mapped region.
+ -interrupts:
+ Internet combiner values.
+ -interrupt-parent:
+ Address of Interrupt combiner node.
+ -dp_phy:
+ Address of dptx_phy node.
+ -samsung,color_space:
+ input video data format.
+ COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
+ -samsung,dynamic_range:
+ dynamic range for input video data.
+ VESA = 0, CEA = 1
+ -samsung,ycbcr_coeff:
+ YCbCr co-efficients for input video.
+ COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
+ -samsung,color_depth:
+ Bit per color component.
+ COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
+ -samsung,link_rate:
+ link rates supportd by the panel.
+ LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
+ -samsung,lane_count:
+ number of lanes supported by the panel.
+ LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+ -samsung,interlaced:
+ Interlace scan mode.
+ Progressive if defined, Interlaced if not defined
+ -samsung,v_sync_polarity:
+ VSYNC polarity configuration.
+ High if defined, Low if not defined
+ -samsung,h_sync_polarity:
+ HSYNC polarity configuration.
+ High if defined, Low if not defined
+
+Example:
+
+SOC specific portion:
+ dptx_phy: dptx_phy@0x10040720 {
+ compatible = "samsung,dp-phy";
+ samsung,dptx_phy_reg = <0x10040720>;
+ samsung,enable_bit = <1>;
+ };
+
+ display-port-controller {
+ compatible = "samsung,exynos5-dp";
+ reg = <0x145B0000 0x10000>;
+ interrupts = <10 3>;
+ interrupt-parent = <&combiner>;
+ dp_phy = <&dptx_phy>;
+ };
+
+Board Specific portion:
+ display-port-controller {
+ samsung,color_space = <0>;
+ samsung,dynamic_range = <0>;
+ samsung,ycbcr_coeff = <0>;
+ samsung,color_depth = <1>;
+ samsung,link_rate = <0x0a>;
+ samsung,lane_count = <2>;
+ };
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index cdc1398..bb0f10c 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/of.h>
#include <video/exynos_dp.h>
@@ -856,6 +857,106 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
}
+#ifdef CONFIG_OF
+struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ struct device_node *dp_node = dev->of_node;
+ struct exynos_dp_platdata *pd;
+ struct video_info *dp_video_config;
+
+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ dev_err(dev, "memory allocation for pdata failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ dp_video_config = devm_kzalloc(dev,
+ sizeof(*dp_video_config), GFP_KERNEL);
+
+ if (!dp_video_config) {
+ dev_err(dev, "memory allocation for video config failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ pd->video_info = dp_video_config;
+
+ if (of_get_property(dp_node, "samsung,h-sync-polarity", NULL))
+ dp_video_config->h_sync_polarity = 1;
+
+ if (of_get_property(dp_node, "samsung,v-sync-polarity", NULL))
+ dp_video_config->v_sync_polarity = 1;
+
+ if (of_get_property(dp_node, "samsung,interlaced", NULL))
+ dp_video_config->interlaced = 1;
+
+ of_property_read_u32(dp_node, "samsung,color_space",
+ &dp_video_config->color_space);
+
+ of_property_read_u32(dp_node, "samsung,dynamic_range",
+ &dp_video_config->dynamic_range);
+
+ of_property_read_u32(dp_node, "samsung,ycbcr_coeff",
+ &dp_video_config->ycbcr_coeff);
+
+ of_property_read_u32(dp_node, "samsung,color_depth",
+ &dp_video_config->color_depth);
+
+ of_property_read_u32(dp_node, "samsung,link_rate",
+ &dp_video_config->link_rate);
+
+ of_property_read_u32(dp_node, "samsung,lane_count",
+ &dp_video_config->lane_count);
+ return pd;
+}
+
+void exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ struct device_node *dp_phy_node;
+ const __be32 *parp;
+ u32 phy_base;
+ void *virt_phy_base;
+
+ parp = of_get_property(dp->dev->of_node, "dp_phy", NULL);
+ if (!parp) {
+ dp->dp_phy_addr = NULL;
+ return;
+ }
+
+ dp_phy_node = of_find_node_by_phandle(be32_to_cpup(parp));
+ if (!dp_phy_node) {
+ dp->dp_phy_addr = NULL;
+ return;
+ }
+
+ of_property_read_u32(dp_phy_node, "samsung,dptx_phy_reg", &phy_base);
+ of_property_read_u32(dp_phy_node, "samsung,enable_bit",
+ &dp->enable_bit);
+ virt_phy_base = ioremap(phy_base, SZ_4);
+ if (!virt_phy_base) {
+ dev_err(dp->dev, "failed to ioremap dp-phy\n");
+ dp->dp_phy_addr = NULL;
+ return;
+ }
+ dp->dp_phy_addr = virt_phy_base;
+}
+
+void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->dp_phy_addr);
+ reg |= dp->enable_bit;
+ __raw_writel(reg, dp->dp_phy_addr);
+}
+
+void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->dp_phy_addr);
+ reg &= ~(dp->enable_bit);
+ __raw_writel(reg, dp->dp_phy_addr);
+}
+#endif /* CONFIG_OF */
+
static int __devinit exynos_dp_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -864,12 +965,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
int ret = 0;
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
GFP_KERNEL);
if (!dp) {
@@ -879,6 +974,21 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->dev = &pdev->dev;
+ if (pdev->dev.of_node) {
+ pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+
+ exynos_dp_dt_parse_phydata(dp);
+ } else {
+ pdata = pdev->dev.platform_data;
+ }
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -EINVAL;
+ }
+
dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(&pdev->dev, "failed to get clock\n");
@@ -909,8 +1019,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
}
dp->video_info = pdata->video_info;
- if (pdata->phy_init)
- pdata->phy_init();
+
+ if (pdev->dev.of_node) {
+ if (dp->dp_phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata->phy_init)
+ pdata->phy_init();
+ }
exynos_dp_init_dp(dp);
@@ -953,8 +1069,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ if (pdev->dev.of_node) {
+ if (dp->dp_phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata && pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable(dp->clock);
@@ -968,8 +1089,13 @@ static int exynos_dp_suspend(struct device *dev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ if (dev->of_node) {
+ if (dp->dp_phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata && pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable(dp->clock);
@@ -982,8 +1108,13 @@ static int exynos_dp_resume(struct device *dev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_init)
- pdata->phy_init();
+ if (dev->of_node) {
+ if (dp->dp_phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata && pdata->phy_init)
+ pdata->phy_init();
+ }
clk_enable(dp->clock);
@@ -1013,6 +1144,14 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
};
+#ifdef CONFIG_OF
+static const struct of_device_id exynos_dp_match[] = {
+ { .compatible = "samsung,exynos5-dp" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+#endif
+
static struct platform_driver exynos_dp_driver = {
.probe = exynos_dp_probe,
.remove = __devexit_p(exynos_dp_remove),
@@ -1020,6 +1159,7 @@ static struct platform_driver exynos_dp_driver = {
.name = "exynos-dp",
.owner = THIS_MODULE,
.pm = &exynos_dp_pm_ops,
+ .of_match_table = of_match_ptr(exynos_dp_match),
},
};
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a65..c9f8c97 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -29,6 +29,8 @@ struct exynos_dp_device {
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
+ void __iomem *dp_phy_addr;
+ unsigned int enable_bit;
struct video_info *video_info;
struct link_train link_train;
--
1.7.0.4
^ permalink raw reply related
* linux-next: manual merge of the arm-soc tree with the fbdev tree
From: Stephen Rothwell @ 2012-09-24 9:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20120924191508.6100b0603d2642c1e7a36679@canb.auug.org.au>
[-- Attachment #1: Type: text/plain, Size: 1755 bytes --]
Hi all,
Today's linux-next merge of the arm-soc tree got conflicts in
drivers/video/msm/mddi.c, drivers/video/msm/mdp.c and
drivers/video/msm/mdp_hw.h between commit 8abf0b31e161 ("video: msm:
Remove useless mach/* includes") from the fbdev tree and commit
1ef21f6343ff ("ARM: msm: move platform_data definitions") from the
arm-soc tree.
I fixed it up (see below) and can carry the fix as necessary (no action
is required).
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc drivers/video/msm/mddi.c
index d43e178,bf73f04..0000000
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@@ -26,7 -26,10 +26,7 @@@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/sched.h>
- #include <mach/msm_fb.h>
-#include <mach/msm_iomap.h>
-#include <mach/irqs.h>
-#include <mach/board.h>
+ #include <linux/platform_data/video-msm_fb.h>
#include "mddi_hw.h"
#define FLAG_DISABLE_HIBERNATION 0x0001
diff --cc drivers/video/msm/mdp.c
index 7570908,d1f881e..0000000
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@@ -25,7 -25,8 +25,7 @@@
#include <linux/major.h>
#include <linux/slab.h>
- #include <mach/msm_fb.h>
-#include <mach/msm_iomap.h>
+ #include <linux/platform_data/video-msm_fb.h>
#include <linux/platform_device.h>
#include <linux/export.h>
diff --cc drivers/video/msm/mdp_hw.h
index 2a84137,a0bacf5..0000000
--- a/drivers/video/msm/mdp_hw.h
+++ b/drivers/video/msm/mdp_hw.h
@@@ -15,7 -15,8 +15,7 @@@
#ifndef _MDP_HW_H_
#define _MDP_HW_H_
- #include <mach/msm_fb.h>
-#include <mach/msm_iomap.h>
+ #include <linux/platform_data/video-msm_fb.h>
struct mdp_info {
struct mdp_device mdp_dev;
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* linux-next: manual merge of the arm-soc tree with the fbdev tree
From: Stephen Rothwell @ 2012-09-24 9:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20120924191508.6100b0603d2642c1e7a36679@canb.auug.org.au>
[-- Attachment #1: Type: text/plain, Size: 1109 bytes --]
Hi all,
Today's linux-next merge of the arm-soc tree got a conflict in
arch/arm/mach-s3c64xx/mach-real6410.c between commit 5a213a55c6d3
("include/video: move fimd register headers from platform to
include/video") from the fbdev tree and commit 436d42c61c3e ("ARM:
samsung: move platform_data definitions") from the arm-soc tree.
I fixed it up (see below) and can carry the fix as necessary (no action
is required).
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc arch/arm/mach-s3c64xx/mach-real6410.c
index 76d3ffb,6daca20..0000000
--- a/arch/arm/mach-s3c64xx/mach-real6410.c
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@@ -39,12 -39,12 +39,12 @@@
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/fb.h>
- #include <plat/nand.h>
+ #include <linux/platform_data/mtd-nand-s3c2410.h>
#include <plat/regs-serial.h>
- #include <plat/ts.h>
+ #include <linux/platform_data/touchscreen-s3c2410.h>
-#include <plat/regs-fb-v4.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include "common.h"
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* linux-next: manual merge of the arm-soc tree with the fbdev tree
From: Stephen Rothwell @ 2012-09-24 9:15 UTC (permalink / raw)
To: linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 1105 bytes --]
Hi all,
Today's linux-next merge of the arm-soc tree got a conflict in arch/arm/mach-s3c64xx/mach-mini6410.c between commit 5a213a55c6d3 ("include/video: move fimd register headers from platform to include/video") from the fbdev tree and commit 436d42c61c3e ("ARM: samsung: move platform_data definitions") from the arm-soc tree.
I fixed it up (see below) and can carry the fix as necessary (no action
is required).
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc arch/arm/mach-s3c64xx/mach-mini6410.c
index 96ebcc5,09311cc..0000000
--- a/arch/arm/mach-s3c64xx/mach-mini6410.c
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@@ -38,12 -38,12 +38,12 @@@
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/fb.h>
- #include <plat/nand.h>
+ #include <linux/platform_data/mtd-nand-s3c2410.h>
#include <plat/regs-serial.h>
- #include <plat/ts.h>
+ #include <linux/platform_data/touchscreen-s3c2410.h>
-#include <plat/regs-fb-v4.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include "common.h"
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [RFC PATCH 1/3] amba-clcd: Add Device Tree support to amba-clcd driver
From: Ryan Harkin @ 2012-09-24 7:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20120921121903.GE15609@n2100.arm.linux.org.uk>
Thanks for all the comments.
Pawel, good point about the framebuffer. Fixing this will also
address one of Russell's concerns. I don't know how to use a phandle,
so I have some reading to do.
Russell, all good points and exactly the type of feedback I needed.
I'll re-work your suggestions into my code and re-post a V2 of the
patches.
Sascha, I see your point. I'll work on the feedback above first
before getting to looking at how to handle the thread you linked to.
Thanks all,
Regards,
Ryan.
^ permalink raw reply
* [PATCH] OMAPDSS: DISPC: Add predecimation limit for TILER based rotations
From: Chandrabhanu Mahapatra @ 2012-09-24 6:50 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra
In OMAP4 and OMAP5 when TILER 2D burst mode is used, a maximum of one line can
be skipped as per the respective TRMs. The MBlockStride OCP signal, which is
sum of ROWINC and image width in memory, is only 17 bits wide. In 2D mode TILER
supports 8192, 16384, 32768 and 65536 values of MBlockStride. In case when 2 or
more lines are skipped the ROWINC value exceeds 65536 resulting in OCP errors.
So, maximum vertical predecimation achievable is 2.
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
drivers/video/omap2/dss/dispc.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index d512c38..61f8369 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2195,7 +2195,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
- int *x_predecim, int *y_predecim, u16 pos_x)
+ int *x_predecim, int *y_predecim, u16 pos_x,
+ enum omap_dss_rotation_type rotation_type)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
@@ -2210,7 +2211,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
return -EINVAL;
*x_predecim = max_decim_limit;
- *y_predecim = max_decim_limit;
+ *y_predecim = (rotation_type = OMAP_DSS_ROT_TILER &&
+ dss_has_feature(FEAT_BURST_2D)) ? 2 : max_decim_limit;
if (color_mode = OMAP_DSS_COLOR_CLUT1 ||
color_mode = OMAP_DSS_COLOR_CLUT2 ||
@@ -2306,7 +2308,8 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width,
in_height, out_width, out_height, oi->color_mode,
- &five_taps, &x_predecim, &y_predecim, oi->pos_x);
+ &five_taps, &x_predecim, &y_predecim, oi->pos_x,
+ oi->rotation_type);
if (r)
return r;
--
1.7.10
^ permalink raw reply related
* Re: [PATCH v2 1/2] video: exynos_mipi_dsi: Remove unused code
From: Florian Tobias Schandinat @ 2012-09-23 19:54 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1348204007-1347-1-git-send-email-sachin.kamat@linaro.org>
Applied both patches of this series.
Thanks,
Florian Tobias Schandinat
On 09/21/2012 05:06 AM, Sachin Kamat wrote:
> This code is never executed and hence removed.
>
> Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
> Acked-by: Inki Dae <inki.dae@samsung.com>
>
> ---
> drivers/video/exynos/exynos_mipi_dsi_common.c | 3 ---
> 1 files changed, 0 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c
> index 47b533a..7cc4113 100644
> --- a/drivers/video/exynos/exynos_mipi_dsi_common.c
> +++ b/drivers/video/exynos/exynos_mipi_dsi_common.c
> @@ -288,9 +288,6 @@ int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
> mutex_unlock(&dsim->lock);
> return -EINVAL;
> }
> -
> - mutex_unlock(&dsim->lock);
> - return 0;
> }
>
> static unsigned int exynos_mipi_dsi_long_data_rd(struct mipi_dsim_device *dsim,
^ permalink raw reply
* Re: [PATCH 01/10] drivers/video/mb862xx/mb862xxfbdrv.c: fix error return code
From: Florian Tobias Schandinat @ 2012-09-23 19:52 UTC (permalink / raw)
To: Peter Senna Tschudin
Cc: paul.gortmaker, hsweeten, agust, davidb, linux-fbdev,
linux-kernel, kernel-janitors
In-Reply-To: <1347970080-25175-1-git-send-email-peter.senna@gmail.com>
Applied all 10 patches of this series.
Thanks,
Florian Tobias Schandinat
On 09/18/2012 12:07 PM, Peter Senna Tschudin wrote:
> From: Peter Senna Tschudin <peter.senna@gmail.com>
>
> Convert a nonnegative error return code to a negative one, as returned
> elsewhere in the function.
>
> A simplified version of the semantic match that finds this problem is as
> follows: (http://coccinelle.lip6.fr/)
>
> // <smpl>
> (
> if@p1 (\(ret < 0\|ret != 0\))
> { ... return ret; }
> |
> ret@p1 = 0
> )
> ... when != ret = e1
> when != &ret
> *if(...)
> {
> ... when != ret = e2
> when forall
> return ret;
> }
> // </smpl>
>
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> ---
> drivers/video/mb862xx/mb862xxfbdrv.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c
> index 57d940b..d68e332 100644
> --- a/drivers/video/mb862xx/mb862xxfbdrv.c
> +++ b/drivers/video/mb862xx/mb862xxfbdrv.c
> @@ -1052,12 +1052,14 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
> break;
> default:
> /* should never occur */
> + ret = -EIO;
> goto rel_reg;
> }
>
> par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram);
> if (par->fb_base = NULL) {
> dev_err(dev, "Cannot map framebuffer\n");
> + ret = -EIO;
> goto rel_reg;
> }
>
> @@ -1073,11 +1075,13 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
> dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n",
> (unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len);
>
> - if (mb862xx_pci_gdc_init(par))
> + ret = mb862xx_pci_gdc_init(par);
> + if (ret)
> goto io_unmap;
>
> - if (request_irq(par->irq, mb862xx_intr, IRQF_SHARED,
> - DRV_NAME, (void *)par)) {
> + ret = request_irq(par->irq, mb862xx_intr, IRQF_SHARED,
> + DRV_NAME, (void *)par);
> + if (ret) {
> dev_err(dev, "Cannot request irq\n");
> goto io_unmap;
> }
^ permalink raw reply
* Re: [PATCH] video: exynos_dp: increase AUX channel voltage level
From: Florian Tobias Schandinat @ 2012-09-23 19:50 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <003e01cd90bb$8332a1b0$8997e510$%han@samsung.com>
On 09/12/2012 07:52 AM, Jingoo Han wrote:
> The value of AUX channel differential amplitude current is changed
> from 8 mA to 16 mA, in order to increase AUX channel voltage level.
> In this case, AUX channel voltage level can be changed from 400 mV
> to 800 mV, when resistance between AUX TX and RX is 100 ohm.
>
> According to DP spec, although the normative voltage level is 390 mV,
> the informative voltage level is 430 mV. So, 800 mV can be helpful
> to improve voltage margin of AUX channel.
>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Applied. But it might be a good idea to keep the old definition in the
header file for documentation purposes.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/exynos/exynos_dp_reg.c | 2 +-
> drivers/video/exynos/exynos_dp_reg.h | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
> index 20e441f..5fd1214 100644
> --- a/drivers/video/exynos/exynos_dp_reg.c
> +++ b/drivers/video/exynos/exynos_dp_reg.c
> @@ -77,7 +77,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
> writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
>
> reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
> - TX_CUR1_2X | TX_CUR_8_MA;
> + TX_CUR1_2X | TX_CUR_16_MA;
> writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
>
> reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
> diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
> index 125b27c..0e79031 100644
> --- a/drivers/video/exynos/exynos_dp_reg.h
> +++ b/drivers/video/exynos/exynos_dp_reg.h
> @@ -187,7 +187,7 @@
> #define PD_RING_OSC (0x1 << 6)
> #define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4)
> #define TX_CUR1_2X (0x1 << 2)
> -#define TX_CUR_8_MA (0x2 << 0)
> +#define TX_CUR_16_MA (0x3 << 0)
>
> /* EXYNOS_DP_TX_AMP_TUNING_CTL */
> #define CH3_AMP_400_MV (0x0 << 24)
^ permalink raw reply
* Re: [PATCH] video: exynos_dp: add bit-masking for LINK_TRAINING_CTL register
From: Florian Tobias Schandinat @ 2012-09-23 19:46 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <002701cd909f$e2b2c960$a8185c20$%han@samsung.com>
On 09/12/2012 04:34 AM, Jingoo Han wrote:
> This patch adds bit-masking for LINK_TRAINING_CTL register, when
> pre-emphasis level is set. The bit 3 and bit 2 of LINK_TRAINING_CTL
> register are used for pre-emphasis level setting, so other bits
> should be masked.
>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/exynos/exynos_dp_reg.c | 16 ++++++++++++----
> drivers/video/exynos/exynos_dp_reg.h | 1 +
> 2 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
> index 20e441f..365be69 100644
> --- a/drivers/video/exynos/exynos_dp_reg.c
> +++ b/drivers/video/exynos/exynos_dp_reg.c
> @@ -895,7 +895,9 @@ void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level)
> {
> u32 reg;
>
> - reg = level << PRE_EMPHASIS_SET_SHIFT;
> + reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
> + reg &= ~PRE_EMPHASIS_SET_MASK;
> + reg |= level << PRE_EMPHASIS_SET_SHIFT;
> writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
> }
>
> @@ -903,7 +905,9 @@ void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level)
> {
> u32 reg;
>
> - reg = level << PRE_EMPHASIS_SET_SHIFT;
> + reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
> + reg &= ~PRE_EMPHASIS_SET_MASK;
> + reg |= level << PRE_EMPHASIS_SET_SHIFT;
> writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
> }
>
> @@ -911,7 +915,9 @@ void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level)
> {
> u32 reg;
>
> - reg = level << PRE_EMPHASIS_SET_SHIFT;
> + reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
> + reg &= ~PRE_EMPHASIS_SET_MASK;
> + reg |= level << PRE_EMPHASIS_SET_SHIFT;
> writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
> }
>
> @@ -919,7 +925,9 @@ void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
> {
> u32 reg;
>
> - reg = level << PRE_EMPHASIS_SET_SHIFT;
> + reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
> + reg &= ~PRE_EMPHASIS_SET_MASK;
> + reg |= level << PRE_EMPHASIS_SET_SHIFT;
> writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
> }
>
> diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
> index 125b27c..9e9af50 100644
> --- a/drivers/video/exynos/exynos_dp_reg.h
> +++ b/drivers/video/exynos/exynos_dp_reg.h
> @@ -285,6 +285,7 @@
> #define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0)
>
> /* EXYNOS_DP_LN0_LINK_TRAINING_CTL */
> +#define PRE_EMPHASIS_SET_MASK (0x3 << 3)
> #define PRE_EMPHASIS_SET_SHIFT (3)
>
> /* EXYNOS_DP_DEBUG_CTL */
^ permalink raw reply
* Re: [PATCH 2/2] video: s3c2410: fix checkpatch warnings
From: Florian Tobias Schandinat @ 2012-09-23 19:46 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <002d01cd8f42$c06b6690$414233b0$%han@samsung.com>
On 09/10/2012 10:55 AM, Jingoo Han wrote:
> This patch fixes the checkpatch warnings listed below:
>
> WARNING: usleep_range should not use min = max args; see Documentation/timers/timers-howto.txt
> WARNING: quoted string split across lines
>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/s3c2410fb.c | 12 ++++++------
> 1 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
> index 1aa37ea..1083bb9 100644
> --- a/drivers/video/s3c2410fb.c
> +++ b/drivers/video/s3c2410fb.c
> @@ -935,7 +935,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
> clk_enable(info->clk);
> dprintk("got and enabled clock\n");
>
> - usleep_range(1000, 1000);
> + usleep_range(1000, 1100);
>
> info->clk_rate = clk_get_rate(info->clk);
>
> @@ -1034,7 +1034,7 @@ static int __devexit s3c2410fb_remove(struct platform_device *pdev)
> s3c2410fb_cpufreq_deregister(info);
>
> s3c2410fb_lcd_enable(info, 0);
> - usleep_range(1000, 1000);
> + usleep_range(1000, 1100);
>
> s3c2410fb_unmap_video_memory(fbinfo);
>
> @@ -1071,7 +1071,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
> * the LCD DMA engine is not going to get back on the bus
> * before the clock goes off again (bjd) */
>
> - usleep_range(1000, 1000);
> + usleep_range(1000, 1100);
> clk_disable(info->clk);
>
> return 0;
> @@ -1083,7 +1083,7 @@ static int s3c2410fb_resume(struct platform_device *dev)
> struct s3c2410fb_info *info = fbinfo->par;
>
> clk_enable(info->clk);
> - usleep_range(1000, 1000);
> + usleep_range(1000, 1100);
>
> s3c2410fb_init_registers(fbinfo);
>
> @@ -1140,8 +1140,8 @@ static void __exit s3c2410fb_cleanup(void)
> module_init(s3c2410fb_init);
> module_exit(s3c2410fb_cleanup);
>
> -MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, "
> - "Ben Dooks <ben-linux@fluff.org>");
> +MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
> +MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
> MODULE_DESCRIPTION("Framebuffer driver for the s3c2410");
> MODULE_LICENSE("GPL");
> MODULE_ALIAS("platform:s3c2410-lcd");
^ permalink raw reply
* Re: [PATCH 1/2] video: s3c2410: Use pr_* and dev_* instead of printk
From: Florian Tobias Schandinat @ 2012-09-23 19:45 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <002c01cd8f42$a2104080$e630c180$%han@samsung.com>
On 09/10/2012 10:54 AM, Jingoo Han wrote:
> From: Sachin Kamat <sachin.kamat@linaro.org>
>
> printk calls are replaced by pr_* and dev_* calls to silence
> checkpatch warnings.
>
> Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/s3c2410fb.c | 22 ++++++++++++++--------
> 1 files changed, 14 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
> index 77f34c6..1aa37ea 100644
> --- a/drivers/video/s3c2410fb.c
> +++ b/drivers/video/s3c2410fb.c
> @@ -11,6 +11,8 @@
> * Driver based on skeletonfb.c, sa1100fb.c and others.
> */
>
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/module.h>
> #include <linux/kernel.h>
> #include <linux/err.h>
> @@ -48,7 +50,11 @@ static int debug = 1;
> static int debug;
> #endif
>
> -#define dprintk(msg...) if (debug) printk(KERN_DEBUG "s3c2410fb: " msg);
> +#define dprintk(msg...) \
> +do { \
> + if (debug) \
> + pr_debug(msg); \
> +} while (0)
>
> /* useful functions */
>
> @@ -598,11 +604,11 @@ static int s3c2410fb_debug_store(struct device *dev,
> if (strnicmp(buf, "on", 2) = 0 ||
> strnicmp(buf, "1", 1) = 0) {
> debug = 1;
> - printk(KERN_DEBUG "s3c2410fb: Debug On");
> + dev_dbg(dev, "s3c2410fb: Debug On");
> } else if (strnicmp(buf, "off", 3) = 0 ||
> strnicmp(buf, "0", 1) = 0) {
> debug = 0;
> - printk(KERN_DEBUG "s3c2410fb: Debug Off");
> + dev_dbg(dev, "s3c2410fb: Debug Off");
> } else {
> return -EINVAL;
> }
> @@ -921,7 +927,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
>
> info->clk = clk_get(NULL, "lcd");
> if (IS_ERR(info->clk)) {
> - printk(KERN_ERR "failed to get lcd clock source\n");
> + dev_err(&pdev->dev, "failed to get lcd clock source\n");
> ret = PTR_ERR(info->clk);
> goto release_irq;
> }
> @@ -947,7 +953,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
> /* Initialize video memory */
> ret = s3c2410fb_map_video_memory(fbinfo);
> if (ret) {
> - printk(KERN_ERR "Failed to allocate video RAM: %d\n", ret);
> + dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
> ret = -ENOMEM;
> goto release_clock;
> }
> @@ -970,7 +976,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
>
> ret = register_framebuffer(fbinfo);
> if (ret < 0) {
> - printk(KERN_ERR "Failed to register framebuffer device: %d\n",
> + dev_err(&pdev->dev, "Failed to register framebuffer device: %d\n",
> ret);
> goto free_cpufreq;
> }
> @@ -978,9 +984,9 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
> /* create device files */
> ret = device_create_file(&pdev->dev, &dev_attr_debug);
> if (ret)
> - printk(KERN_ERR "failed to add debug attribute\n");
> + dev_err(&pdev->dev, "failed to add debug attribute\n");
>
> - printk(KERN_INFO "fb%d: %s frame buffer device\n",
> + dev_info(&pdev->dev, "fb%d: %s frame buffer device\n",
> fbinfo->node, fbinfo->fix.id);
>
> return 0;
^ permalink raw reply
* Re: [PATCH] fbdev: jz4740: Use devm_request_and_ioremap
From: Florian Tobias Schandinat @ 2012-09-23 19:44 UTC (permalink / raw)
To: Lars-Peter Clausen; +Cc: Damien Cassou, linux-fbdev, linux-kernel
In-Reply-To: <1347205121-5551-1-git-send-email-lars@metafoo.de>
On 09/09/2012 03:38 PM, Lars-Peter Clausen wrote:
> Use devm_request_and_ioremap instead of request_mem_region + devm_ioremap.
>
> This also fixes the following compile error introduced in commit b2ca7f4d
> ("drivers/video/jz4740_fb.c: use devm_ functions"):
>
> drivers/video/jz4740_fb.c: In function 'jzfb_probe':
> drivers/video/jz4740_fb.c:676:2: error: implicit declaration of function 'devm_ioremap'
> drivers/video/jz4740_fb.c:676:13: warning: assignment makes pointer from integer without a cast
>
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Applied. Thanks for pointing this out and fixing it.
Best regards,
Florian Tobias Schandinat
> ---
> drivers/video/jz4740_fb.c | 24 +++---------------------
> 1 files changed, 3 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c
> index 7669770..b0df279 100644
> --- a/drivers/video/jz4740_fb.c
> +++ b/drivers/video/jz4740_fb.c
> @@ -632,23 +632,10 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
> return -ENXIO;
> }
>
> - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - if (!mem) {
> - dev_err(&pdev->dev, "Failed to get register memory resource\n");
> - return -ENXIO;
> - }
> -
> - mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
> - if (!mem) {
> - dev_err(&pdev->dev, "Failed to request register memory region\n");
> - return -EBUSY;
> - }
> -
> fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
> if (!fb) {
> dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
> - ret = -ENOMEM;
> - goto err_release_mem_region;
> + return -ENOMEM;
> }
>
> fb->fbops = &jzfb_ops;
> @@ -657,7 +644,6 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
> jzfb = fb->par;
> jzfb->pdev = pdev;
> jzfb->pdata = pdata;
> - jzfb->mem = mem;
>
> jzfb->ldclk = devm_clk_get(&pdev->dev, "lcd");
> if (IS_ERR(jzfb->ldclk)) {
> @@ -673,9 +659,9 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
> goto err_framebuffer_release;
> }
>
> - jzfb->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + jzfb->base = devm_request_and_ioremap(&pdev->dev, mem);
> if (!jzfb->base) {
> - dev_err(&pdev->dev, "Failed to ioremap register memory region\n");
> ret = -EBUSY;
> goto err_framebuffer_release;
> }
> @@ -736,8 +722,6 @@ err_free_devmem:
> jzfb_free_devmem(jzfb);
> err_framebuffer_release:
> framebuffer_release(fb);
> -err_release_mem_region:
> - release_mem_region(mem->start, resource_size(mem));
> return ret;
> }
>
> @@ -750,8 +734,6 @@ static int __devexit jzfb_remove(struct platform_device *pdev)
> jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
> jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
>
> - release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
> -
> fb_dealloc_cmap(&jzfb->fb->cmap);
> jzfb_free_devmem(jzfb);
>
^ permalink raw reply
* Re: [PATCH 7/10] drivers/video/sis/initextlfb.c: removes unnecessary semicolon
From: Florian Tobias Schandinat @ 2012-09-23 19:43 UTC (permalink / raw)
To: Peter Senna Tschudin
Cc: Thomas Winischhofer, kernel-janitors, linux-fbdev, linux-kernel
In-Reply-To: <1346947757-10481-8-git-send-email-peter.senna@gmail.com>
On 09/06/2012 04:09 PM, Peter Senna Tschudin wrote:
> From: Peter Senna Tschudin <peter.senna@gmail.com>
>
> removes unnecessary semicolon
>
> Found by Coccinelle: http://coccinelle.lip6.fr/
>
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
Applied.
Thanks,
Florian Tobias Schandinat
>
> ---
> drivers/video/sis/initextlfb.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff -u -p a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
> --- a/drivers/video/sis/initextlfb.c
> +++ b/drivers/video/sis/initextlfb.c
> @@ -65,7 +65,7 @@ sisfb_mode_rate_to_dclock(struct SiS_Pri
> }
> #endif
>
> - if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
> + if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {
> printk(KERN_ERR "Could not find mode %x\n", ModeNo);
> return 65000;
> }
>
>
^ permalink raw reply
* Re: [PATCH] video: bf*: Add missing spinlock init
From: Florian Tobias Schandinat @ 2012-09-23 19:42 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <20120906092311.22961acd@endymion.delvare>
On 09/06/2012 07:23 AM, Jean Delvare wrote:
> It doesn't seem these spinlocks were properly initialized.
>
> Signed-off-by: Jean Delvare <khali@linux-fr.org>
> Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Applied. Looks correct to me.
Thanks,
Florian Tobias Schandinat
> ---
> I can't even build-test this.
>
> drivers/video/bf54x-lq043fb.c | 1 +
> drivers/video/bfin-lq035q1-fb.c | 1 +
> drivers/video/bfin-t350mcqb-fb.c | 1 +
> 3 files changed, 3 insertions(+)
>
> --- linux-3.6-rc4.orig/drivers/video/bf54x-lq043fb.c 2012-07-21 22:58:29.000000000 +0200
> +++ linux-3.6-rc4/drivers/video/bf54x-lq043fb.c 2012-09-06 08:49:37.812899185 +0200
> @@ -525,6 +525,7 @@ static int __devinit bfin_bf54x_probe(st
> info = fbinfo->par;
> info->fb = fbinfo;
> info->dev = &pdev->dev;
> + spin_lock_init(&info->lock);
>
> platform_set_drvdata(pdev, fbinfo);
>
> --- linux-3.6-rc4.orig/drivers/video/bfin-lq035q1-fb.c 2012-07-21 22:58:29.000000000 +0200
> +++ linux-3.6-rc4/drivers/video/bfin-lq035q1-fb.c 2012-09-06 08:48:50.618858480 +0200
> @@ -577,6 +577,7 @@ static int __devinit bfin_lq035q1_probe(
> info = fbinfo->par;
> info->fb = fbinfo;
> info->dev = &pdev->dev;
> + spin_lock_init(&info->lock);
>
> info->disp_info = pdev->dev.platform_data;
>
> --- linux-3.6-rc4.orig/drivers/video/bfin-t350mcqb-fb.c 2012-07-21 22:58:29.000000000 +0200
> +++ linux-3.6-rc4/drivers/video/bfin-t350mcqb-fb.c 2012-09-06 08:48:12.310825601 +0200
> @@ -447,6 +447,7 @@ static int __devinit bfin_t350mcqb_probe
> info = fbinfo->par;
> info->fb = fbinfo;
> info->dev = &pdev->dev;
> + spin_lock_init(&info->lock);
>
> platform_set_drvdata(pdev, fbinfo);
>
>
>
^ permalink raw reply
* Re: [PATCH] vmlfb: use list_move_tail instead of list_del/list_add_tail
From: Florian Tobias Schandinat @ 2012-09-23 19:41 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <CAPgLHd_SinBfmVH2erdTq5howN3yAsjhoV+MdSShPgT5Nr5mLg@mail.gmail.com>
On 09/05/2012 06:40 AM, Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>
> Using list_move_tail() instead of list_del() + list_add_tail().
>
> spatch with a semantic match is used to found this problem.
> (http://coccinelle.lip6.fr/)
>
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/vermilion/vermilion.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
> index 970e43d..083f0c8 100644
> --- a/drivers/video/vermilion/vermilion.c
> +++ b/drivers/video/vermilion/vermilion.c
> @@ -1168,8 +1168,7 @@ void vmlfb_unregister_subsys(struct vml_sys *sys)
> list_for_each_entry_safe(entry, next, &global_has_mode, head) {
> printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n");
> vmlfb_disable_pipe(entry);
> - list_del(&entry->head);
> - list_add_tail(&entry->head, &global_no_mode);
> + list_move_tail(&entry->head, &global_no_mode);
> }
> mutex_unlock(&vml_mutex);
> }
>
>
>
^ permalink raw reply
* Re: [PATCH] viafb: don't touch clock state on OLPC XO-1.5
From: Florian Tobias Schandinat @ 2012-09-23 19:41 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <20120904154533.1DC4AFAA0F@dev.laptop.org>
On 09/04/2012 03:45 PM, Daniel Drake wrote:
> As detailed in the thread titled "viafb PLL/clock tweaking causes XO-1.5
> instability," enabling or disabling the IGA1/IGA2 clocks causes occasional
> stability problems during suspend/resume cycles on this platform.
>
> This is rather odd, as the documentation suggests that clocks have two
> states (on/off) and the default (stable) configuration is configured to
> enable the clock only when it is needed. However, explicitly enabling *or*
> disabling the clock triggers this system instability, suggesting that there
> is a 3rd state at play here.
>
> Leaving the clock enable/disable registers alone solves this problem.
> This fixes spurious reboots during suspend/resume behaviour introduced by
> commit b692a63a.
>
> Signed-off-by: Daniel Drake <dsd@laptop.org>
Applied. Thanks for investigating it. I didn't have the time to look at
it due to writing my thesis. Patch looks okay, at least it is a clean
workaround. I did Cc stable when committing it to fix older releases.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/via/via_clock.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c
> index af8f26b..db1e392 100644
> --- a/drivers/video/via/via_clock.c
> +++ b/drivers/video/via/via_clock.c
> @@ -25,6 +25,7 @@
>
> #include <linux/kernel.h>
> #include <linux/via-core.h>
> +#include <asm/olpc.h>
> #include "via_clock.h"
> #include "global.h"
> #include "debug.h"
> @@ -289,6 +290,10 @@ static void dummy_set_pll(struct via_pll_config config)
> printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap);
> }
>
> +static void noop_set_clock_state(u8 state)
> +{
> +}
> +
> void via_clock_init(struct via_clock *clock, int gfx_chip)
> {
> switch (gfx_chip) {
> @@ -346,4 +351,18 @@ void via_clock_init(struct via_clock *clock, int gfx_chip)
> break;
>
> }
> +
> + if (machine_is_olpc()) {
> + /* The OLPC XO-1.5 cannot suspend/resume reliably if the
> + * IGA1/IGA2 clocks are set as on or off (memory rot
> + * occasionally happens during suspend under such
> + * configurations).
> + *
> + * The only known stable scenario is to leave this bits as-is,
> + * which in their default states are documented to enable the
> + * clock only when it is needed.
> + */
> + clock->set_primary_clock_state = noop_set_clock_state;
> + clock->set_secondary_clock_state = noop_set_clock_state;
> + }
> }
^ permalink raw reply
* Re: [PATCH] video: exynos_dp: replace link_status with link_align to check channel equalization
From: Florian Tobias Schandinat @ 2012-09-23 19:37 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <000001cd89b1$2852e3b0$78f8ab10$%han@samsung.com>
On 09/03/2012 08:50 AM, Jingoo Han wrote:
> To check channel equalization, the value of LANE_ALIGN_STATUS_UPDATED is
> necessary in exynos_dp_channel_eq_ok(). Also, link_align includes this value.
> However, link_status does not include this value, so it makes the problem
> that channel equalization is failed during link training.
>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/exynos/exynos_dp_core.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> index f57c915..cdc1398 100644
> --- a/drivers/video/exynos/exynos_dp_core.c
> +++ b/drivers/video/exynos/exynos_dp_core.c
> @@ -587,7 +587,7 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
> dp->link_train.training_lane[lane] = training_lane;
> }
>
> - if (exynos_dp_channel_eq_ok(link_status, lane_count) = 0) {
> + if (exynos_dp_channel_eq_ok(link_align, lane_count) = 0) {
> /* traing pattern Set to Normal */
> exynos_dp_training_pattern_dis(dp);
>
^ permalink raw reply
* Re: [PATCH v2] da8xx-fb: enable LCDC if FB is unblanked
From: Florian Tobias Schandinat @ 2012-09-23 19:37 UTC (permalink / raw)
To: linux-fbdev
On 08/31/2012 02:18 PM, Manjunathappa, Prakash wrote:
> It is expected that LCDC to continue to be disabled after
> resume if it is blanked before suspend. This is also true
> for DVFS. But it is observed that LCDC being enabled after
> suspend/resume cycle or DVFS.
>
> Correcting it by having check for FB_BLANK_UNBLANK before
> enabling.
>
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> Applies on top of fbdev-next of Florian Tobias Schandinat's tree.
> Since v1:
> Re-written commit message.
>
> drivers/video/da8xx-fb.c | 11 +++++++----
> 1 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 761c8d1..1273354 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -962,7 +962,8 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
> par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
> lcd_disable_raster();
> lcd_calc_clk_divider(par);
> - lcd_enable_raster();
> + if (par->blank = FB_BLANK_UNBLANK)
> + lcd_enable_raster();
> }
> }
>
> @@ -1486,10 +1487,12 @@ static int fb_resume(struct platform_device *dev)
>
> console_lock();
> clk_enable(par->lcdc_clk);
> - lcd_enable_raster();
> + if (par->blank = FB_BLANK_UNBLANK) {
> + lcd_enable_raster();
>
> - if (par->panel_power_ctrl)
> - par->panel_power_ctrl(1);
> + if (par->panel_power_ctrl)
> + par->panel_power_ctrl(1);
> + }
>
> fb_set_suspend(info, 0);
> console_unlock();
^ permalink raw reply
* Re: [PATCH] video: mbxfb: Include linux/io.h instead of asm/io.h
From: Florian Tobias Schandinat @ 2012-09-23 19:36 UTC (permalink / raw)
To: Axel Lin
Cc: Arnd Bergmann, Mathieu Poirier, Damien Cassou, linux-fbdev,
linux-kernel
In-Reply-To: <1346420343.3107.0.camel@phoenix>
On 08/31/2012 01:39 PM, Axel Lin wrote:
> This fixes below build error:
>
> CC [M] drivers/video/mbx/mbxfb.o
> drivers/video/mbx/mbxfb.c: In function 'mbxfb_probe':
> drivers/video/mbx/mbxfb.c:942:2: error: implicit declaration of function 'devm_ioremap_nocache' [-Werror=implicit-function-declaration]
> drivers/video/mbx/mbxfb.c:942:22: warning: assignment makes pointer from integer without a cast [enabled by default]
> drivers/video/mbx/mbxfb.c:952:21: warning: assignment makes pointer from integer without a cast [enabled by default]
> cc1: some warnings being treated as errors
>
> Signed-off-by: Axel Lin <axel.lin@gmail.com>
Applied. Thanks for pointing this out and fixing it.
Best regards,
Florian Tobias Schandinat
> ---
> drivers/video/mbx/mbxfb.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
> index 9229acf..6563e50 100644
> --- a/drivers/video/mbx/mbxfb.c
> +++ b/drivers/video/mbx/mbxfb.c
> @@ -26,8 +26,7 @@
> #include <linux/module.h>
> #include <linux/platform_device.h>
> #include <linux/uaccess.h>
> -
> -#include <asm/io.h>
> +#include <linux/io.h>
>
> #include <video/mbxfb.h>
>
^ permalink raw reply
* Re: [PATCH v5] da8xx-fb: allow frame to complete after disabling LCDC
From: Florian Tobias Schandinat @ 2012-09-23 19:28 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1345813980-14758-1-git-send-email-prakash.pm@ti.com>
On 08/24/2012 01:13 PM, Manjunathappa, Prakash wrote:
> Wait for active frame transfer to complete after disabling LCDC.
> At the same this wait is not be required when there are sync and
> underflow errors.
> Patch applies for revision 2 of LCDC present am335x.
> More information on disable and reset sequence can be found in
> section 13.4.6 of AM335x TRM @www.ti.com/am335x.
>
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> Applies on top of fbdev-next of Florian Tobias Schandinat's tree.
> Since v4:
> Minor nit, removed extra line.
> Since v3:
> Rely on frame done interrupt instead of polling for it.
> Since v2:
> Optimized the lcd_disable_raster function.
> Since v1:
> Changed the commit message, also added link to hardware specification.
> drivers/video/da8xx-fb.c | 52 +++++++++++++++++++++++++++++++++++----------
> 1 files changed, 40 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 7ae9d53..32f0d06 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -27,6 +27,7 @@
> #include <linux/platform_device.h>
> #include <linux/uaccess.h>
> #include <linux/interrupt.h>
> +#include <linux/wait.h>
> #include <linux/clk.h>
> #include <linux/cpufreq.h>
> #include <linux/console.h>
> @@ -48,6 +49,7 @@
> #define LCD_PL_LOAD_DONE BIT(6)
> #define LCD_FIFO_UNDERFLOW BIT(5)
> #define LCD_SYNC_LOST BIT(2)
> +#define LCD_FRAME_DONE BIT(0)
>
> /* LCD DMA Control Register */
> #define LCD_DMA_BURST_SIZE(x) ((x) << 4)
> @@ -135,6 +137,8 @@ static resource_size_t da8xx_fb_reg_base;
> static struct resource *lcdc_regs;
> static unsigned int lcd_revision;
> static irq_handler_t lcdc_irq_handler;
> +static wait_queue_head_t frame_done_wq;
> +static int frame_done_flag;
>
> static inline unsigned int lcdc_read(unsigned int addr)
> {
> @@ -288,13 +292,26 @@ static inline void lcd_enable_raster(void)
> }
>
> /* Disable the Raster Engine of the LCD Controller */
> -static inline void lcd_disable_raster(void)
> +static inline void lcd_disable_raster(bool wait_for_frame_done)
> {
> u32 reg;
> + int ret;
>
> reg = lcdc_read(LCD_RASTER_CTRL_REG);
> if (reg & LCD_RASTER_ENABLE)
> lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
> + else
> + /* return if already disabled */
> + return;
> +
> + if ((wait_for_frame_done = true) && (lcd_revision = LCD_VERSION_2)) {
> + frame_done_flag = 0;
> + ret = wait_event_interruptible_timeout(frame_done_wq,
> + frame_done_flag != 0,
> + msecs_to_jiffies(50));
> + if (ret = 0)
> + pr_err("LCD Controller timed out\n");
> + }
> }
>
> static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
> @@ -321,7 +338,8 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
> } else {
> reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
> LCD_V2_END_OF_FRAME0_INT_ENA |
> - LCD_V2_END_OF_FRAME1_INT_ENA;
> + LCD_V2_END_OF_FRAME1_INT_ENA |
> + LCD_FRAME_DONE;
> lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
> }
> reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
> @@ -638,7 +656,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
> static void lcd_reset(struct da8xx_fb_par *par)
> {
> /* Disable the Raster if previously Enabled */
> - lcd_disable_raster();
> + lcd_disable_raster(false);
>
> /* DMA has to be disabled */
> lcdc_write(0, LCD_DMA_CTRL_REG);
> @@ -734,7 +752,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
> u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
>
> if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
> - lcd_disable_raster();
> + lcd_disable_raster(false);
> lcdc_write(stat, LCD_MASKED_STAT_REG);
> lcd_enable_raster();
> } else if (stat & LCD_PL_LOAD_DONE) {
> @@ -744,7 +762,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
> * interrupt via the following write to the status register. If
> * this is done after then one gets multiple PL done interrupts.
> */
> - lcd_disable_raster();
> + lcd_disable_raster(false);
>
> lcdc_write(stat, LCD_MASKED_STAT_REG);
>
> @@ -775,6 +793,14 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
> par->vsync_flag = 1;
> wake_up_interruptible(&par->vsync_wait);
> }
> +
> + /* Set only when controller is disabled and at the end of
> + * active frame
> + */
> + if (stat & BIT(0)) {
> + frame_done_flag = 1;
> + wake_up_interruptible(&frame_done_wq);
> + }
> }
>
> lcdc_write(0, LCD_END_OF_INT_IND_REG);
> @@ -789,7 +815,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
> u32 reg_ras;
>
> if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
> - lcd_disable_raster();
> + lcd_disable_raster(false);
> lcdc_write(stat, LCD_STAT_REG);
> lcd_enable_raster();
> } else if (stat & LCD_PL_LOAD_DONE) {
> @@ -799,7 +825,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
> * interrupt via the following write to the status register. If
> * this is done after then one gets multiple PL done interrupts.
> */
> - lcd_disable_raster();
> + lcd_disable_raster(false);
>
> lcdc_write(stat, LCD_STAT_REG);
>
> @@ -898,7 +924,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
> if (val = CPUFREQ_POSTCHANGE) {
> if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
> par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
> - lcd_disable_raster();
> + lcd_disable_raster(true);
> lcd_calc_clk_divider(par);
> lcd_enable_raster();
> }
> @@ -935,7 +961,7 @@ static int __devexit fb_remove(struct platform_device *dev)
> if (par->panel_power_ctrl)
> par->panel_power_ctrl(0);
>
> - lcd_disable_raster();
> + lcd_disable_raster(true);
> lcdc_write(0, LCD_RASTER_CTRL_REG);
>
> /* disable DMA */
> @@ -1051,7 +1077,7 @@ static int cfb_blank(int blank, struct fb_info *info)
> if (par->panel_power_ctrl)
> par->panel_power_ctrl(0);
>
> - lcd_disable_raster();
> + lcd_disable_raster(true);
> break;
> default:
> ret = -EINVAL;
> @@ -1356,8 +1382,10 @@ static int __devinit fb_probe(struct platform_device *device)
>
> if (lcd_revision = LCD_VERSION_1)
> lcdc_irq_handler = lcdc_irq_handler_rev01;
> - else
> + else {
> + init_waitqueue_head(&frame_done_wq);
> lcdc_irq_handler = lcdc_irq_handler_rev02;
> + }
>
> ret = request_irq(par->irq, lcdc_irq_handler, 0,
> DRIVER_NAME, par);
> @@ -1411,7 +1439,7 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
> par->panel_power_ctrl(0);
>
> fb_set_suspend(info, 1);
> - lcd_disable_raster();
> + lcd_disable_raster(true);
> clk_disable(par->lcdc_clk);
> console_unlock();
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox