[PATCH] dovefb: add more config options to the display controller (DCON)

Eric Miao eric.miao at canonical.com
Tue Aug 17 02:05:33 UTC 2010


On Tue, Aug 17, 2010 at 2:56 AM, Brad Figg <brad.figg at canonical.com> wrote:
> On 08/16/2010 01:20 AM, Eric Miao wrote:
>> It would be good if all the possibilities of PortA and PortB combinations in the
>> Display Controller can be exposed, instead of simply having either port_a or
>> port_b being enabled or not. Idea?
>>
>> One more thing is - can be decide lcd0_enable and lcd1_enable depending
>> on the dovefb_mach_info * pointer passed to clcd_platform_init(), it seems to
>> get overly designed to have these two parameters. And lcd0_enable/lcd1_enable
>> seems to have no relationship with DCON configuration, and some of the code
>> can be clean'ed up?
>>
>> Green?
>>
>>
>> commit 84a7f186460e6b5d1428de51cd7093404724125d
>> Author: Eric Miao<eric.miao at canonical.com>
>> Date:   Sat Aug 14 21:06:46 2010 +0800
>>
>>      dovefb: add more config options to the display controller (DCON)
>>
>>      Signed-off-by: Eric Miao<eric.miao at canonical.com>
>>
>> diff --git a/arch/arm/mach-dove/clcd.c b/arch/arm/mach-dove/clcd.c
>> index 70e9f7d..b1a8364 100755
>> --- a/arch/arm/mach-dove/clcd.c
>> +++ b/arch/arm/mach-dove/clcd.c
>> @@ -528,8 +528,7 @@ static struct resource dcon_res[] = {
>>   };
>>
>>   static struct dovedcon_mach_info dcon_data = {
>> -     .port_a = 1,
>> -     .port_b = 1,
>> +     .mode   = PORTA_ENABLE | PORTB_ENABLE,
>>   };
>>
>>   static struct platform_device dcon_platform_device = {
>> @@ -565,7 +564,8 @@ int clcd_platform_init(struct dovefb_mach_info
>> *lcd0_dmi_data,
>>                      struct dovefb_mach_info *lcd0_vid_dmi_data,
>>                      struct dovefb_mach_info *lcd1_dmi_data,
>>                      struct dovefb_mach_info *lcd1_vid_dmi_data,
>> -                    struct dovebl_platform_data *backlight_data)
>> +                    struct dovebl_platform_data *backlight_data,
>> +                    struct dovedcon_mach_info *dcon)
>>   {
>>       u32 total_x, total_y, i;
>>       u64 div_result;
>> @@ -632,16 +632,21 @@ int clcd_platform_init(struct dovefb_mach_info
>> *lcd0_dmi_data,
>>               lcd_accurate_clock = 0;
>>
>>   #ifdef CONFIG_FB_DOVE_DCON
>> -     if (lcd0_enable || lcd1_enable) {
>> -             if (lcd0_enable)
>> -                     dcon_data.port_a = 1;
>> -             if (lcd1_enable)
>> -                     dcon_data.port_b = 1;
>> +     if (dcon)
>> +             memcpy(&dcon_data, dcon, sizeof(*dcon));
>> +     else {
>> +             /* generate default according to cmdline */
>> +             if (lcd0_enable || lcd1_enable) {
>> +                     if (lcd0_enable)
>> +                             dcon_data.mode |= PORTA_ENABLE;
>> +                     if (lcd1_enable)
>> +                             dcon_data.mode |= PORTB_ENABLE;
>>   #ifdef CONFIG_FB_DOVE_CLCD_DCONB_BYPASS0
>> -             dcon_data.port_b = 1;
>> +                     dcon_data.mode |= PORTB_LCD0_BYPASS;
>>   #endif
>> -             platform_device_register(&dcon_platform_device);
>> +             }
>>       }
>> +     platform_device_register(&dcon_platform_device);
>>   #endif
>>
>>   #ifdef CONFIG_BACKLIGHT_DOVE
>> diff --git a/arch/arm/mach-dove/dove-db-setup.c
>> b/arch/arm/mach-dove/dove-db-setup.c
>> index 52d66fe..bd38ca0 100755
>> --- a/arch/arm/mach-dove/dove-db-setup.c
>> +++ b/arch/arm/mach-dove/dove-db-setup.c
>> @@ -381,7 +381,7 @@ void __init dove_db_clcd_init(void) {
>>       }
>>       clcd_platform_init(lcd0_dmi, lcd0_vid_dmi,
>>                       &dove_db_lcd1_dmi,&dove_db_lcd1_vid_dmi,
>> -                     &dove_db_backlight_data);
>> +                     &dove_db_backlight_data, NULL);
>>
>>   #endif /* CONFIG_FB_DOVE */
>>   }
>> diff --git a/arch/arm/mach-dove/dove-front-panel-common.c
>> b/arch/arm/mach-dove/dove-front-panel-common.c
>> index 3fddf67..9b97a22 100755
>> --- a/arch/arm/mach-dove/dove-front-panel-common.c
>> +++ b/arch/arm/mach-dove/dove-front-panel-common.c
>> @@ -237,6 +237,6 @@ void __init dove_fp_clcd_init(void) {
>>   #ifdef CONFIG_FB_DOVE
>>       clcd_platform_init(&dove_lcd0_dmi,&dove_lcd0_vid_dmi,
>>                       &dove_lcd1_dmi,&dove_lcd1_vid_dmi,
>> -                     &fp_backlight_data);
>> +                     &fp_backlight_data, NULL);
>>   #endif /* CONFIG_FB_DOVE */
>>   }
>> diff --git a/arch/arm/mach-dove/dove-rd-avng-setup.c
>> b/arch/arm/mach-dove/dove-rd-avng-setup.c
>> index a5e832e..947935a 100755
>> --- a/arch/arm/mach-dove/dove-rd-avng-setup.c
>> +++ b/arch/arm/mach-dove/dove-rd-avng-setup.c
>> @@ -230,7 +230,7 @@ void __init dove_rd_avng_clcd_init(void) {
>>   #ifdef CONFIG_FB_DOVE
>>       clcd_platform_init(&dove_rd_avng_lcd0_dmi,&dove_rd_avng_lcd0_vid_dmi,
>>                       &dove_rd_avng_lcd1_dmi,&dove_rd_avng_lcd1_vid_dmi,
>> -                     &dove_rd_avng_backlight_data);
>> +                     &dove_rd_avng_backlight_data, NULL);
>>   #endif /* CONFIG_FB_DOVE */
>>   }
>>
>> diff --git a/arch/arm/mach-dove/dove-videoplug-setup.c
>> b/arch/arm/mach-dove/dove-videoplug-setup.c
>> index 37a366e..ff226a1 100644
>> --- a/arch/arm/mach-dove/dove-videoplug-setup.c
>> +++ b/arch/arm/mach-dove/dove-videoplug-setup.c
>> @@ -129,7 +129,7 @@ static struct dove_ssp_platform_data
>> dove_ssp_platform_data = {
>>   void __init dove_videoplug_clcd_init(void) {
>>   #ifdef CONFIG_FB_DOVE
>>       clcd_platform_init(&dove_videoplug_lcd0_dmi,&dove_videoplug_lcd0_vid_dmi,
>> -                        NULL, NULL, NULL);
>> +                        NULL, NULL, NULL, NULL);
>>   #endif /* CONFIG_FB_DOVE */
>>   }
>>
>> diff --git a/drivers/video/marvell/dovedcon.c b/drivers/video/marvell/dovedcon.c
>> index 1f3fa24..4de60c8 100755
>> --- a/drivers/video/marvell/dovedcon.c
>> +++ b/drivers/video/marvell/dovedcon.c
>> @@ -15,7 +15,18 @@
>>
>>   #include<video/dovedcon.h>
>>
>> +#define DCON_CTRL0_VGA_CLK_DISABLE   (1<<  25)
>> +#define DCON_CTRL0_DCON_CLK_DISABLE  (1<<  24)
>> +#define DCON_CTRL0_DCON_RESET                (1<<  23)
>> +#define DCON_CTRL0_OUTPUT_DELAY              (1<<  22)
>> +#define DCON_CTRL0_LCD_DISABLE               (1<<  17)
>> +#define DCON_CTRL0_REVERSE_SCAN              (1<<  10)
>> +#define DCON_CTRL0_PORTB_SELECT              (3<<  8)
>> +#define DCON_CTRL0_PORTA_SELECT              (3<<  6)
>> +#define DCON_CTRL0_LBUF_EN           (1<<  5)
>> +
>>   #define VGA_CHANNEL_DEFAULT 0x90C78
>> +
>>   static int dovedcon_enable(struct dovedcon_info *ddi)
>>   {
>>       unsigned int channel_ctrl;
>> @@ -30,36 +41,44 @@ static int dovedcon_enable(struct dovedcon_info *ddi)
>>       /* enable lcd0 pass to PortB */
>>       ctrl0&= ~(0x3<<  8);
>>       ctrl0 |= (0x1<<  8);
>> -     ddi->port_b = 1;
>> +     ddi->mode |= PORTB_ENABLE;
>>   #endif
>> -
>> -     /*
>> -      * Enable VGA clock, clear it to enable.
>> -      */
>> -     ctrl0&= ~(ddi->port_b<<  25);
>> -
>> -     /*
>> -      * Enable LCD clock, clear it to enable
>> -      */
>> -     ctrl0&= ~(ddi->port_a<<  24);
>>
>> -     /*
>> -      * Enable LCD Parallel Interface, clear it to enable
>> -      */
>> -     ctrl0&= ~(0x1<<  17);
>> +     /* Enable DCON clock if either port is enabled */
>> +     if (ddi->mode&  (PORTA_ENABLE | PORTB_ENABLE))
>> +             ctrl0&= ~DCON_CTRL0_DCON_CLK_DISABLE;
>>
>> -     writel(ctrl0, ddi->reg_base+DCON_CTRL0);
>> +     if (ddi->mode&  PORTA_ENABLE) {
>> +             /* Enable LCD Parallel Interface on PortA */
>> +             ctrl0&= ~DCON_CTRL0_LCD_DISABLE;
>> +
>> +             /* Configure PortA mode */
>> +             ctrl0&= ~DCON_CTRL0_PORTA_SELECT;
>> +             ctrl0 |= PORTA_MODE(ddi->mode)<<  6;
>> +     }
>> +
>> +     if (ddi->mode&  PORTB_ENABLE) {
>> +             /* Enable VGA clock on PortB */
>> +             ctrl0&= ~DCON_CTRL0_VGA_CLK_DISABLE;
>> +
>> +             /* Configure PortB mode */
>> +             ctrl0&= ~DCON_CTRL0_PORTB_SELECT;
>> +             ctrl0 |= PORTB_MODE(ddi->mode)<<  8;
>> +     }
>> +
>> +     writel(ctrl0, ddi->reg_base + DCON_CTRL0);
>>
>>       /*
>>        * Configure VGA data channel and power on them.
>>        */
>> -     if (ddi->port_b) {
>> +     if (ddi->mode&  PORTB_ENABLE) {
>>               channel_ctrl = VGA_CHANNEL_DEFAULT;
>> -             writel(channel_ctrl, ddi->reg_base+DCON_VGA_DAC_CHANNEL_A_CTRL);
>> -             writel(channel_ctrl, ddi->reg_base+DCON_VGA_DAC_CHANNEL_B_CTRL);
>> -             writel(channel_ctrl, ddi->reg_base+DCON_VGA_DAC_CHANNEL_C_CTRL);
>> +             writel(channel_ctrl, ddi->reg_base + DCON_VGA_DAC_CHANNEL_A_CTRL);
>> +             writel(channel_ctrl, ddi->reg_base + DCON_VGA_DAC_CHANNEL_B_CTRL);
>> +             writel(channel_ctrl, ddi->reg_base + DCON_VGA_DAC_CHANNEL_C_CTRL);
>>       }
>>
>> +     pr_debug("%s: DCON_CTRL0 = 0x%08x\n", __func__, ctrl0);
>>       return 0;
>>   }
>>
>> @@ -171,7 +190,7 @@ static ssize_t dcon_show_pa_clk(struct device *dev,
>>
>>       ddi = dev_get_drvdata(dev);
>>
>> -     return sprintf(buf, "%d\n", ddi->port_a);
>> +     return sprintf(buf, "%d\n", (ddi->mode&  PORTA_ENABLE) ? 1 : 0);
>>   }
>>
>>   static ssize_t dcon_ena_pa_clk(struct device *dev,
>> @@ -179,38 +198,26 @@ static ssize_t dcon_ena_pa_clk(struct device *dev,
>>   {
>>       int rc;
>>       struct dovedcon_info *ddi;
>> -     unsigned long ena_clk;
>> +     unsigned long ena_clk, ctrl0;
>>
>>       ddi = dev_get_drvdata(dev);
>>       rc = strict_strtoul(buf, 0,&ena_clk);
>>       if (rc)
>>               return rc;
>>
>> -     rc = -ENXIO;
>> -
>> -     if (ddi->port_a != ena_clk) {
>> -             unsigned int ctrl0;
>> -
>> -             ddi->port_a = ena_clk;
>> -
>> -             /*
>> -              * Get current configuration of CTRL0
>> -              */
>> -             ctrl0 = readl(ddi->reg_base+DCON_CTRL0);
>> -
>> -             /* enable or disable LCD clk. */
>> -             if (0 == ddi->port_a)
>> -                     ctrl0 |= (0x1<<  24);
>> -             else
>> -                     ctrl0&= ~(0x1<<  24);
>> -
>> -             /* Apply setting. */
>> -             writel(ctrl0, ddi->reg_base+DCON_CTRL0);
>> +     if ((ddi->mode&  PORTA_ENABLE)&&  !ena_clk) {
>> +             ctrl0 = readl(ddi->reg_base + DCON_CTRL0);
>> +             ctrl0&= ~DCON_CTRL0_DCON_CLK_DISABLE;
>> +             writel(ctrl0, ddi->reg_base + DCON_CTRL0);
>>       }
>>
>> -     rc = count;
>> +     if (ena_clk&&  !(ddi->mode&  PORTA_ENABLE)) {
>> +             ctrl0 = readl(ddi->reg_base + DCON_CTRL0);
>> +             ctrl0 |= DCON_CTRL0_DCON_CLK_DISABLE;
>> +             writel(ctrl0, ddi->reg_base + DCON_CTRL0);
>> +     }
>>
>> -     return rc;
>> +     return count;
>>   }
>>
>>   static ssize_t dcon_show_pb_clk(struct device *dev,
>> @@ -220,7 +227,7 @@ static ssize_t dcon_show_pb_clk(struct device *dev,
>>
>>       ddi = dev_get_drvdata(dev);
>>
>> -     return sprintf(buf, "%d\n", ddi->port_b);
>> +     return sprintf(buf, "%d\n", (ddi->mode&  PORTB_ENABLE) ? 1 : 0);
>>   }
>>
>>   static ssize_t dcon_ena_pb_clk(struct device *dev,
>> @@ -228,36 +235,26 @@ static ssize_t dcon_ena_pb_clk(struct device *dev,
>>   {
>>       int rc;
>>       struct dovedcon_info *ddi;
>> -     unsigned long ena_clk;
>> +     unsigned long ena_clk, ctrl0;
>>
>>       ddi = dev_get_drvdata(dev);
>>       rc = strict_strtoul(buf, 0,&ena_clk);
>>       if (rc)
>>               return rc;
>>
>> -     if (ddi->port_b != ena_clk) {
>> -             unsigned int ctrl0;
>> -
>> -             ddi->port_b = ena_clk;
>> -
>> -             /*
>> -              * Get current configuration of CTRL0
>> -              */
>> -             ctrl0 = readl(ddi->reg_base+DCON_CTRL0);
>> -
>> -             /* enable or disable LCD clk. */
>> -             if (0 == ddi->port_b)
>> -                     ctrl0 |= (0x1<<  25);
>> -             else
>> -                     ctrl0&= ~(0x1<<  25);
>> -
>> -             /* Apply setting. */
>> -             writel(ctrl0, ddi->reg_base+DCON_CTRL0);
>> +     if ((ddi->mode&  PORTB_ENABLE)&&  !ena_clk) {
>> +             ctrl0 = readl(ddi->reg_base + DCON_CTRL0);
>> +             ctrl0&= ~DCON_CTRL0_VGA_CLK_DISABLE;
>> +             writel(ctrl0, ddi->reg_base + DCON_CTRL0);
>>       }
>>
>> -     rc = count;
>> +     if (ena_clk&&  !(ddi->mode&  PORTB_ENABLE)) {
>> +             ctrl0 = readl(ddi->reg_base + DCON_CTRL0);
>> +             ctrl0 |= DCON_CTRL0_VGA_CLK_DISABLE;
>> +             writel(ctrl0, ddi->reg_base + DCON_CTRL0);
>> +     }
>>
>> -     return rc;
>> +     return count;
>>   }
>>
>>   static ssize_t dcon_show_pa_mode(struct device *dev,
>> @@ -576,8 +573,7 @@ static int __init dovedcon_probe(struct
>> platform_device *pdev)
>>       if (!IS_ERR(ddi->clk))
>>               clk_enable(ddi->clk);
>>
>> -     ddi->port_a = ddmi->port_a;
>> -     ddi->port_b = ddmi->port_b;
>> +     ddi->mode = ddmi->mode;
>>
>>       /* Initialize DCON hardware */
>>       dovedcon_enable(ddi);
>> diff --git a/include/video/dovedcon.h b/include/video/dovedcon.h
>> index a9ec18b..3bfa02d 100644
>> --- a/include/video/dovedcon.h
>> +++ b/include/video/dovedcon.h
>> @@ -43,17 +43,29 @@
>>
>>   #ifdef __KERNEL__
>>
>> +#define PORTA_ENABLE         (1<<  15)
>> +#define PORTA_LCD0_BYPASS    (PORTA_ENABLE | 0)
>> +#define PORTA_OLPC_MODE              (PORTA_ENABLE | 1)
>> +#define PORTA_DUAL_VIEW              (PORTA_ENABLE | 2)
>> +#define PORTA_EXT_DCON               (PORTA_ENABLE | 3)
>> +
>> +#define PORTB_ENABLE         (1<<  31)
>> +#define PORTB_LCD1_BYPASS    (PORTB_ENABLE | (0<<  16))
>> +#define PORTB_LCD0_BYPASS    (PORTB_ENABLE | (1<<  16))
>> +#define PORTB_DCON_COPY              (PORTB_ENABLE | (3<<  16))
>> +
>> +#define PORTA_MODE(m)                ((m)&  0xf)
>> +#define PORTB_MODE(m)                (((m)>>  16)&  0xf)
>> +
>>   struct dovedcon_mach_info {
>> -     unsigned int port_a;
>> -     unsigned int port_b;
>> +     uint32_t        mode;
>>   };
>>
>>   struct dovedcon_info {
>>       void                    *reg_base;
>>       struct clk              *clk;
>> -     struct notifier_block fb_notif;
>> -     unsigned int port_a;
>> -     unsigned int port_b;
>> +     uint32_t                mode;
>> +     struct notifier_block   fb_notif;
>>   };
>>
>>   #define to_dcon_device(obj) container_of(obj, struct dovedcon_info, dev)
>> diff --git a/include/video/dovefb.h b/include/video/dovefb.h
>> index 8f9f058..b2fb7c4 100755
>> --- a/include/video/dovefb.h
>> +++ b/include/video/dovefb.h
>> @@ -20,6 +20,7 @@
>>   /*              Header Files                      */
>>   /* ---------------------------------------------- */
>>   #include<linux/fb.h>
>> +#include<video/dovedcon.h>
>>
>>   /* ---------------------------------------------- */
>>   /*              IOCTL Definition                  */
>> @@ -476,7 +477,8 @@ int clcd_platform_init(struct dovefb_mach_info
>> *lcd0_dmi_data,
>>                      struct dovefb_mach_info *lcd0_vid_dmi_data,
>>                      struct dovefb_mach_info *lcd1_dmi_data,
>>                      struct dovefb_mach_info *lcd1_vid_dmi_data,
>> -                    struct dovebl_platform_data *backlight_data);
>> +                    struct dovebl_platform_data *backlight_data,
>> +                    struct dovedcon_mach_info *dcon);
>>
>>
>>   #endif /* _KERNEL_ */
>>
>
> Eric,
>
> I can't tell if this is a request to have this patch applied to
> Lucid or this is just a discussion of a potential patch.
>

Brad,

Sorry I should have made it clear. It was supposed to be RFC only
and not targeting for Lucid.

And since it's a small feature enhancement, I'd expect this to be in
Maverick if the review is positive. This will be used in hedley to
enable their quite unique display configuration though.




More information about the kernel-team mailing list