diff options
58 files changed, 2398 insertions, 2156 deletions
diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt b/Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt new file mode 100644 index 000000000000..c46ba641a1df --- /dev/null +++ b/Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt @@ -0,0 +1,33 @@ +Sunxi specific Simple Framebuffer bindings + +This binding documents sunxi specific extensions to the simple-framebuffer +bindings. The sunxi simplefb u-boot code relies on the devicetree containing +pre-populated simplefb nodes. + +These extensions are intended so that u-boot can select the right node based +on which pipeline is being used. As such they are solely intended for +firmware / bootloader use, and the OS should ignore them. + +Required properties: +- compatible: "allwinner,simple-framebuffer" +- allwinner,pipeline, one of: + "de_be0-lcd0" + "de_be1-lcd1" + "de_be0-lcd0-hdmi" + "de_be1-lcd1-hdmi" + +Example: + +chosen { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + framebuffer@0 { + compatible = "allwinner,simple-framebuffer", "simple-framebuffer"; + allwinner,pipeline = "de_be0-lcd0-hdmi"; + clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>, + <&ahb_gates 44>; + status = "disabled"; + }; +}; diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt index 70c26f3a5b9a..4474ef6e0b95 100644 --- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt +++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt @@ -1,8 +1,40 @@ Simple Framebuffer -A simple frame-buffer describes a raw memory region that may be rendered to, -with the assumption that the display hardware has already been set up to scan -out from that buffer. +A simple frame-buffer describes a frame-buffer setup by firmware or +the bootloader, with the assumption that the display hardware has already +been set up to scan out from the memory pointed to by the reg property. + +Since simplefb nodes represent runtime information they must be sub-nodes of +the chosen node (*). Simplefb nodes must be named "framebuffer@<address>". + +If the devicetree contains nodes for the display hardware used by a simplefb, +then the simplefb node must contain a property called "display", which +contains a phandle pointing to the primary display hw node, so that the OS +knows which simplefb to disable when handing over control to a driver for the +real hardware. The bindings for the hw nodes must specify which node is +considered the primary node. + +It is advised to add display# aliases to help the OS determine how to number +things. If display# aliases are used, then if the simplefb node contains a +"display" property then the /aliases/display# path must point to the display +hw node the "display" property points to, otherwise it must point directly +to the simplefb node. + +If a simplefb node represents the preferred console for user interaction, +then the chosen node's stdout-path property should point to it, or to the +primary display hw node, as with display# aliases. If display aliases are +used then it should be set to the alias instead. + +It is advised that devicetree files contain pre-filled, disabled framebuffer +nodes, so that the firmware only needs to update the mode information and +enable them. This way if e.g. later on support for more display clocks get +added, the simplefb nodes will already contain this info and the firmware +does not need to be updated. + +If pre-filled framebuffer nodes are used, the firmware may need extra +information to find the right node. In that case an extra platform specific +compatible and platform specific properties should be used and documented, +see e.g. simple-framebuffer-sunxi.txt . Required properties: - compatible: "simple-framebuffer" @@ -14,13 +46,41 @@ Required properties: - r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b). - a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r). +Optional properties: +- clocks : List of clocks used by the framebuffer. Clocks listed here + are expected to already be configured correctly. The OS must + ensure these clocks are not modified or disabled while the + simple framebuffer remains active. +- display : phandle pointing to the primary display hardware node + Example: - framebuffer { +aliases { + display0 = &lcdc0; +} + +chosen { + framebuffer0: framebuffer@1d385000 { compatible = "simple-framebuffer"; reg = <0x1d385000 (1600 * 1200 * 2)>; width = <1600>; height = <1200>; stride = <(1600 * 2)>; format = "r5g6b5"; + clocks = <&ahb_gates 36>, <&ahb_gates 43>, <&ahb_gates 44>; + display = <&lcdc0>; + }; + stdout-path = "display0"; +}; + +soc@01c00000 { + lcdc0: lcdc@1c0c000 { + compatible = "allwinner,sun4i-a10-lcdc"; + ... }; +}; + + +*) Older devicetree files may have a compatible = "simple-framebuffer" node +in a different place, operating systems must first enumerate any compatible +nodes found under chosen and then check for other compatible nodes. diff --git a/MAINTAINERS b/MAINTAINERS index 1a4165094482..7bff8087fce7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8586,6 +8586,14 @@ F: drivers/media/usb/siano/ F: drivers/media/usb/siano/ F: drivers/media/mmc/siano/ +SIMPLEFB FB DRIVER +M: Hans de Goede <hdegoede@redhat.com> +L: linux-fbdev@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/video/simple-framebuffer.txt +F: drivers/video/fbdev/simplefb.c +F: include/linux/platform_data/simplefb.h + SH_VEU V4L2 MEM2MEM DRIVER L: linux-media@vger.kernel.org S: Orphan diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index eb976ee3a02f..ea437245562e 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -3624,7 +3624,7 @@ static int __init fb_console_init(void) return 0; } -module_init(fb_console_init); +fs_initcall(fb_console_init); #ifdef MODULE diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index c78bfd1d1b34..4916c97216f8 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2408,7 +2408,7 @@ config FB_JZ4740 config FB_MXS tristate "MXS LCD framebuffer support" - depends on FB && ARCH_MXS + depends on FB && (ARCH_MXS || ARCH_MXC) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index 6ad23bd3523a..32c0b6b28097 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -27,7 +27,6 @@ #include <linux/bitops.h> #include <linux/clk.h> #include <linux/hardirq.h> -#include <linux/dma-mapping.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_graph.h> diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c index adc4ea2cc5a0..b305a1e7cc76 100644 --- a/drivers/video/fbdev/arkfb.c +++ b/drivers/video/fbdev/arkfb.c @@ -1016,7 +1016,7 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); - par->state.vgabase = (void __iomem *) vga_res.start; + par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start; /* FIXME get memsize */ regval = vga_rseq(par->state.vgabase, 0x10); diff --git a/drivers/video/fbdev/mmp/core.c b/drivers/video/fbdev/mmp/core.c index b563b920f159..a0f496049db7 100644 --- a/drivers/video/fbdev/mmp/core.c +++ b/drivers/video/fbdev/mmp/core.c @@ -223,10 +223,10 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info) EXPORT_SYMBOL_GPL(mmp_register_path); /* - * mmp_unregister_path - unregister and destory path - * @p: path to be destoried. + * mmp_unregister_path - unregister and destroy path + * @p: path to be destroyed. * - * this function registers path and destorys it. + * this function registers path and destroys it. */ void mmp_unregister_path(struct mmp_path *path) { diff --git a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c index 8621a9f2bdcc..3c12bd83b561 100644 --- a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c +++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c @@ -441,8 +441,7 @@ static void path_deinit(struct mmphw_path_plat *path_plat) if (!path_plat) return; - if (path_plat->path) - mmp_unregister_path(path_plat->path); + mmp_unregister_path(path_plat->path); } static int mmphw_probe(struct platform_device *pdev) diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c index 23ec781e9a61..f23fca0be9d7 100644 --- a/drivers/video/fbdev/mx3fb.c +++ b/drivers/video/fbdev/mx3fb.c @@ -334,8 +334,7 @@ static void mx3fb_init_backlight(struct mx3fb_data *fbd) static void mx3fb_exit_backlight(struct mx3fb_data *fbd) { - if (fbd->bl) - backlight_device_unregister(fbd->bl); + backlight_device_unregister(fbd->bl); } static void mx3fb_dma_done(void *); diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c index accf48a2cce4..f8ac4a452f26 100644 --- a/drivers/video/fbdev/mxsfb.c +++ b/drivers/video/fbdev/mxsfb.c @@ -172,6 +172,8 @@ struct mxsfb_info { struct fb_info fb_info; struct platform_device *pdev; struct clk *clk; + struct clk *clk_axi; + struct clk *clk_disp_axi; void __iomem *base; /* registers */ unsigned allocated_size; int enabled; @@ -331,6 +333,11 @@ static void mxsfb_enable_controller(struct fb_info *fb_info) } } + if (host->clk_axi) + clk_prepare_enable(host->clk_axi); + + if (host->clk_disp_axi) + clk_prepare_enable(host->clk_disp_axi); clk_prepare_enable(host->clk); clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); @@ -374,6 +381,10 @@ static void mxsfb_disable_controller(struct fb_info *fb_info) writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4); clk_disable_unprepare(host->clk); + if (host->clk_disp_axi) + clk_disable_unprepare(host->clk_disp_axi); + if (host->clk_axi) + clk_disable_unprepare(host->clk_axi); host->enabled = 0; @@ -867,6 +878,14 @@ static int mxsfb_probe(struct platform_device *pdev) goto fb_release; } + host->clk_axi = devm_clk_get(&host->pdev->dev, "axi"); + if (IS_ERR(host->clk_axi)) + host->clk_axi = NULL; + + host->clk_disp_axi = devm_clk_get(&host->pdev->dev, "disp_axi"); + if (IS_ERR(host->clk_disp_axi)) + host->clk_disp_axi = NULL; + host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd"); if (IS_ERR(host->reg_lcd)) host->reg_lcd = NULL; diff --git a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c index 2dfb6e5ff0cc..3d38e478bc64 100644 --- a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c @@ -262,8 +262,7 @@ static int dvic_probe_pdata(struct platform_device *pdev) in = omap_dss_find_output(pdata->source); if (in == NULL) { - if (ddata->i2c_adapter) - i2c_put_adapter(ddata->i2c_adapter); + i2c_put_adapter(ddata->i2c_adapter); dev_err(&pdev->dev, "Failed to find video source\n"); return -EPROBE_DEFER; @@ -352,8 +351,7 @@ static int dvic_probe(struct platform_device *pdev) err_reg: omap_dss_put_device(ddata->in); - if (ddata->i2c_adapter) - i2c_put_adapter(ddata->i2c_adapter); + i2c_put_adapter(ddata->i2c_adapter); return r; } @@ -371,8 +369,7 @@ static int __exit dvic_remove(struct platform_device *pdev) omap_dss_put_device(in); - if (ddata->i2c_adapter) - i2c_put_adapter(ddata->i2c_adapter); + i2c_put_adapter(ddata->i2c_adapter); return 0; } diff --git a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c index 7b25967a91eb..219f14f59672 100644 --- a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c @@ -170,98 +170,6 @@ static bool hdmic_detect(struct omap_dss_device *dssdev) return in->ops.hdmi->detect(in); } -static int hdmic_audio_enable(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - int r; - - /* enable audio only if the display is active */ - if (!omapdss_device_is_enabled(dssdev)) - return -EPERM; - - r = in->ops.hdmi->audio_enable(in); - if (r) - return r; - - dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED; - - return 0; -} - -static void hdmic_audio_disable(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - in->ops.hdmi->audio_disable(in); - - dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED; -} - -static int hdmic_audio_start(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - int r; - - /* - * No need to check the panel state. It was checked when trasitioning - * to AUDIO_ENABLED. - */ - if (dssdev->audio_state != OMAP_DSS_AUDIO_ENABLED) - return -EPERM; - - r = in->ops.hdmi->audio_start(in); - if (r) - return r; - - dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING; - - return 0; -} - -static void hdmic_audio_stop(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - in->ops.hdmi->audio_stop(in); - - dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED; -} - -static bool hdmic_audio_supported(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - if (!omapdss_device_is_enabled(dssdev)) - return false; - - return in->ops.hdmi->audio_supported(in); -} - -static int hdmic_audio_config(struct omap_dss_device *dssdev, - struct omap_dss_audio *audio) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - int r; - - /* config audio only if the display is active */ - if (!omapdss_device_is_enabled(dssdev)) - return -EPERM; - - r = in->ops.hdmi->audio_config(in, audio); - if (r) - return r; - - dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED; - - return 0; -} - static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode) { struct panel_drv_data *ddata = to_panel_data(dssdev); @@ -296,13 +204,6 @@ static struct omap_dss_driver hdmic_driver = { .detect = hdmic_detect, .set_hdmi_mode = hdmic_set_hdmi_mode, .set_hdmi_infoframe = hdmic_set_infoframe, - - .audio_enable = hdmic_audio_enable, - .audio_disable = hdmic_audio_disable, - .audio_start = hdmic_audio_start, - .audio_stop = hdmic_audio_stop, - .audio_supported = hdmic_audio_supported, - .audio_config = hdmic_audio_config, }; static int hdmic_probe_pdata(struct platform_device *pdev) diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c index 47ee7cdee1c5..e349064ed615 100644 --- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c +++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c @@ -249,6 +249,7 @@ static int tfp410_probe(struct platform_device *pdev) dssdev->output_type = OMAP_DISPLAY_TYPE_DVI; dssdev->owner = THIS_MODULE; dssdev->phy.dpi.data_lines = ddata->data_lines; + dssdev->port_num = 1; r = omapdss_register_output(dssdev); if (r) { diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c index c4abd56dd846..c7a3ce2c5120 100644 --- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c +++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c @@ -193,55 +193,6 @@ static bool tpd_detect(struct omap_dss_device *dssdev) return gpio_get_value_cansleep(ddata->hpd_gpio); } -static int tpd_audio_enable(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - return in->ops.hdmi->audio_enable(in); -} - -static void tpd_audio_disable(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - in->ops.hdmi->audio_disable(in); -} - -static int tpd_audio_start(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - return in->ops.hdmi->audio_start(in); -} - -static void tpd_audio_stop(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - in->ops.hdmi->audio_stop(in); -} - -static bool tpd_audio_supported(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - return in->ops.hdmi->audio_supported(in); -} - -static int tpd_audio_config(struct omap_dss_device *dssdev, - struct omap_dss_audio *audio) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - return in->ops.hdmi->audio_config(in, audio); -} - static int tpd_set_infoframe(struct omap_dss_device *dssdev, const struct hdmi_avi_infoframe *avi) { @@ -275,13 +226,6 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = { .detect = tpd_detect, .set_infoframe = tpd_set_infoframe, .set_hdmi_mode = tpd_set_hdmi_mode, - - .audio_enable = tpd_audio_enable, - .audio_disable = tpd_audio_disable, - .audio_start = tpd_audio_start, - .audio_stop = tpd_audio_stop, - .audio_supported = tpd_audio_supported, - .audio_config = tpd_audio_config, }; static int tpd_probe_pdata(struct platform_device *pdev) @@ -409,6 +353,7 @@ static int tpd_probe(struct platform_device *pdev) dssdev->type = OMAP_DISPLAY_TYPE_HDMI; dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; + dssdev->port_num = 1; in = ddata->in; diff --git a/drivers/video/fbdev/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig index 3d5eb6c36c22..d1fa730c7d54 100644 --- a/drivers/video/fbdev/omap2/dss/Kconfig +++ b/drivers/video/fbdev/omap2/dss/Kconfig @@ -74,9 +74,6 @@ config OMAP4_DSS_HDMI help HDMI support for OMAP4 based SoCs. -config OMAP4_DSS_HDMI_AUDIO - bool - config OMAP5_DSS_HDMI bool "HDMI support for OMAP5" default n @@ -86,10 +83,6 @@ config OMAP5_DSS_HDMI Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI specification. -config OMAP5_DSS_HDMI_AUDIO - depends on OMAP5_DSS_HDMI - bool - config OMAP2_DSS_SDI bool "SDI support" default n diff --git a/drivers/video/fbdev/omap2/dss/Makefile b/drivers/video/fbdev/omap2/dss/Makefile index 245f933060ee..2ea9d382354c 100644 --- a/drivers/video/fbdev/omap2/dss/Makefile +++ b/drivers/video/fbdev/omap2/dss/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o obj-$(CONFIG_OMAP2_DSS) += omapdss.o # Core DSS files omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ - output.o dss-of.o + output.o dss-of.o pll.o # DSS compat layer files omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \ dispc-compat.o display-sysfs.o diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c index 0e9a74bb9fc2..0729c08ac75a 100644 --- a/drivers/video/fbdev/omap2/dss/dispc.c +++ b/drivers/video/fbdev/omap2/dss/dispc.c @@ -3028,7 +3028,7 @@ static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div, unsigned long dispc_fclk_rate(void) { - struct platform_device *dsidev; + struct dss_pll *pll; unsigned long r = 0; switch (dss_get_dispc_clk_source()) { @@ -3036,12 +3036,12 @@ unsigned long dispc_fclk_rate(void) r = dss_get_dispc_clk_rate(); break; case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_D |