From a7c42990f1bed8665037fd5a3848ffb02de3b553 Mon Sep 17 00:00:00 2001 From: Harald Geyer Date: Tue, 28 Apr 2015 13:17:49 +0200 Subject: framebuffer: don't link fb_devio into kernel image unconditionally CONFIG_FB_DEFERRED_IO is defined as bool while CONFIG_FB is defined as tristate. Currently fb_defio.o is linked into the kernel image even if CONFIG_FB=m. I fix this by updating the Makefile to link fb_defio.o into fb.o and thus go into one place with the other core framebuffer code. Signed-off-by: Harald Geyer Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/core/Makefile | 2 +- drivers/video/fbdev/core/fb_defio.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile index 67f28e20a892..23d86a8b7d7b 100644 --- a/drivers/video/fbdev/core/Makefile +++ b/drivers/video/fbdev/core/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_FB_CMDLINE) += fb_cmdline.o obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ modedb.o fbcvt.o +fb-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o fb-objs := $(fb-y) obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o @@ -14,4 +15,3 @@ obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o obj-$(CONFIG_FB_SVGALIB) += svgalib.o obj-$(CONFIG_FB_DDC) += fb_ddc.o -obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index d6cab1fd9a47..3fc63c208d08 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -242,5 +242,3 @@ void fb_deferred_io_cleanup(struct fb_info *info) mutex_destroy(&fbdefio->lock); } EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); - -MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From 2fa3b4c4a78a5db3502ab9e32630ea660ff923d0 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Fri, 3 Apr 2015 12:51:05 +0800 Subject: video: mxsfb: Make sure axi clock is enabled when accessing registers The LCDIF engines embedded in i.MX6sl and i.MX6sx SoCs need the axi clock as the engine's system clock. The clock should be enabled when accessing LCDIF registers, otherwise the kernel would hang up. We should also keep the clock enabled when the engine is being active to scan out frames from memory. This patch makes sure the axi clock is enabled when accessing registers so that the kernel hang up issue can be fixed. Reported-by: Peter Chen Tested-by: Peter Chen Cc: # 3.19+ Signed-off-by: Liu Ying Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/mxsfb.c | 68 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c index f8ac4a452f26..0f64165b0147 100644 --- a/drivers/video/fbdev/mxsfb.c +++ b/drivers/video/fbdev/mxsfb.c @@ -316,6 +316,18 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var, return 0; } +static inline void mxsfb_enable_axi_clk(struct mxsfb_info *host) +{ + if (host->clk_axi) + clk_prepare_enable(host->clk_axi); +} + +static inline void mxsfb_disable_axi_clk(struct mxsfb_info *host) +{ + if (host->clk_axi) + clk_disable_unprepare(host->clk_axi); +} + static void mxsfb_enable_controller(struct fb_info *fb_info) { struct mxsfb_info *host = to_imxfb_host(fb_info); @@ -333,14 +345,13 @@ 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); + mxsfb_enable_axi_clk(host); + /* if it was disabled, re-enable the mode again */ writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_SET); @@ -380,11 +391,11 @@ static void mxsfb_disable_controller(struct fb_info *fb_info) reg = readl(host->base + LCDC_VDCTRL4); writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4); + mxsfb_disable_axi_clk(host); + 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; @@ -421,6 +432,8 @@ static int mxsfb_set_par(struct fb_info *fb_info) mxsfb_disable_controller(fb_info); } + mxsfb_enable_axi_clk(host); + /* clear the FIFOs */ writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET); @@ -438,6 +451,7 @@ static int mxsfb_set_par(struct fb_info *fb_info) ctrl |= CTRL_SET_WORD_LENGTH(3); switch (host->ld_intf_width) { case STMLCDIF_8BIT: + mxsfb_disable_axi_clk(host); dev_err(&host->pdev->dev, "Unsupported LCD bus width mapping\n"); return -EINVAL; @@ -451,6 +465,7 @@ static int mxsfb_set_par(struct fb_info *fb_info) writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1); break; default: + mxsfb_disable_axi_clk(host); dev_err(&host->pdev->dev, "Unhandled color depth of %u\n", fb_info->var.bits_per_pixel); return -EINVAL; @@ -504,6 +519,8 @@ static int mxsfb_set_par(struct fb_info *fb_info) fb_info->fix.line_length * fb_info->var.yoffset, host->base + host->devdata->next_buf); + mxsfb_disable_axi_clk(host); + if (reenable) mxsfb_enable_controller(fb_info); @@ -582,10 +599,14 @@ static int mxsfb_pan_display(struct fb_var_screeninfo *var, offset = fb_info->fix.line_length * var->yoffset; + mxsfb_enable_axi_clk(host); + /* update on next VSYNC */ writel(fb_info->fix.smem_start + offset, host->base + host->devdata->next_buf); + mxsfb_disable_axi_clk(host); + return 0; } @@ -608,13 +629,17 @@ static int mxsfb_restore_mode(struct mxsfb_info *host, unsigned line_count; unsigned period; unsigned long pa, fbsize; - int bits_per_pixel, ofs; + int bits_per_pixel, ofs, ret = 0; u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl; + mxsfb_enable_axi_clk(host); + /* Only restore the mode when the controller is running */ ctrl = readl(host->base + LCDC_CTRL); - if (!(ctrl & CTRL_RUN)) - return -EINVAL; + if (!(ctrl & CTRL_RUN)) { + ret = -EINVAL; + goto err; + } vdctrl0 = readl(host->base + LCDC_VDCTRL0); vdctrl2 = readl(host->base + LCDC_VDCTRL2); @@ -635,7 +660,8 @@ static int mxsfb_restore_mode(struct mxsfb_info *host, break; case 1: default: - return -EINVAL; + ret = -EINVAL; + goto err; } fb_info->var.bits_per_pixel = bits_per_pixel; @@ -673,10 +699,14 @@ static int mxsfb_restore_mode(struct mxsfb_info *host, pa = readl(host->base + host->devdata->cur_buf); fbsize = fb_info->fix.line_length * vmode->yres; - if (pa < fb_info->fix.smem_start) - return -EINVAL; - if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) - return -EINVAL; + if (pa < fb_info->fix.smem_start) { + ret = -EINVAL; + goto err; + } + if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) { + ret = -EINVAL; + goto err; + } ofs = pa - fb_info->fix.smem_start; if (ofs) { memmove(fb_info->screen_base, fb_info->screen_base + ofs, fbsize); @@ -689,7 +719,11 @@ static int mxsfb_restore_mode(struct mxsfb_info *host, clk_prepare_enable(host->clk); host->enabled = 1; - return 0; +err: + if (ret) + mxsfb_disable_axi_clk(host); + + return ret; } static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host, @@ -915,7 +949,9 @@ static int mxsfb_probe(struct platform_device *pdev) } if (!host->enabled) { + mxsfb_enable_axi_clk(host); writel(0, host->base + LCDC_CTRL); + mxsfb_disable_axi_clk(host); mxsfb_set_par(fb_info); mxsfb_enable_controller(fb_info); } @@ -954,11 +990,15 @@ static void mxsfb_shutdown(struct platform_device *pdev) struct fb_info *fb_info = platform_get_drvdata(pdev); struct mxsfb_info *host = to_imxfb_host(fb_info); + mxsfb_enable_axi_clk(host); + /* * Force stop the LCD controller as keeping it running during reboot * might interfere with the BootROM's boot mode pads sampling. */ writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR); + + mxsfb_disable_axi_clk(host); } static struct platform_driver mxsfb_driver = { -- cgit v1.2.3-59-g8ed1b From 258c0ea21d3aa974b43e5ce6c2f7c94553a3b1cc Mon Sep 17 00:00:00 2001 From: Thomas Niederprüm Date: Tue, 31 Mar 2015 20:27:07 +0200 Subject: fbdev: ssd1307fb: fix memory address smem_start. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the smem_start pointer of the framebuffer info struct needs to hold the physical address rather than the logical address. Right now the logical address returned by kmalloc is stored. This patch converts this address to a physical address and thus fixes a driver crash on mmaping the framebuffer memory due to an access to the wrong memory address. Signed-off-by: Thomas Niederprüm Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/ssd1307fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index f7ed6d9016f7..61e0ce866506 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -515,7 +515,7 @@ static int ssd1307fb_probe(struct i2c_client *client, info->var.blue.offset = 0; info->screen_base = (u8 __force __iomem *)vmem; - info->fix.smem_start = (unsigned long)vmem; + info->fix.smem_start = __pa(vmem); info->fix.smem_len = vmem_size; fb_deferred_io_init(info); -- cgit v1.2.3-59-g8ed1b From facd94bc458af12e1ebab06cfc3b8e7a41906622 Mon Sep 17 00:00:00 2001 From: Thomas Niederprüm Date: Tue, 31 Mar 2015 20:27:08 +0200 Subject: fbdev: ssd1307fb: Allocate page aligned video memory. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the videomemory is allocated by kmalloc, making it a memory region that is not necessarily page aligend. This leads to problems upon mmap call, where the video memory's address gets aligned to the next page boundary. The result is that the userspace program that issued the mmap call is not able to access the video memory from the start to the next page boundary. This patch changes the allocation of the video memory to use __get_free_pages() in order to obtain memory that is aligned to page boundaries. Signed-off-by: Thomas Niederprüm Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/ssd1307fb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 61e0ce866506..8d34c5651187 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -489,7 +489,8 @@ static int ssd1307fb_probe(struct i2c_client *client, vmem_size = par->width * par->height / 8; - vmem = devm_kzalloc(&client->dev, vmem_size, GFP_KERNEL); + vmem = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, + get_order(vmem_size)); if (!vmem) { dev_err(&client->dev, "Couldn't allocate graphical memory.\n"); ret = -ENOMEM; @@ -573,6 +574,7 @@ static int ssd1307fb_remove(struct i2c_client *client) if (par->ops->remove) par->ops->remove(par); fb_deferred_io_cleanup(info); + __free_pages(__va(info->fix.smem_start), get_order(info->fix.smem_len)); framebuffer_release(info); return 0; -- cgit v1.2.3-59-g8ed1b From c89eacfc700675912b53df770953c30930c2554f Mon Sep 17 00:00:00 2001 From: Thomas Niederprüm Date: Tue, 31 Mar 2015 20:27:10 +0200 Subject: fbdev: ssd1307fb: Unify init code and obtain hw specific bits from DT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 130X controllers are very similar from the configuration point of view. The configuration registers for the SSD1305/6/7 are bit identical (except the the VHCOM register and the the default values for clock setup register). This patch unifies the init code of the controller and adds hardware specific properties to DT that are needed to correctly initialize the device. The SSD130X can be wired to the OLED panel in various ways. Even for the same controller this wiring can differ from one display module to another and can not be probed by software. The added DT properties reflect these hardware decisions of the display module manufacturer. The 'com-sequential', 'com-lrremap' and 'com-invdir' values define different possibilities for the COM signals pin configuration and readout direction of the video memory. The 'segment-no-remap' allows the inversion of the memory-to-pin mapping ultimately inverting the order of the controllers output pins. The 'prechargepX' values need to be adapted according to the capacitance of the OLEDs pixel cells. So far these hardware specific bits are hard coded in the init code, making the driver usable only for one certain wiring of the controller. This patch makes the driver usable with all possible hardware setups, given a valid hw description in DT. If these values are not set in DT the default values, as they are set in the ssd1307 init code right now, are used. This implies that without the corresponding DT property "segment-no-remap" the segment remap of the ssd130X controller gets activated. Even though this is not the default behaviour according to the datasheet it maintains backward compatibility with older DTBs. Note that the SSD1306 does not seem to be using the configuration written to the registers at all. Therefore this patch does not try to maintain these values without changes in DT. For reference an example is added to the DT bindings documentation that reproduces the configuration that is set in the current init code. Signed-off-by: Thomas Niederprüm Tested-by: Olliver Schinagl Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen --- .../devicetree/bindings/video/ssd1307fb.txt | 21 +++ drivers/video/fbdev/ssd1307fb.c | 177 ++++++++++++--------- 2 files changed, 125 insertions(+), 73 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/video/ssd1307fb.txt b/Documentation/devicetree/bindings/video/ssd1307fb.txt index 7a125427ff4b..635efa3b2b27 100644 --- a/Documentation/devicetree/bindings/video/ssd1307fb.txt +++ b/Documentation/devicetree/bindings/video/ssd1307fb.txt @@ -15,6 +15,16 @@ Required properties: Optional properties: - reset-active-low: Is the reset gpio is active on physical low? + - solomon,segment-no-remap: Display needs normal (non-inverted) data column + to segment mapping + - solomon,com-seq: Display uses sequential COM pin configuration + - solomon,com-lrremap: Display uses left-right COM pin remap + - solomon,com-invdir: Display uses inverted COM pin scan direction + - solomon,com-offset: Number of the COM pin wired to the first display line + - solomon,prechargep1: Length of deselect period (phase 1) in clock cycles. + - solomon,prechargep2: Length of precharge period (phase 2) in clock cycles. + This needs to be the higher, the higher the capacitance + of the OLED's pixels is [0]: Documentation/devicetree/bindings/pwm/pwm.txt @@ -26,3 +36,14 @@ ssd1307: oled@3c { reset-gpios = <&gpio2 7>; reset-active-low; }; + +ssd1306: oled@3c { + compatible = "solomon,ssd1306fb-i2c"; + reg = <0x3c>; + pwms = <&pwm 4 3000>; + reset-gpios = <&gpio2 7>; + reset-active-low; + solomon,com-lrremap; + solomon,com-invdir; + solomon,com-offset = <32>; +}; diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 8d34c5651187..8667c7769d8a 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -40,20 +40,34 @@ struct ssd1307fb_par; -struct ssd1307fb_ops { - int (*init)(struct ssd1307fb_par *); - int (*remove)(struct ssd1307fb_par *); +struct ssd1307fb_deviceinfo { + u32 default_vcomh; + u32 default_dclk_div; + u32 default_dclk_frq; + int need_pwm; + int need_chargepump; }; struct ssd1307fb_par { + u32 com_invdir; + u32 com_lrremap; + u32 com_offset; + u32 com_seq; + u32 contrast; + u32 dclk_div; + u32 dclk_frq; + struct ssd1307fb_deviceinfo *device_info; struct i2c_client *client; u32 height; struct fb_info *info; - struct ssd1307fb_ops *ops; u32 page_offset; + u32 prechargep1; + u32 prechargep2; struct pwm_device *pwm; u32 pwm_period; int reset; + u32 seg_remap; + u32 vcomh; u32 width; }; @@ -254,69 +268,46 @@ static struct fb_deferred_io ssd1307fb_defio = { .deferred_io = ssd1307fb_deferred_io, }; -static int ssd1307fb_ssd1307_init(struct ssd1307fb_par *par) +static int ssd1307fb_init(struct ssd1307fb_par *par) { int ret; + u32 precharge, dclk, com_invdir, compins; - par->pwm = pwm_get(&par->client->dev, NULL); - if (IS_ERR(par->pwm)) { - dev_err(&par->client->dev, "Could not get PWM from device tree!\n"); - return PTR_ERR(par->pwm); - } - - par->pwm_period = pwm_get_period(par->pwm); - /* Enable the PWM */ - pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period); - pwm_enable(par->pwm); - - dev_dbg(&par->client->dev, "Using PWM%d with a %dns period.\n", - par->pwm->pwm, par->pwm_period); - - /* Map column 127 of the OLED to segment 0 */ - ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SEG_REMAP_ON); - if (ret < 0) - return ret; - - /* Turn on the display */ - ret = ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON); - if (ret < 0) - return ret; - - return 0; -} + if (par->device_info->need_pwm) { + par->pwm = pwm_get(&par->client->dev, NULL); + if (IS_ERR(par->pwm)) { + dev_err(&par->client->dev, "Could not get PWM from device tree!\n"); + return PTR_ERR(par->pwm); + } -static int ssd1307fb_ssd1307_remove(struct ssd1307fb_par *par) -{ - pwm_disable(par->pwm); - pwm_put(par->pwm); - return 0; -} + par->pwm_period = pwm_get_period(par->pwm); + /* Enable the PWM */ + pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period); + pwm_enable(par->pwm); -static struct ssd1307fb_ops ssd1307fb_ssd1307_ops = { - .init = ssd1307fb_ssd1307_init, - .remove = ssd1307fb_ssd1307_remove, -}; - -static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) -{ - int ret; + dev_dbg(&par->client->dev, "Using PWM%d with a %dns period.\n", + par->pwm->pwm, par->pwm_period); + }; /* Set initial contrast */ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CONTRAST); if (ret < 0) return ret; - ret = ssd1307fb_write_cmd(par->client, 0x7f); - if (ret < 0) - return ret; - - /* Set COM direction */ - ret = ssd1307fb_write_cmd(par->client, 0xc8); + ret = ssd1307fb_write_cmd(par->client, par->contrast); if (ret < 0) return ret; /* Set segment re-map */ - ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SEG_REMAP_ON); + if (par->seg_remap) { + ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SEG_REMAP_ON); + if (ret < 0) + return ret; + }; + + /* Set COM direction */ + com_invdir = 0xc0 | (par->com_invdir & 0x1) << 3; + ret = ssd1307fb_write_cmd(par->client, com_invdir); if (ret < 0) return ret; @@ -334,7 +325,7 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) if (ret < 0) return ret; - ret = ssd1307fb_write_cmd(par->client, 0x20); + ret = ssd1307fb_write_cmd(par->client, par->com_offset); if (ret < 0) return ret; @@ -343,7 +334,8 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) if (ret < 0) return ret; - ret = ssd1307fb_write_cmd(par->client, 0xf0); + dclk = ((par->dclk_div - 1) & 0xf) | (par->dclk_frq & 0xf) << 4; + ret = ssd1307fb_write_cmd(par->client, dclk); if (ret < 0) return ret; @@ -352,7 +344,8 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) if (ret < 0) return ret; - ret = ssd1307fb_write_cmd(par->client, 0x22); + precharge = (par->prechargep1 & 0xf) | (par->prechargep2 & 0xf) << 4; + ret = ssd1307fb_write_cmd(par->client, precharge); if (ret < 0) return ret; @@ -361,7 +354,9 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) if (ret < 0) return ret; - ret = ssd1307fb_write_cmd(par->client, 0x22); + compins = 0x02 | (!par->com_seq & 0x1) << 4 + | (par->com_lrremap & 0x1) << 5; + ret = ssd1307fb_write_cmd(par->client, compins); if (ret < 0) return ret; @@ -370,7 +365,7 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) if (ret < 0) return ret; - ret = ssd1307fb_write_cmd(par->client, 0x49); + ret = ssd1307fb_write_cmd(par->client, par->vcomh); if (ret < 0) return ret; @@ -379,7 +374,8 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) if (ret < 0) return ret; - ret = ssd1307fb_write_cmd(par->client, 0x14); + ret = ssd1307fb_write_cmd(par->client, + (par->device_info->need_chargepump & 0x1 << 2) & 0x14); if (ret < 0) return ret; @@ -393,6 +389,7 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) if (ret < 0) return ret; + /* Set column range */ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE); if (ret < 0) return ret; @@ -405,6 +402,7 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) if (ret < 0) return ret; + /* Set page range */ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE); if (ret < 0) return ret; @@ -426,18 +424,28 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) return 0; } -static struct ssd1307fb_ops ssd1307fb_ssd1306_ops = { - .init = ssd1307fb_ssd1306_init, +static struct ssd1307fb_deviceinfo ssd1307fb_ssd1306_deviceinfo = { + .default_vcomh = 0x20, + .default_dclk_div = 1, + .default_dclk_frq = 8, + .need_chargepump = 1, +}; + +static struct ssd1307fb_deviceinfo ssd1307fb_ssd1307_deviceinfo = { + .default_vcomh = 0x20, + .default_dclk_div = 2, + .default_dclk_frq = 12, + .need_pwm = 1, }; static const struct of_device_id ssd1307fb_of_match[] = { { .compatible = "solomon,ssd1306fb-i2c", - .data = (void *)&ssd1307fb_ssd1306_ops, + .data = (void *)&ssd1307fb_ssd1306_deviceinfo, }, { .compatible = "solomon,ssd1307fb-i2c", - .data = (void *)&ssd1307fb_ssd1307_ops, + .data = (void *)&ssd1307fb_ssd1307_deviceinfo, }, {}, }; @@ -468,8 +476,8 @@ static int ssd1307fb_probe(struct i2c_client *client, par->info = info; par->client = client; - par->ops = (struct ssd1307fb_ops *)of_match_device(ssd1307fb_of_match, - &client->dev)->data; + par->device_info = (struct ssd1307fb_deviceinfo *)of_match_device( + ssd1307fb_of_match, &client->dev)->data; par->reset = of_get_named_gpio(client->dev.of_node, "reset-gpios", 0); @@ -487,6 +495,27 @@ static int ssd1307fb_probe(struct i2c_client *client, if (of_property_read_u32(node, "solomon,page-offset", &par->page_offset)) par->page_offset = 1; + if (of_property_read_u32(node, "solomon,com-offset", &par->com_offset)) + par->com_offset = 0; + + if (of_property_read_u32(node, "solomon,prechargep1", &par->prechargep1)) + par->prechargep1 = 2; + + if (of_property_read_u32(node, "solomon,prechargep2", &par->prechargep2)) + par->prechargep2 = 2; + + par->seg_remap = !of_property_read_bool(node, "solomon,segment-no-remap"); + par->com_seq = of_property_read_bool(node, "solomon,com-seq"); + par->com_lrremap = of_property_read_bool(node, "solomon,com-lrremap"); + par->com_invdir = of_property_read_bool(node, "solomon,com-invdir"); + + par->contrast = 127; + par->vcomh = par->device_info->default_vcomh; + + /* Setup display timing */ + par->dclk_div = par->device_info->default_dclk_div; + par->dclk_frq = par->device_info->default_dclk_frq; + vmem_size = par->width * par->height / 8; vmem = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, @@ -539,11 +568,9 @@ static int ssd1307fb_probe(struct i2c_client *client, gpio_set_value(par->reset, 1); udelay(4); - if (par->ops->init) { - ret = par->ops->init(par); - if (ret) - goto reset_oled_error; - } + ret = ssd1307fb_init(par); + if (ret) + goto reset_oled_error; ret = register_framebuffer(info); if (ret) { @@ -556,8 +583,10 @@ static int ssd1307fb_probe(struct i2c_client *client, return 0; panel_init_error: - if (par->ops->remove) - par->ops->remove(par); + if (par->device_info->need_pwm) { + pwm_disable(par->pwm); + pwm_put(par->pwm); + }; reset_oled_error: fb_deferred_io_cleanup(info); fb_alloc_error: @@ -571,8 +600,10 @@ static int ssd1307fb_remove(struct i2c_client *client) struct ssd1307fb_par *par = info->par; unregister_framebuffer(info); - if (par->ops->remove) - par->ops->remove(par); + if (par->device_info->need_pwm) { + pwm_disable(par->pwm); + pwm_put(par->pwm); + }; fb_deferred_io_cleanup(info); __free_pages(__va(info->fix.smem_start), get_order(info->fix.smem_len)); framebuffer_release(info); -- cgit v1.2.3-59-g8ed1b From 5f2d36b3cf629ae1d70ee8476599ff53f0d1d1f1 Mon Sep 17 00:00:00 2001 From: Thomas Niederprüm Date: Tue, 31 Mar 2015 20:27:12 +0200 Subject: fbdev: ssd1307fb: Add support for SSD1305 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for the SSD1305 OLED controller. Signed-off-by: Thomas Niederprüm Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen --- Documentation/devicetree/bindings/video/ssd1307fb.txt | 2 +- drivers/video/fbdev/ssd1307fb.c | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/video/ssd1307fb.txt b/Documentation/devicetree/bindings/video/ssd1307fb.txt index 635efa3b2b27..d1be78db63f5 100644 --- a/Documentation/devicetree/bindings/video/ssd1307fb.txt +++ b/Documentation/devicetree/bindings/video/ssd1307fb.txt @@ -2,7 +2,7 @@ Required properties: - compatible: Should be "solomon,fb-". The only supported bus for - now is i2c, and the supported chips are ssd1306 and ssd1307. + now is i2c, and the supported chips are ssd1305, ssd1306 and ssd1307. - reg: Should contain address of the controller on the I2C bus. Most likely 0x3c or 0x3d - pwm: Should contain the pwm to use according to the OF device tree PWM diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 8667c7769d8a..f685d244fa2a 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -424,6 +424,12 @@ static int ssd1307fb_init(struct ssd1307fb_par *par) return 0; } +static struct ssd1307fb_deviceinfo ssd1307fb_ssd1305_deviceinfo = { + .default_vcomh = 0x34, + .default_dclk_div = 1, + .default_dclk_frq = 7, +}; + static struct ssd1307fb_deviceinfo ssd1307fb_ssd1306_deviceinfo = { .default_vcomh = 0x20, .default_dclk_div = 1, @@ -439,6 +445,10 @@ static struct ssd1307fb_deviceinfo ssd1307fb_ssd1307_deviceinfo = { }; static const struct of_device_id ssd1307fb_of_match[] = { + { + .compatible = "solomon,ssd1305fb-i2c", + .data = (void *)&ssd1307fb_ssd1305_deviceinfo, + }, { .compatible = "solomon,ssd1306fb-i2c", .data = (void *)&ssd1307fb_ssd1306_deviceinfo, @@ -612,6 +622,7 @@ static int ssd1307fb_remove(struct i2c_client *client) } static const struct i2c_device_id ssd1307fb_i2c_id[] = { + { "ssd1305fb", 0 }, { "ssd1306fb", 0 }, { "ssd1307fb", 0 }, { } -- cgit v1.2.3-59-g8ed1b From 3277e0bb8fc737174bd5e2fae5598b1595cfcdbe Mon Sep 17 00:00:00 2001 From: Thomas Niederprüm Date: Tue, 31 Mar 2015 20:27:13 +0200 Subject: fbdev: ssd1307fb: Add a module parameter to set the refresh rate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds the module parameter "refreshrate" to set delay for the deferred io. The refresh rate is given in units of Hertz. The default refresh rate is 1 Hz. The refresh rate set through the newly introduced parameter applies to all instances of the driver and for now it is not possible to change it individually. Signed-off-by: Thomas Niederprüm Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/ssd1307fb.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index f685d244fa2a..85eeda0fc2e4 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -38,6 +38,11 @@ #define SSD1307FB_SET_COM_PINS_CONFIG 0xda #define SSD1307FB_SET_VCOMH 0xdb +#define REFRESHRATE 1 + +static u_int refreshrate = REFRESHRATE; +module_param(refreshrate, uint, 0); + struct ssd1307fb_par; struct ssd1307fb_deviceinfo { @@ -263,11 +268,6 @@ static void ssd1307fb_deferred_io(struct fb_info *info, ssd1307fb_update_display(info->par); } -static struct fb_deferred_io ssd1307fb_defio = { - .delay = HZ, - .deferred_io = ssd1307fb_deferred_io, -}; - static int ssd1307fb_init(struct ssd1307fb_par *par) { int ret; @@ -466,6 +466,7 @@ static int ssd1307fb_probe(struct i2c_client *client, { struct fb_info *info; struct device_node *node = client->dev.of_node; + struct fb_deferred_io *ssd1307fb_defio; u32 vmem_size; struct ssd1307fb_par *par; u8 *vmem; @@ -536,10 +537,20 @@ static int ssd1307fb_probe(struct i2c_client *client, goto fb_alloc_error; } + ssd1307fb_defio = devm_kzalloc(&client->dev, sizeof(struct fb_deferred_io), GFP_KERNEL); + if (!ssd1307fb_defio) { + dev_err(&client->dev, "Couldn't allocate deferred io.\n"); + ret = -ENOMEM; + goto fb_alloc_error; + } + + ssd1307fb_defio->delay = HZ / refreshrate; + ssd1307fb_defio->deferred_io = ssd1307fb_deferred_io; + info->fbops = &ssd1307fb_ops; info->fix = ssd1307fb_fix; info->fix.line_length = par->width / 8; - info->fbdefio = &ssd1307fb_defio; + info->fbdefio = ssd1307fb_defio; info->var = ssd1307fb_var; info->var.xres = par->width; -- cgit v1.2.3-59-g8ed1b From 13bad59730c31e876588977534b6b6a46ce876ae Mon Sep 17 00:00:00 2001 From: Thomas Niederprüm Date: Tue, 31 Mar 2015 20:27:14 +0200 Subject: fbdev: ssd1307fb: Turn off display on driver unload. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch turns off the display when the driver is unloaded. Signed-off-by: Thomas Niederprüm Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/ssd1307fb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 85eeda0fc2e4..5f3d5a810c54 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -620,6 +620,8 @@ static int ssd1307fb_remove(struct i2c_client *client) struct fb_info *info = i2c_get_clientdata(client); struct ssd1307fb_par *par = info->par; + ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_OFF); + unregister_framebuffer(info); if (par->device_info->need_pwm) { pwm_disable(par->pwm); -- cgit v1.2.3-59-g8ed1b From 6ed5e2db52b1e27a70241ef8749780f6f5d553bf Mon Sep 17 00:00:00 2001 From: Thomas Niederprüm Date: Tue, 31 Mar 2015 20:27:15 +0200 Subject: fbdev: ssd1307fb: add backlight controls for setting the contrast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The backlight class is used to create userspace handles for setting the OLED contrast. Signed-off-by: Thomas Niederprüm Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/ssd1307fb.c | 58 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) (limited to 'drivers') diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 109462303087..54fb8f86b68d 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2478,6 +2478,7 @@ config FB_SSD1307 select FB_SYS_IMAGEBLIT select FB_DEFERRED_IO select PWM + select FB_BACKLIGHT help This driver implements support for the Solomon SSD1307 OLED controller over I2C. diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 5f3d5a810c54..77efed7a42a3 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -38,6 +39,8 @@ #define SSD1307FB_SET_COM_PINS_CONFIG 0xda #define SSD1307FB_SET_VCOMH 0xdb +#define MAX_CONTRAST 255 + #define REFRESHRATE 1 static u_int refreshrate = REFRESHRATE; @@ -424,6 +427,43 @@ static int ssd1307fb_init(struct ssd1307fb_par *par) return 0; } +static int ssd1307fb_update_bl(struct backlight_device *bdev) +{ + struct ssd1307fb_par *par = bl_get_data(bdev); + int ret; + int brightness = bdev->props.brightness; + + par->contrast = brightness; + + ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CONTRAST); + if (ret < 0) + return ret; + ret = ssd1307fb_write_cmd(par->client, par->contrast); + if (ret < 0) + return ret; + return 0; +} + +static int ssd1307fb_get_brightness(struct backlight_device *bdev) +{ + struct ssd1307fb_par *par = bl_get_data(bdev); + + return par->contrast; +} + +static int ssd1307fb_check_fb(struct backlight_device *bdev, + struct fb_info *info) +{ + return (info->bl_dev == bdev); +} + +static const struct backlight_ops ssd1307fb_bl_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = ssd1307fb_update_bl, + .get_brightness = ssd1307fb_get_brightness, + .check_fb = ssd1307fb_check_fb, +}; + static struct ssd1307fb_deviceinfo ssd1307fb_ssd1305_deviceinfo = { .default_vcomh = 0x34, .default_dclk_div = 1, @@ -464,6 +504,8 @@ MODULE_DEVICE_TABLE(of, ssd1307fb_of_match); static int ssd1307fb_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct backlight_device *bl; + char bl_name[12]; struct fb_info *info; struct device_node *node = client->dev.of_node; struct fb_deferred_io *ssd1307fb_defio; @@ -599,10 +641,24 @@ static int ssd1307fb_probe(struct i2c_client *client, goto panel_init_error; } + snprintf(bl_name, sizeof(bl_name), "ssd1307fb%d", info->node); + bl = backlight_device_register(bl_name, &client->dev, par, + &ssd1307fb_bl_ops, NULL); + bl->props.brightness = par->contrast; + bl->props.max_brightness = MAX_CONTRAST; + info->bl_dev = bl; + + if (IS_ERR(bl)) { + dev_err(&client->dev, "unable to register backlight device: %ld\n", + PTR_ERR(bl)); + goto bl_init_error; + } dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size); return 0; +bl_init_error: + unregister_framebuffer(info); panel_init_error: if (par->device_info->need_pwm) { pwm_disable(par->pwm); @@ -622,6 +678,8 @@ static int ssd1307fb_remove(struct i2c_client *client) ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_OFF); + backlight_device_unregister(info->bl_dev); + unregister_framebuffer(info); if (par->device_info->need_pwm) { pwm_disable(par->pwm); -- cgit v1.2.3-59-g8ed1b From 550e768c2a9932e037f2148ecddecd8a5ee0f26e Mon Sep 17 00:00:00 2001 From: Thomas Niederprüm Date: Tue, 31 Mar 2015 20:27:16 +0200 Subject: fbdev: ssd1307fb: Add blank mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds ssd1307fb_blank() to make the framebuffer capable of blanking. Signed-off-by: Thomas Niederprüm Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/ssd1307fb.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 77efed7a42a3..8fc224c99032 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -235,6 +235,16 @@ static ssize_t ssd1307fb_write(struct fb_info *info, const char __user *buf, return count; } +static int ssd1307fb_blank(int blank_mode, struct fb_info *info) +{ + struct ssd1307fb_par *par = info->par; + + if (blank_mode != FB_BLANK_UNBLANK) + return ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_OFF); + else + return ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON); +} + static void ssd1307fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct ssd1307fb_par *par = info->par; @@ -260,6 +270,7 @@ static struct fb_ops ssd1307fb_ops = { .owner = THIS_MODULE, .fb_read = fb_sys_read, .fb_write = ssd1307fb_write, + .fb_blank = ssd1307fb_blank, .fb_fillrect = ssd1307fb_fillrect, .fb_copyarea = ssd1307fb_copyarea, .fb_imageblit = ssd1307fb_imageblit, -- cgit v1.2.3-59-g8ed1b From c2b00024bc6f3408b0facc87227383e633131900 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 23 May 2015 20:32:35 +0300 Subject: fbdev: ssd1307fb: potential ERR_PTR dereference The error handling got shifted down a few lines from where it was supposed to be for some reason. Fixes: a14a7ba8cb0f ('fbdev: ssd1307fb: add backlight controls for setting the contrast') Signed-off-by: Dan Carpenter Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/ssd1307fb.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 8fc224c99032..9c28a77c2934 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -655,15 +655,16 @@ static int ssd1307fb_probe(struct i2c_client *client, snprintf(bl_name, sizeof(bl_name), "ssd1307fb%d", info->node); bl = backlight_device_register(bl_name, &client->dev, par, &ssd1307fb_bl_ops, NULL); - bl->props.brightness = par->contrast; - bl->props.max_brightness = MAX_CONTRAST; - info->bl_dev = bl; - if (IS_ERR(bl)) { dev_err(&client->dev, "unable to register backlight device: %ld\n", PTR_ERR(bl)); goto bl_init_error; } + + bl->props.brightness = par->contrast; + bl->props.max_brightness = MAX_CONTRAST; + info->bl_dev = bl; + dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size); return 0; -- cgit v1.2.3-59-g8ed1b From ee62eddb1a80e86ccbbbff5a8ecf4c2a2ccf95c9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 22 May 2015 16:22:16 +0200 Subject: video: omap/h3: fix tps65010 dependency The h3 LCD driver fails to link when tps65010 is configured as a loadable module: drivers/built-in.o: In function `h3_panel_disable': debugfs.c:(.text+0x206ac): undefined reference to `tps65010_set_gpio_out_value' debugfs.c:(.text+0x206cc): undefined reference to `tps65010_set_gpio_out_value' drivers/built-in.o: In function `h3_panel_enable': debugfs.c:(.text+0x206e0): undefined reference to `tps65010_set_gpio_out_value' debugfs.c:(.text+0x20704): undefined reference to `tps65010_set_gpio_out_value' This clarifies the dependency so we can only select it if the dependnecy is built-in. Signed-off-by: Arnd Bergmann Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/omap/Kconfig b/drivers/video/fbdev/omap/Kconfig index 18c4cb0d5690..29d250da8a3e 100644 --- a/drivers/video/fbdev/omap/Kconfig +++ b/drivers/video/fbdev/omap/Kconfig @@ -42,7 +42,7 @@ config FB_OMAP_LCD_MIPID config FB_OMAP_LCD_H3 bool "TPS65010 LCD controller on OMAP-H3" depends on MACH_OMAP_H3 - depends on TPS65010 + depends on TPS65010=y default y help Say Y here if you want to have support for the LCD on the -- cgit v1.2.3-59-g8ed1b From 5e47932be81e860d317498363c13153e7df37625 Mon Sep 17 00:00:00 2001 From: Thomas Niederprüm Date: Mon, 25 May 2015 21:29:21 +0200 Subject: fbdev: ssd1307fb: fix logical error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The logical not needs to be done after the bit masking. Fixes: a3998fe03e87 ("fbdev: ssd1307fb: Unify init code and obtain hw specific bits from DT") Signed-off-by: Thomas Niederprüm Reported-by: Dan Carpenter Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/ssd1307fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 9c28a77c2934..3e153c06131a 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -368,7 +368,7 @@ static int ssd1307fb_init(struct ssd1307fb_par *par) if (ret < 0) return ret; - compins = 0x02 | (!par->com_seq & 0x1) << 4 + compins = 0x02 | !(par->com_seq & 0x1) << 4 | (par->com_lrremap & 0x1) << 5; ret = ssd1307fb_write_cmd(par->client, compins); if (ret < 0) -- cgit v1.2.3-59-g8ed1b From 889dbc174933895ad28c38bec47e2794a5957ef0 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 18 May 2015 19:31:04 +0200 Subject: video: fbdev: matrox: use swap() in matroxfb_decode_var() Use kernel.h macro definition. Signed-off-by: Fabian Frederick Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/matrox/matroxfb_base.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c index 62539ca1cfa9..2ba4e54bb59d 100644 --- a/drivers/video/fbdev/matrox/matroxfb_base.c +++ b/drivers/video/fbdev/matrox/matroxfb_base.c @@ -591,12 +591,8 @@ static int matroxfb_decode_var(const struct matrox_fb_info *minfo, unsigned int max_yres; while (m1) { - int t; - while (m2 >= m1) m2 -= m1; - t = m1; - m1 = m2; - m2 = t; + swap(m1, m2); } m2 = linelen * PAGE_SIZE / m2; *ydstorg = m2 = 0x400000 % m2; -- cgit v1.2.3-59-g8ed1b From 1ebd8eccf542ee406a945c8569e362c09c93ee2c Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 18 May 2015 19:32:09 +0200 Subject: video: fbdev: use swap() in ami_set_sprite() Use kernel.h macro definition. Signed-off-by: Fabian Frederick Acked-by: Geert Uytterhoeven Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/amifb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/amifb.c b/drivers/video/fbdev/amifb.c index 35f7900a0573..a171bd93eb6a 100644 --- a/drivers/video/fbdev/amifb.c +++ b/drivers/video/fbdev/amifb.c @@ -2052,7 +2052,7 @@ static void ami_set_sprite(const struct amifb_par *par) { copins *copl, *cops; u_short hs, vs, ve; - u_long pl, ps, pt; + u_long pl, ps; short mx, my; cops = copdisplay.list[currentcop][0]; @@ -2078,7 +2078,7 @@ static void ami_set_sprite(const struct amifb_par *par) if (mod2(vs)) { lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve); shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve + 1); - pt = pl; pl = ps; ps = pt; + swap(pl, ps); } else { lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve + 1); shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve); -- cgit v1.2.3-59-g8ed1b From 36520841a443d5ee966f9632c417fcc8a25e07e3 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 18 May 2015 19:43:21 +0200 Subject: video/console: use swap() in newport_bmove() Use kernel.h macro definition. Signed-off-by: Fabian Frederick Signed-off-by: Tomi Valkeinen --- drivers/video/console/newport_con.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index a6ab9299813c..bb4e96255974 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -687,7 +687,7 @@ static int newport_scroll(struct vc_data *vc, int t, int b, int dir, static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, int h, int w) { - short xs, ys, xe, ye, xoffs, yoffs, tmp; + short xs, ys, xe, ye, xoffs, yoffs; xs = sx << 3; xe = ((sx + w) << 3) - 1; @@ -701,9 +701,7 @@ static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy, yoffs = (dy - sy) << 4; if (xoffs > 0) { /* move to the right, exchange starting points */ - tmp = xe; - xe = xs; - xs = tmp; + swap(xe, xs); } newport_wait(npregs); npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK | -- cgit v1.2.3-59-g8ed1b From 5e200b5352ccc40f39b64df5216772780ef03e7f Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 21 Apr 2015 13:16:22 -0700 Subject: video: fbdev: radeonfb: use arch_phys_wc_add() and ioremap_wc() Convert the driver from using the x86 specific MTRR code to the architecture agnostic arch_phys_wc_add(). arch_phys_wc_add() will avoid MTRR if write-combining is available, in order to take advantage of that also ensure the ioremap'd area is requested as write-combining. There are a few motivations for this: a) Take advantage of PAT when available b) Help bury MTRR code away, MTRR is architecture specific and on x86 its replaced by PAT c) Help with the goal of eventually using _PAGE_CACHE_UC over _PAGE_CACHE_UC_MINUS on x86 on ioremap_nocache() (see commit de33c442e titled "x86 PAT: fix performance drop for glx, use UC minus for ioremap(), ioremap_nocache() and pci_mmap_page_range()") The conversion done is expressed by the following Coccinelle SmPL patch, it additionally required manual intervention to address all the #ifdery and removal of redundant things which arch_phys_wc_add() already addresses such as verbose message about when MTRR fails and doing nothing when we didn't get an MTRR. @ mtrr_found @ expression index, base, size; @@ -index = mtrr_add(base, size, MTRR_TYPE_WRCOMB, 1); +index = arch_phys_wc_add(base, size); @ mtrr_rm depends on mtrr_found @ expression mtrr_found.index, mtrr_found.base, mtrr_found.size; @@ -mtrr_del(index, base, size); +arch_phys_wc_del(index); @ mtrr_rm_zero_arg depends on mtrr_found @ expression mtrr_found.index; @@ -mtrr_del(index, 0, 0); +arch_phys_wc_del(index); @ mtrr_rm_fb_info depends on mtrr_found @ struct fb_info *info; expression mtrr_found.index; @@ -mtrr_del(index, info->fix.smem_start, info->fix.smem_len); +arch_phys_wc_del(index); @ ioremap_replace_nocache depends on mtrr_found @ struct fb_info *info; expression base, size; @@ -info->screen_base = ioremap_nocache(base, size); +info->screen_base = ioremap_wc(base, size); @ ioremap_replace_default depends on mtrr_found @ struct fb_info *info; expression base, size; @@ -info->screen_base = ioremap(base, size); +info->screen_base = ioremap_wc(base, size); Generated-by: Coccinelle SmPL Cc: Benjamin Herrenschmidt Cc: Jean-Christophe Plagniol-Villard Cc: Tomi Valkeinen Cc: Suresh Siddha Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Juergen Gross Cc: Daniel Vetter Cc: Andy Lutomirski Cc: Dave Airlie Cc: Antonino Daplas Cc: linux-fbdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Luis R. Rodriguez Reviewed-by: Dave Airlie Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/aty/radeon_base.c | 29 ++++++----------------------- drivers/video/fbdev/aty/radeonfb.h | 2 +- 2 files changed, 7 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c index 01237c8fcdc6..2bdb070707e4 100644 --- a/drivers/video/fbdev/aty/radeon_base.c +++ b/drivers/video/fbdev/aty/radeon_base.c @@ -85,10 +85,6 @@ #endif /* CONFIG_PPC */ -#ifdef CONFIG_MTRR -#include -#endif - #include