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

Bryan Wu bryan.wu at canonical.com
Mon Aug 16 09:29:36 UTC 2010


Is this for Lucid or Maverick? I guess it is for Lucid.

So SRU justification will be needed for stable maintainers review.

-Bryan

On 08/16/2010 04:20 PM, 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_ */
> 





More information about the kernel-team mailing list