From 557b7d5d0787997247a798e6f46541fe9dc977fa Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Feb 2013 16:31:56 +0100 Subject: ARM: at91/avr32/atmel_lcdfb: add bus-clock entry Add hclk entry for the atmel_lcdfb bus clock. On at91sam9261, at91sam9g10 and at32ap the bus clock has to be enabled as well as the peripheral clock. Add the appropriate lookup entries to these SOCs and fake clocks to the SOCs that do not use it. This allows us to get rid of the conditional enabling of the clocks in the driver which relied on the cpu_is macros. Tested on at91sam9263 and at91sam9g45, compile-tested for other AT91-SOCs, and untested for AVR32. Signed-off-by: Johan Hovold Signed-off-by: Nicolas Ferre --- drivers/video/atmel_lcdfb.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'drivers/video/atmel_lcdfb.c') diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 025428e..c5883ca 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -821,15 +821,13 @@ static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo) static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo) { - if (sinfo->bus_clk) - clk_enable(sinfo->bus_clk); + clk_enable(sinfo->bus_clk); clk_enable(sinfo->lcdc_clk); } static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) { - if (sinfo->bus_clk) - clk_disable(sinfo->bus_clk); + clk_disable(sinfo->bus_clk); clk_disable(sinfo->lcdc_clk); } @@ -888,13 +886,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) info->fix = atmel_lcdfb_fix; /* Enable LCDC Clocks */ - if (cpu_is_at91sam9261() || cpu_is_at91sam9g10() - || cpu_is_at32ap7000()) { - sinfo->bus_clk = clk_get(dev, "hck1"); - if (IS_ERR(sinfo->bus_clk)) { - ret = PTR_ERR(sinfo->bus_clk); - goto free_info; - } + sinfo->bus_clk = clk_get(dev, "hclk"); + if (IS_ERR(sinfo->bus_clk)) { + ret = PTR_ERR(sinfo->bus_clk); + goto free_info; } sinfo->lcdc_clk = clk_get(dev, "lcdc_clk"); if (IS_ERR(sinfo->lcdc_clk)) { @@ -1055,8 +1050,7 @@ stop_clk: atmel_lcdfb_stop_clock(sinfo); clk_put(sinfo->lcdc_clk); put_bus_clk: - if (sinfo->bus_clk) - clk_put(sinfo->bus_clk); + clk_put(sinfo->bus_clk); free_info: framebuffer_release(info); out: @@ -1081,8 +1075,7 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev) unregister_framebuffer(info); atmel_lcdfb_stop_clock(sinfo); clk_put(sinfo->lcdc_clk); - if (sinfo->bus_clk) - clk_put(sinfo->bus_clk); + clk_put(sinfo->bus_clk); fb_dealloc_cmap(&info->cmap); free_irq(sinfo->irq_base, info); iounmap(sinfo->mmio); -- cgit v1.1 From 934a50bd089789d1ed74f0bef4988a97bd590afe Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Feb 2013 16:31:57 +0100 Subject: atmel_lcdfb: move lcdcon2 register access to compute_hozval Pass atmel_lcd_info structure to compute_hozval and only do the register access on SOCs that actually use it. This will also simplify the removal of the cpu_is macros. Signed-off-by: Johan Hovold Signed-off-by: Nicolas Ferre --- drivers/video/atmel_lcdfb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/video/atmel_lcdfb.c') diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index c5883ca..2effd35 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -193,14 +193,17 @@ static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = { .accel = FB_ACCEL_NONE, }; -static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) +static unsigned long compute_hozval(struct atmel_lcdfb_info *sinfo, + unsigned long xres) { + unsigned long lcdcon2; unsigned long value; if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() || cpu_is_at32ap7000())) return xres; + lcdcon2 = lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2); value = xres; if ((lcdcon2 & ATMEL_LCDC_DISTYPE) != ATMEL_LCDC_DISTYPE_TFT) { /* STN display */ @@ -591,8 +594,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value); /* Horizontal value (aka line size) */ - hozval_linesz = compute_hozval(info->var.xres, - lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2)); + hozval_linesz = compute_hozval(sinfo, info->var.xres); /* Display size */ value = (hozval_linesz - 1) << ATMEL_LCDC_HOZVAL_OFFSET; -- cgit v1.1 From bbd44f6bd9d1aa735b180b29b5719d63a8e87b55 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 7 Feb 2013 16:31:58 +0100 Subject: ARM: at91/avr32/atmel_lcdfb: add platform device-id table Add platform device-id table in order to identify the controller and determine its configuration. The currently used configuration parameters are: have_alt_pixclock - SOC uses an alternate pixel-clock calculation formula (at91sam9g45 non-ES) have_hozval - SOC has a HOZVAL field in LCDFRMCFG which is used to determine the linesize for STN displays (at91sam9261, at921sam9g10 and at32ap) have_intensity_bit - SOC uses IBGR:555 rather than BGR:565 16-bit pixel layout (at91sam9261, at91sam9263 and at91sam9rl) This allows us to remove all the remaining uses of cpu_is macros from the driver. Tested on at91sam9263 and at91sam9g45, compile-tested for other AT91-SOCs, and untested for AVR32. Signed-off-by: Johan Hovold Signed-off-by: Nicolas Ferre --- drivers/video/atmel_lcdfb.c | 89 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 10 deletions(-) (limited to 'drivers/video/atmel_lcdfb.c') diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 2effd35..c1a2914 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -34,6 +34,77 @@ #define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */ #define ATMEL_LCDC_FIFO_SIZE 512 /* words */ +struct atmel_lcdfb_config { + bool have_alt_pixclock; + bool have_hozval; + bool have_intensity_bit; +}; + +static struct atmel_lcdfb_config at91sam9261_config = { + .have_hozval = true, + .have_intensity_bit = true, +}; + +static struct atmel_lcdfb_config at91sam9263_config = { + .have_intensity_bit = true, +}; + +static struct atmel_lcdfb_config at91sam9g10_config = { + .have_hozval = true, +}; + +static struct atmel_lcdfb_config at91sam9g45_config = { + .have_alt_pixclock = true, +}; + +static struct atmel_lcdfb_config at91sam9g45es_config = { +}; + +static struct atmel_lcdfb_config at91sam9rl_config = { + .have_intensity_bit = true, +}; + +static struct atmel_lcdfb_config at32ap_config = { + .have_hozval = true, +}; + +static const struct platform_device_id atmel_lcdfb_devtypes[] = { + { + .name = "at91sam9261-lcdfb", + .driver_data = (unsigned long)&at91sam9261_config, + }, { + .name = "at91sam9263-lcdfb", + .driver_data = (unsigned long)&at91sam9263_config, + }, { + .name = "at91sam9g10-lcdfb", + .driver_data = (unsigned long)&at91sam9g10_config, + }, { + .name = "at91sam9g45-lcdfb", + .driver_data = (unsigned long)&at91sam9g45_config, + }, { + .name = "at91sam9g45es-lcdfb", + .driver_data = (unsigned long)&at91sam9g45es_config, + }, { + .name = "at91sam9rl-lcdfb", + .driver_data = (unsigned long)&at91sam9rl_config, + }, { + .name = "at32ap-lcdfb", + .driver_data = (unsigned long)&at32ap_config, + }, { + /* terminator */ + } +}; + +static struct atmel_lcdfb_config * +atmel_lcdfb_get_config(struct platform_device *pdev) +{ + unsigned long data; + + data = platform_get_device_id(pdev)->driver_data; + + return (struct atmel_lcdfb_config *)data; +} + #if defined(CONFIG_ARCH_AT91) #define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \ | FBINFO_PARTIAL_PAN_OK \ @@ -199,8 +270,7 @@ static unsigned long compute_hozval(struct atmel_lcdfb_info *sinfo, unsigned long lcdcon2; unsigned long value; - if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() - || cpu_is_at32ap7000())) + if (!sinfo->config->have_hozval) return xres; lcdcon2 = lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2); @@ -426,7 +496,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, break; case 16: /* Older SOCs use IBGR:555 rather than BGR:565. */ - if (sinfo->have_intensity_bit) + if (sinfo->config->have_intensity_bit) var->green.length = 5; else var->green.length = 6; @@ -534,7 +604,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) /* Now, the LCDC core... */ /* Set pixel clock */ - if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es()) + if (sinfo->config->have_alt_pixclock) pix_factor = 1; clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; @@ -686,7 +756,7 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red, case FB_VISUAL_PSEUDOCOLOR: if (regno < 256) { - if (sinfo->have_intensity_bit) { + if (sinfo->config->have_intensity_bit) { /* old style I+BGR:555 */ val = ((red >> 11) & 0x001f); val |= ((green >> 6) & 0x03e0); @@ -874,10 +944,9 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) } sinfo->info = info; sinfo->pdev = pdev; - if (cpu_is_at91sam9261() || cpu_is_at91sam9263() || - cpu_is_at91sam9rl()) { - sinfo->have_intensity_bit = true; - } + sinfo->config = atmel_lcdfb_get_config(pdev); + if (!sinfo->config) + goto free_info; strcpy(info->fix.id, sinfo->pdev->name); info->flags = ATMEL_LCDFB_FBINFO_DEFAULT; @@ -1146,7 +1215,7 @@ static struct platform_driver atmel_lcdfb_driver = { .remove = __exit_p(atmel_lcdfb_remove), .suspend = atmel_lcdfb_suspend, .resume = atmel_lcdfb_resume, - + .id_table = atmel_lcdfb_devtypes, .driver = { .name = "atmel_lcdfb", .owner = THIS_MODULE, -- cgit v1.1