Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH] locomo: drop special locomo_{read/write}l in favor of io{read/write}16
From: H Hartley Sweeten @ 2011-06-20 21:54 UTC (permalink / raw)
  To: linux-arm-kernel

All the locomo registers are 16-bit ioremap'ed memory addresses.  

Make the locomo drivers use generic purpose io routines: ioread16
and iowrite16 instead of directly accessing memory.

There are still a couple checkpatch warnings about lines exceeding
79 characters.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Richard Purdie <rpurdie@rpsys.net>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Lennert Buytenhek <buytenh@secretlab.ca>

---

diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index b55c362..3ced960 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -141,13 +141,14 @@ static struct locomo_dev_info locomo_devices[] = {
 static void locomo_handler(unsigned int irq, struct irq_desc *desc)
 {
 	struct locomo *lchip = irq_get_chip_data(irq);
-	int req, i;
+	u16 req;
+	int i;
 
 	/* Acknowledge the parent IRQ */
 	desc->irq_data.chip->irq_ack(&desc->irq_data);
 
 	/* check why this interrupt was generated */
-	req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
+	req = ioread16(lchip->base + LOCOMO_ICR) & 0x0f00;
 
 	if (req) {
 		/* generate the next interrupt(s) */
@@ -168,19 +169,21 @@ static void locomo_ack_irq(struct irq_data *d)
 static void locomo_mask_irq(struct irq_data *d)
 {
 	struct locomo *lchip = irq_data_get_irq_chip_data(d);
-	unsigned int r;
-	r = locomo_readl(lchip->base + LOCOMO_ICR);
+	u16 r;
+
+	r = ioread16(lchip->base + LOCOMO_ICR);
 	r &= ~(0x0010 << (d->irq - lchip->irq_base));
-	locomo_writel(r, lchip->base + LOCOMO_ICR);
+	iowrite16(r, lchip->base + LOCOMO_ICR);
 }
 
 static void locomo_unmask_irq(struct irq_data *d)
 {
 	struct locomo *lchip = irq_data_get_irq_chip_data(d);
-	unsigned int r;
-	r = locomo_readl(lchip->base + LOCOMO_ICR);
+	u16 r;
+
+	r = ioread16(lchip->base + LOCOMO_ICR);
 	r |= (0x0010 << (d->irq - lchip->irq_base));
-	locomo_writel(r, lchip->base + LOCOMO_ICR);
+	iowrite16(r, lchip->base + LOCOMO_ICR);
 }
 
 static struct irq_chip locomo_chip = {
@@ -265,11 +268,11 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
 #ifdef CONFIG_PM
 
 struct locomo_save_data {
-	u16	LCM_GPO;
-	u16	LCM_SPICT;
-	u16	LCM_GPE;
-	u16	LCM_ASD;
-	u16	LCM_SPIMD;
+	u16	LCM_GPO;	/* GPIO */
+	u16	LCM_SPICT;	/* SPI */
+	u16	LCM_GPE;	/* GPIO */
+	u16	LCM_ASD;	/* ADSTART */
+	u16	LCM_SPIMD;	/* SPI */
 };
 
 static int locomo_suspend(struct platform_device *dev, pm_message_t state)
@@ -286,30 +289,31 @@ static int locomo_suspend(struct platform_device *dev, pm_message_t state)
 
 	spin_lock_irqsave(&lchip->lock, flags);
 
-	save->LCM_GPO     = locomo_readl(lchip->base + LOCOMO_GPO);	/* GPIO */
-	locomo_writel(0x00, lchip->base + LOCOMO_GPO);
-	save->LCM_SPICT   = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPICT);	/* SPI */
-	locomo_writel(0x40, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
-	save->LCM_GPE     = locomo_readl(lchip->base + LOCOMO_GPE);	/* GPIO */
-	locomo_writel(0x00, lchip->base + LOCOMO_GPE);
-	save->LCM_ASD     = locomo_readl(lchip->base + LOCOMO_ASD);	/* ADSTART */
-	locomo_writel(0x00, lchip->base + LOCOMO_ASD);
-	save->LCM_SPIMD   = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);	/* SPI */
-	locomo_writel(0x3C14, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
-
-	locomo_writel(0x00, lchip->base + LOCOMO_PAIF);
-	locomo_writel(0x00, lchip->base + LOCOMO_DAC);
-	locomo_writel(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC);
-
-	if ((locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88))
-		locomo_writel(0x00, lchip->base + LOCOMO_C32K); 	/* CLK32 off */
+	save->LCM_GPO = ioread16(lchip->base + LOCOMO_GPO);
+	save->LCM_SPICT = ioread16(lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
+	save->LCM_GPE = ioread16(lchip->base + LOCOMO_GPE);
+	save->LCM_ASD = ioread16(lchip->base + LOCOMO_ASD);
+	save->LCM_SPIMD = ioread16(lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
+	iowrite16(0x00, lchip->base + LOCOMO_GPO);
+	iowrite16(0x40, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
+	iowrite16(0x00, lchip->base + LOCOMO_GPE);
+	iowrite16(0x00, lchip->base + LOCOMO_ASD);
+	iowrite16(0x3C14, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
+
+	iowrite16(0x00, lchip->base + LOCOMO_PAIF);
+	iowrite16(0x00, lchip->base + LOCOMO_DAC);
+	iowrite16(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC);
+
+	if ((ioread16(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) &&
+	    (ioread16(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88))
+		iowrite16(0x00, lchip->base + LOCOMO_C32K);	/* CLK32 off */
 	else
 		/* 18MHz already enabled, so no wait */
-		locomo_writel(0xc1, lchip->base + LOCOMO_C32K); 	/* CLK32 on */
+		iowrite16(0xc1, lchip->base + LOCOMO_C32K);	/* CLK32 on */
 
-	locomo_writel(0x00, lchip->base + LOCOMO_TADC);		/* 18MHz clock off*/
-	locomo_writel(0x00, lchip->base + LOCOMO_AUDIO + LOCOMO_ACC);			/* 22MHz/24MHz clock off */
-	locomo_writel(0x00, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);			/* FL */
+	iowrite16(0x00, lchip->base + LOCOMO_TADC);		/* 18MHz clock off*/
+	iowrite16(0x00, lchip->base + LOCOMO_AUDIO + LOCOMO_ACC);	/* 22MHz/24MHz clock off */
+	iowrite16(0x00, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);	/* FL */
 
 	spin_unlock_irqrestore(&lchip->lock, flags);
 
@@ -320,7 +324,7 @@ static int locomo_resume(struct platform_device *dev)
 {
 	struct locomo *lchip = platform_get_drvdata(dev);
 	struct locomo_save_data *save;
-	unsigned long r;
+	u16 r;
 	unsigned long flags;
 
 	save = lchip->saved_state;
@@ -329,20 +333,20 @@ static int locomo_resume(struct platform_device *dev)
 
 	spin_lock_irqsave(&lchip->lock, flags);
 
-	locomo_writel(save->LCM_GPO, lchip->base + LOCOMO_GPO);
-	locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
-	locomo_writel(save->LCM_GPE, lchip->base + LOCOMO_GPE);
-	locomo_writel(save->LCM_ASD, lchip->base + LOCOMO_ASD);
-	locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
+	iowrite16(save->LCM_GPO, lchip->base + LOCOMO_GPO);
+	iowrite16(save->LCM_SPICT, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
+	iowrite16(save->LCM_GPE, lchip->base + LOCOMO_GPE);
+	iowrite16(save->LCM_ASD, lchip->base + LOCOMO_ASD);
+	iowrite16(save->LCM_SPIMD, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
 
-	locomo_writel(0x00, lchip->base + LOCOMO_C32K);
-	locomo_writel(0x90, lchip->base + LOCOMO_TADC);
+	iowrite16(0x00, lchip->base + LOCOMO_C32K);
+	iowrite16(0x90, lchip->base + LOCOMO_TADC);
 
-	locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KSC);
-	r = locomo_readl(lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+	iowrite16(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KSC);
+	r = ioread16(lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
 	r &= 0xFEFF;
-	locomo_writel(r, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
-	locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
+	iowrite16(r, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+	iowrite16(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
 
 	spin_unlock_irqrestore(&lchip->lock, flags);
 
@@ -371,7 +375,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
 {
 	struct locomo_platform_data *pdata = me->platform_data;
 	struct locomo *lchip;
-	unsigned long r;
+	u16 r;
 	int i, ret = -ENODEV;
 
 	lchip = kzalloc(sizeof(struct locomo), GFP_KERNEL);
@@ -398,54 +402,53 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
 	}
 
 	/* locomo initialize */
-	locomo_writel(0, lchip->base + LOCOMO_ICR);
+	iowrite16(0, lchip->base + LOCOMO_ICR);
 	/* KEYBOARD */
-	locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+	iowrite16(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
 
 	/* GPIO */
-	locomo_writel(0, lchip->base + LOCOMO_GPO);
-	locomo_writel((LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14))
-			, lchip->base + LOCOMO_GPE);
-	locomo_writel((LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14))
-			, lchip->base + LOCOMO_GPD);
-	locomo_writel(0, lchip->base + LOCOMO_GIE);
+	iowrite16(0, lchip->base + LOCOMO_GPO);
+	r = LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14);
+	iowrite16(r, lchip->base + LOCOMO_GPE);
+	iowrite16(r, lchip->base + LOCOMO_GPD);
+	iowrite16(0, lchip->base + LOCOMO_GIE);
 
 	/* Frontlight */
-	locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
-	locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
+	iowrite16(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
+	iowrite16(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
 
 	/* Longtime timer */
-	locomo_writel(0, lchip->base + LOCOMO_LTINT);
+	iowrite16(0, lchip->base + LOCOMO_LTINT);
 	/* SPI */
-	locomo_writel(0, lchip->base + LOCOMO_SPI + LOCOMO_SPIIE);
+	iowrite16(0, lchip->base + LOCOMO_SPI + LOCOMO_SPIIE);
 
-	locomo_writel(6 + 8 + 320 + 30 - 10, lchip->base + LOCOMO_ASD);
-	r = locomo_readl(lchip->base + LOCOMO_ASD);
+	iowrite16(6 + 8 + 320 + 30 - 10, lchip->base + LOCOMO_ASD);
+	r = ioread16(lchip->base + LOCOMO_ASD);
 	r |= 0x8000;
-	locomo_writel(r, lchip->base + LOCOMO_ASD);
+	iowrite16(r, lchip->base + LOCOMO_ASD);
 
-	locomo_writel(6 + 8 + 320 + 30 - 10 - 128 + 4, lchip->base + LOCOMO_HSD);
-	r = locomo_readl(lchip->base + LOCOMO_HSD);
+	iowrite16(6 + 8 + 320 + 30 - 10 - 128 + 4, lchip->base + LOCOMO_HSD);
+	r = ioread16(lchip->base + LOCOMO_HSD);
 	r |= 0x8000;
-	locomo_writel(r, lchip->base + LOCOMO_HSD);
+	iowrite16(r, lchip->base + LOCOMO_HSD);
 
-	locomo_writel(128 / 8, lchip->base + LOCOMO_HSC);
+	iowrite16(128 / 8, lchip->base + LOCOMO_HSC);
 
 	/* XON */
-	locomo_writel(0x80, lchip->base + LOCOMO_TADC);
+	iowrite16(0x80, lchip->base + LOCOMO_TADC);
 	udelay(1000);
 	/* CLK9MEN */
-	r = locomo_readl(lchip->base + LOCOMO_TADC);
+	r = ioread16(lchip->base + LOCOMO_TADC);
 	r |= 0x10;
-	locomo_writel(r, lchip->base + LOCOMO_TADC);
+	iowrite16(r, lchip->base + LOCOMO_TADC);
 	udelay(100);
 
 	/* init DAC */
-	r = locomo_readl(lchip->base + LOCOMO_DAC);
+	r = ioread16(lchip->base + LOCOMO_DAC);
 	r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, lchip->base + LOCOMO_DAC);
+	iowrite16(r, lchip->base + LOCOMO_DAC);
 
-	r = locomo_readl(lchip->base + LOCOMO_VER);
+	r = ioread16(lchip->base + LOCOMO_VER);
 	printk(KERN_INFO "LoCoMo Chip: %lu%lu\n", (r >> 8), (r & 0xff));
 
 	/*
@@ -541,26 +544,26 @@ void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir
 {
 	struct locomo *lchip = dev_get_drvdata(dev);
 	unsigned long flags;
-	unsigned int r;
+	u16 r;
 
 	if (!lchip)
 		return;
 
 	spin_lock_irqsave(&lchip->lock, flags);
 
-	r = locomo_readl(lchip->base + LOCOMO_GPD);
+	r = ioread16(lchip->base + LOCOMO_GPD);
 	if (dir)
 		r |= bits;
 	else
 		r &= ~bits;
-	locomo_writel(r, lchip->base + LOCOMO_GPD);
+	iowrite16(r, lchip->base + LOCOMO_GPD);
 
-	r = locomo_readl(lchip->base + LOCOMO_GPE);
+	r = ioread16(lchip->base + LOCOMO_GPE);
 	if (dir)
 		r |= bits;
 	else
 		r &= ~bits;
-	locomo_writel(r, lchip->base + LOCOMO_GPE);
+	iowrite16(r, lchip->base + LOCOMO_GPE);
 
 	spin_unlock_irqrestore(&lchip->lock, flags);
 }
@@ -570,13 +573,13 @@ int locomo_gpio_read_level(struct device *dev, unsigned int bits)
 {
 	struct locomo *lchip = dev_get_drvdata(dev);
 	unsigned long flags;
-	unsigned int ret;
+	u16 ret;
 
 	if (!lchip)
 		return -ENODEV;
 
 	spin_lock_irqsave(&lchip->lock, flags);
-	ret = locomo_readl(lchip->base + LOCOMO_GPL);
+	ret = ioread16(lchip->base + LOCOMO_GPL);
 	spin_unlock_irqrestore(&lchip->lock, flags);
 
 	ret &= bits;
@@ -588,13 +591,13 @@ int locomo_gpio_read_output(struct device *dev, unsigned int bits)
 {
 	struct locomo *lchip = dev_get_drvdata(dev);
 	unsigned long flags;
-	unsigned int ret;
+	u16 ret;
 
 	if (!lchip)
 		return -ENODEV;
 
 	spin_lock_irqsave(&lchip->lock, flags);
-	ret = locomo_readl(lchip->base + LOCOMO_GPO);
+	ret = ioread16(lchip->base + LOCOMO_GPO);
 	spin_unlock_irqrestore(&lchip->lock, flags);
 
 	ret &= bits;
@@ -606,19 +609,19 @@ void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set)
 {
 	struct locomo *lchip = dev_get_drvdata(dev);
 	unsigned long flags;
-	unsigned int r;
+	u16 r;
 
 	if (!lchip)
 		return;
 
 	spin_lock_irqsave(&lchip->lock, flags);
 
-	r = locomo_readl(lchip->base + LOCOMO_GPO);
+	r = ioread16(lchip->base + LOCOMO_GPO);
 	if (set)
 		r |= bits;
 	else
 		r &= ~bits;
-	locomo_writel(r, lchip->base + LOCOMO_GPO);
+	iowrite16(r, lchip->base + LOCOMO_GPO);
 
 	spin_unlock_irqrestore(&lchip->lock, flags);
 }
@@ -626,35 +629,35 @@ EXPORT_SYMBOL(locomo_gpio_write);
 
 static void locomo_m62332_sendbit(void *mapbase, int bit)
 {
-	unsigned int r;
+	u16 r;
 
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
 	udelay(DAC_DATA_HOLD_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
 	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
 
 	if (bit & 1) {
-		r = locomo_readl(mapbase + LOCOMO_DAC);
+		r = ioread16(mapbase + LOCOMO_DAC);
 		r |=  LOCOMO_DAC_SDAOEB;
-		locomo_writel(r, mapbase + LOCOMO_DAC);
+		iowrite16(r, mapbase + LOCOMO_DAC);
 		udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
 	} else {
-		r = locomo_readl(mapbase + LOCOMO_DAC);
+		r = ioread16(mapbase + LOCOMO_DAC);
 		r &=  ~(LOCOMO_DAC_SDAOEB);
-		locomo_writel(r, mapbase + LOCOMO_DAC);
+		iowrite16(r, mapbase + LOCOMO_DAC);
 		udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
 	}
 
 	udelay(DAC_DATA_SETUP_TIME);	/* 250 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
 	udelay(DAC_SCL_HIGH_HOLD_TIME);	/*  4.0 usec */
 }
@@ -664,7 +667,7 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
 	struct locomo *lchip = locomo_chip_driver(ldev);
 	int i;
 	unsigned char data;
-	unsigned int r;
+	u16 r;
 	void *mapbase = lchip->base;
 	unsigned long flags;
 
@@ -672,14 +675,14 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
 
 	/* Start */
 	udelay(DAC_BUS_FREE_TIME);	/* 5.0 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r |=  LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
 	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.0 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_START_HOLD_TIME);	/* 5.0 usec */
 	udelay(DAC_DATA_HOLD_TIME);	/* 300 nsec */
 
@@ -690,21 +693,21 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
 	}
 
 	/* Check A bit */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
 	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
 	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
-	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
+	if (ioread16(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
 		printk(KERN_WARNING "locomo: m62332_senddata Error 1\n");
 		goto out;
 	}
@@ -718,21 +721,21 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
 	}
 
 	/* Check A bit */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
 	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
 	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
-	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
+	if (ioread16(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
 		printk(KERN_WARNING "locomo: m62332_senddata Error 2\n");
 		goto out;
 	}
@@ -743,45 +746,45 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
 	}
 
 	/* Check A bit */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
 	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
 	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
-	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
+	if (ioread16(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
 		printk(KERN_WARNING "locomo: m62332_senddata Error 3\n");
 	}
 
 out:
 	/* stop */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
 	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
 	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r |=  LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
 	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4 usec */
 
-	r = locomo_readl(mapbase + LOCOMO_DAC);
+	r = ioread16(mapbase + LOCOMO_DAC);
 	r |=  LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
+	iowrite16(r, mapbase + LOCOMO_DAC);
 	udelay(DAC_LOW_SETUP_TIME);	/* 1000 nsec */
 	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
 
@@ -804,10 +807,10 @@ void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf)
 		locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
 
 	spin_lock_irqsave(&lchip->lock, flags);
-	locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
+	iowrite16(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
 	udelay(100);
-	locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
-	locomo_writel(bpwf | LOCOMO_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
+	iowrite16(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
+	iowrite16(bpwf | LOCOMO_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
 	spin_unlock_irqrestore(&lchip->lock, flags);
 }
 EXPORT_SYMBOL(locomo_frontlight_set);
diff --git a/arch/arm/include/asm/hardware/locomo.h b/arch/arm/include/asm/hardware/locomo.h
index 74e51d6..dc90c21 100644
--- a/arch/arm/include/asm/hardware/locomo.h
+++ b/arch/arm/include/asm/hardware/locomo.h
@@ -13,9 +13,6 @@
 #ifndef _ASM_ARCH_LOCOMO
 #define _ASM_ARCH_LOCOMO
 
-#define locomo_writel(val,addr)	({ *(volatile u16 *)(addr) = (val); })
-#define locomo_readl(addr)	(*(volatile u16 *)(addr))
-
 /* LOCOMO version */
 #define LOCOMO_VER	0x00
 
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index b1ab298..ddb9595 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -31,6 +31,7 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 
 #include <asm/hardware/locomo.h>
 #include <asm/irq.h>
@@ -86,35 +87,35 @@ struct locomokbd {
 /* helper functions for reading the keyboard matrix */
 static inline void locomokbd_charge_all(unsigned long membase)
 {
-	locomo_writel(0x00FF, membase + LOCOMO_KSC);
+	iowrite16(0x00FF, membase + LOCOMO_KSC);
 }
 
 static inline void locomokbd_activate_all(unsigned long membase)
 {
-	unsigned long r;
+	u16 r;
 
-	locomo_writel(0, membase + LOCOMO_KSC);
-	r = locomo_readl(membase + LOCOMO_KIC);
+	iowrite16(0, membase + LOCOMO_KSC);
+	r = ioread16(membase + LOCOMO_KIC);
 	r &= 0xFEFF;
-	locomo_writel(r, membase + LOCOMO_KIC);
+	iowrite16(r, membase + LOCOMO_KIC);
 }
 
 static inline void locomokbd_activate_col(unsigned long membase, int col)
 {
-	unsigned short nset;
-	unsigned short nbset;
+	u16 nset;
+	u16 nbset;
 
 	nset = 0xFF & ~(1 << col);
 	nbset = (nset << 8) + nset;
-	locomo_writel(nbset, membase + LOCOMO_KSC);
+	iowrite16(nbset, membase + LOCOMO_KSC);
 }
 
 static inline void locomokbd_reset_col(unsigned long membase, int col)
 {
-	unsigned short nbset;
+	u16 nbset;
 
 	nbset = ((0xFF & ~(1 << col)) << 8) + 0xFF;
-	locomo_writel(nbset, membase + LOCOMO_KSC);
+	iowrite16(nbset, membase + LOCOMO_KSC);
 }
 
 /*
@@ -126,7 +127,7 @@ static inline void locomokbd_reset_col(unsigned long membase, int col)
 /* Scan the hardware keyboard and push any changes up through the input layer */
 static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 {
-	unsigned int row, col, rowd;
+	u16 row, col, rowd;
 	unsigned long flags;
 	unsigned int num_pressed;
 	unsigned long membase = locomokbd->base;
@@ -141,7 +142,7 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 		locomokbd_activate_col(membase, col);
 		udelay(KB_DELAY);
 
-		rowd = ~locomo_readl(membase + LOCOMO_KIB);
+		rowd = ~ioread16(membase + LOCOMO_KIB);
 		for (row = 0; row < KB_ROWS; row++) {
 			unsigned int scancode, pressed, key;
 
@@ -194,11 +195,11 @@ static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
 	struct locomokbd *locomokbd = dev_id;
 	u16 r;
 
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC);
+	r = ioread16(locomokbd->base + LOCOMO_KIC);
 	if ((r & 0x0001) = 0)
 		return IRQ_HANDLED;
 
-	locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
+	iowrite16(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
 
 	/** wait chattering delay **/
 	udelay(100);
@@ -222,8 +223,8 @@ static int locomokbd_open(struct input_dev *dev)
 	struct locomokbd *locomokbd = input_get_drvdata(dev);
 	u16 r;
 	
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010;
-	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+	r = ioread16(locomokbd->base + LOCOMO_KIC) | 0x0010;
+	iowrite16(r, locomokbd->base + LOCOMO_KIC);
 	return 0;
 }
 
@@ -232,8 +233,8 @@ static void locomokbd_close(struct input_dev *dev)
 	struct locomokbd *locomokbd = input_get_drvdata(dev);
 	u16 r;
 	
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010;
-	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+	r = ioread16(locomokbd->base + LOCOMO_KIC) & ~0x0010;
+	iowrite16(r, locomokbd->base + LOCOMO_KIC);
 }
 
 static int __devinit locomokbd_probe(struct locomo_dev *dev)
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
index 1f7c10f..6cc6b69 100644
--- a/drivers/leds/leds-locomo.c
+++ b/drivers/leds/leds-locomo.c
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/leds.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/hardware/locomo.h>
@@ -24,9 +25,9 @@ static void locomoled_brightness_set(struct led_classdev *led_cdev,
 
 	local_irq_save(flags);
 	if (value)
-		locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
+		iowrite16(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
 	else
-		locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
+		iowrite16(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
 	local_irq_restore(flags);
 }
 
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index be20b5c..37f325c 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
+#include <linux/io.h>
 
 #include <asm/hardware/locomo.h>
 #include <asm/irq.h>
@@ -49,13 +50,13 @@ static void locomolcd_on(int comadj)
 	mdelay(10);
 
 	/* TFTCRST | CPSOUT=0 | CPSEN */
-	locomo_writel(0x01, locomolcd_dev->mapbase + LOCOMO_TC);
+	iowrite16(0x01, locomolcd_dev->mapbase + LOCOMO_TC);
 
 	/* Set CPSD */
-	locomo_writel(6, locomolcd_dev->mapbase + LOCOMO_CPSD);
+	iowrite16(6, locomolcd_dev->mapbase + LOCOMO_CPSD);
 
 	/* TFTCRST | CPSOUT=0 | CPSEN */
-	locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC);
+	iowrite16((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC);
 	mdelay(10);
 
 	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
@@ -65,7 +66,7 @@ static void locomolcd_on(int comadj)
 static void locomolcd_off(int comadj)
 {
 	/* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
-	locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
+	iowrite16(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
 	mdelay(1);
 
 	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
@@ -75,7 +76,7 @@ static void locomolcd_off(int comadj)
 	mdelay(700);
 
 	/* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
-	locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC);
+	iowrite16(0, locomolcd_dev->mapbase + LOCOMO_TC);
 	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
 	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
 }

^ permalink raw reply related

* Regression in panic
From: Mandeep Singh Baines @ 2011-06-20 22:15 UTC (permalink / raw)
  To: Dave Airlie, Andrew Morton, Jesse Barnes, Olof Johansson
  Cc: linux-fbdev, dri-devel, linux-kernel

On Tue, Jun 22, 2010 at 8:12 PM, Dave Airlie <airlied@gmail.com> wrote:
> From: Jesse Barnes <jbarnes@virtuousgeek.org>
>
> Jesse's initial patch commit said:
>
> "At panic time (i.e. when oops_in_progress is set) we should try a bit
> harder to update the screen and make sure output gets to the VT, since
> some drivers are capable of flipping back to it.
>
> So make sure we try to unblank and update the display if called from a
> panic context."
>
> I've enhanced this to add a flag to the vc that console layer can set
> to indicate they want this behaviour to occur. This also adds support
> to fbcon for that flag and adds an fb flag for drivers to indicate
> they want to use the support. It enables this for KMS drivers.
>
> Signed-off-by: Dave Airlie <airlied@redhat.com>

Hi Dave,

I think this change is causing a regression I'm seeing in panic.
Before this change, I'd get a
reboot on panic (we've configured as such).

With this change, my machine gets wedged if the machine is running in
X when the panic occurs.

I traced the code flow to this:

bust_spinlocks(0);
 ->unblank_screen();
   ->do_unblank_screen(0);
     ->vc->vc_sw->con_blank(vc, 0, 0);
       ->fbcon_blank(vc, 0, 0);
         ->update_screen(vc);
           ->redraw_screen(vc, 0);
             ->vc->vc_sw->con_switch(vc);
               ->fbcon_switch(vc);
                 ->ops->update_start(info);
                   ->bit_update_start(info);
                    ->fb_pan_display(info, &ops->var);
                      ->info->fbops->fb_pan_display(var, info);
                        ->drm_fb_helper_pan_display(var, info);
                          ->mutex_lock(&dev->mode_config.mutex); *this blocks*

With this change, there is now a lot going on in the panic path. Stuff
that I'm not sure is safe when panicking. In addition to the
mutex_lock, there is also a del_timer_sync()
now happening in the context of panic().

I see this bug with a 2.6.38 kernel but did a quick scan of a newer
kernels and did not see anything that changed in this path so I
suspect its still there.

Reverting this change fixes the regression.

Regards,
Mandeep

> ---
>  drivers/char/vt.c                       |   13 +++++++++----
>  drivers/gpu/drm/i915/intel_fb.c         |    4 +---
>  drivers/gpu/drm/nouveau/nouveau_fbcon.c |    1 +
>  drivers/gpu/drm/radeon/radeon_fb.c      |    2 +-
>  drivers/video/console/fbcon.c           |    4 +++-
>  include/linux/console_struct.h          |    1 +
>  include/linux/fb.h                      |    4 ++++
>  include/linux/vt_kern.h                 |    7 +++++++
>  8 files changed, 27 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/char/vt.c b/drivers/char/vt.c
> index 7cdb6ee..6e04c9e 100644
> --- a/drivers/char/vt.c
> +++ b/drivers/char/vt.c
> @@ -698,7 +698,10 @@ void redraw_screen(struct vc_data *vc, int is_switch)
>                        update_attr(vc);
>                        clear_buffer_attributes(vc);
>                }
> -               if (update && vc->vc_mode != KD_GRAPHICS)
> +
> +               /* Forcibly update if we're panicing */
> +               if ((update && vc->vc_mode != KD_GRAPHICS) ||
> +                   vt_force_oops_output(vc))
>                        do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
>        }
>        set_cursor(vc);
> @@ -736,6 +739,7 @@ static void visual_init(struct vc_data *vc, int num, int init)
>        vc->vc_hi_font_mask = 0;
>        vc->vc_complement_mask = 0;
>        vc->vc_can_do_color = 0;
> +       vc->vc_panic_force_write = false;
>        vc->vc_sw->con_init(vc, init);
>        if (!vc->vc_complement_mask)
>                vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
> @@ -2498,7 +2502,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
>                goto quit;
>        }
>
> -       if (vc->vc_mode != KD_TEXT)
> +       if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
>                goto quit;
>
>        /* undraw cursor first */
> @@ -3703,7 +3707,8 @@ void do_unblank_screen(int leaving_gfx)
>                return;
>        }
>        vc = vc_cons[fg_console].d;
> -       if (vc->vc_mode != KD_TEXT)
> +       /* Try to unblank in oops case too */
> +       if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
>                return; /* but leave console_blanked != 0 */
>
>        if (blankinterval) {
> @@ -3712,7 +3717,7 @@ void do_unblank_screen(int leaving_gfx)
>        }
>
>        console_blanked = 0;
> -       if (vc->vc_sw->con_blank(vc, 0, leaving_gfx))
> +       if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc))
>                /* Low-level driver cannot restore -> do it ourselves */
>                update_screen(vc);
>        if (console_blank_hook)
> diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
> index c3c5052..bd5d87a 100644
> --- a/drivers/gpu/drm/i915/intel_fb.c
> +++ b/drivers/gpu/drm/i915/intel_fb.c
> @@ -128,7 +128,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
>
>        strcpy(info->fix.id, "inteldrmfb");
>
> -       info->flags = FBINFO_DEFAULT;
> +       info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
>        info->fbops = &intelfb_ops;
>
>        /* setup aperture base/size for vesafb takeover */
> @@ -146,8 +146,6 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
>        info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset;
>        info->fix.smem_len = size;
>
> -       info->flags = FBINFO_DEFAULT;
> -
>        info->screen_base = ioremap_wc(dev->agp->base + obj_priv->gtt_offset,
>                                       size);
>        if (!info->screen_base) {
> diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
> index c9a4a0d..9b2d3b7 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
> @@ -250,6 +250,7 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
>                info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
>                              FBINFO_HWACCEL_FILLRECT |
>                              FBINFO_HWACCEL_IMAGEBLIT;
> +       info->flags |= FBINFO_CAN_FORCE_OUTPUT;
>        info->fbops = &nouveau_fbcon_ops;
>        info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset -
>                               dev_priv->vm_vram_base;
> diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
> index dc1634b..dbf8696 100644
> --- a/drivers/gpu/drm/radeon/radeon_fb.c
> +++ b/drivers/gpu/drm/radeon/radeon_fb.c
> @@ -224,7 +224,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
>
>        drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
>
> -       info->flags = FBINFO_DEFAULT;
> +       info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
>        info->fbops = &radeonfb_ops;
>
>        tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start;
> diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
> index b0a3fa0..7eadb35 100644
> --- a/drivers/video/console/fbcon.c
> +++ b/drivers/video/console/fbcon.c
> @@ -283,7 +283,8 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
>        struct fbcon_ops *ops = info->fbcon_par;
>
>        return (info->state != FBINFO_STATE_RUNNING ||
> -               vc->vc_mode != KD_TEXT || ops->graphics);
> +               vc->vc_mode != KD_TEXT || ops->graphics) &&
> +               !vt_force_oops_output(vc);
>  }
>
>  static inline int get_color(struct vc_data *vc, struct fb_info *info,
> @@ -1073,6 +1074,7 @@ static void fbcon_init(struct vc_data *vc, int init)
>        if (p->userfont)
>                charcnt = FNTCHARCNT(p->fontdata);
>
> +       vc->vc_panic_force_write = !!(info->flags & FBINFO_CAN_FORCE_OUTPUT);
>        vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
>        vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
>        if (charcnt = 256) {
> diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
> index 38fe59d..d7d9acd 100644
> --- a/include/linux/console_struct.h
> +++ b/include/linux/console_struct.h
> @@ -105,6 +105,7 @@ struct vc_data {
>        struct vc_data **vc_display_fg;         /* [!] Ptr to var holding fg console for this display */
>        unsigned long   vc_uni_pagedir;
>        unsigned long   *vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
> +       bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
>        /* additional information is in vt_kern.h */
>  };
>
> diff --git a/include/linux/fb.h b/include/linux/fb.h
> index 8e5a9df..25f4950 100644
> --- a/include/linux/fb.h
> +++ b/include/linux/fb.h
> @@ -812,6 +812,10 @@ struct fb_tile_ops {
>  */
>  #define FBINFO_BE_MATH  0x100000
>
> +/* report to the VT layer that this fb driver can accept forced console
> +   output like oopses */
> +#define FBINFO_CAN_FORCE_OUTPUT     0x200000
> +
>  struct fb_info {
>        int node;
>        int flags;
> diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
> index 7f56db4..56cce34 100644
> --- a/include/linux/vt_kern.h
> +++ b/include/linux/vt_kern.h
> @@ -100,6 +100,13 @@ extern int unbind_con_driver(const struct consw *csw, int first, int last,
>                             int deflt);
>  int vty_init(const struct file_operations *console_fops);
>
> +static inline bool vt_force_oops_output(struct vc_data *vc)
> +{
> +       if (oops_in_progress && vc->vc_panic_force_write)
> +               return true;
> +       return false;
> +}
> +
>  /*
>  * vc_screen.c shares this temporary buffer with the console write code so that
>  * we can easily avoid touching user space while holding the console spinlock.
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

^ permalink raw reply

* Re: Regression in panic
From: David Rientjes @ 2011-06-20 23:03 UTC (permalink / raw)
  To: Mandeep Singh Baines
  Cc: Dave Airlie, Andrew Morton, Jesse Barnes, Olof Johansson,
	linux-fbdev, dri-devel, linux-kernel, Chris Fowler
In-Reply-To: <BANLkTingstCoWk0H20nN1J7t3H=mndSdnL2YpeW2R46fhL2kpA@mail.gmail.com>

On Mon, 20 Jun 2011, Mandeep Singh Baines wrote:

> Hi Dave,
> 
> I think this change is causing a regression I'm seeing in panic.
> Before this change, I'd get a
> reboot on panic (we've configured as such).
> 
> With this change, my machine gets wedged if the machine is running in
> X when the panic occurs.
> 
> I traced the code flow to this:
> 
> bust_spinlocks(0);
>  ->unblank_screen();
>    ->do_unblank_screen(0);
>      ->vc->vc_sw->con_blank(vc, 0, 0);
>        ->fbcon_blank(vc, 0, 0);
>          ->update_screen(vc);
>            ->redraw_screen(vc, 0);
>              ->vc->vc_sw->con_switch(vc);
>                ->fbcon_switch(vc);
>                  ->ops->update_start(info);
>                    ->bit_update_start(info);
>                     ->fb_pan_display(info, &ops->var);
>                       ->info->fbops->fb_pan_display(var, info);
>                         ->drm_fb_helper_pan_display(var, info);
>                           ->mutex_lock(&dev->mode_config.mutex); *this blocks*
> 
> With this change, there is now a lot going on in the panic path. Stuff
> that I'm not sure is safe when panicking. In addition to the
> mutex_lock, there is also a del_timer_sync()
> now happening in the context of panic().
> 
> I see this bug with a 2.6.38 kernel but did a quick scan of a newer
> kernels and did not see anything that changed in this path so I
> suspect its still there.
> 
> Reverting this change fixes the regression.
> 

Chris Fowler reports something similar when running 2.6.38 by inducing a 
kernel panic via the oom killer -- see 
http://marc.info/?l=linux-kernel&m\x130805985022791.  I've added him to the 
cc so he can participate in the thread and cherry-pick any fixes (last 
status update was that he was going to be trying 2.6.38.8).

^ permalink raw reply

* Re: Regression in panic
From: Mandeep Singh Baines @ 2011-06-20 23:20 UTC (permalink / raw)
  To: David Rientjes
  Cc: Dave Airlie, Andrew Morton, Jesse Barnes, Olof Johansson,
	linux-fbdev, dri-devel, linux-kernel, Chris Fowler
In-Reply-To: <alpine.DEB.2.00.1106201601220.15259@chino.kir.corp.google.com>

On Mon, Jun 20, 2011 at 4:03 PM, David Rientjes <rientjes@google.com> wrote:
> On Mon, 20 Jun 2011, Mandeep Singh Baines wrote:
>
>> Hi Dave,
>>
>> I think this change is causing a regression I'm seeing in panic.
>> Before this change, I'd get a
>> reboot on panic (we've configured as such).
>>
>> With this change, my machine gets wedged if the machine is running in
>> X when the panic occurs.
>>
>> I traced the code flow to this:
>>
>> bust_spinlocks(0);
>>  ->unblank_screen();
>>    ->do_unblank_screen(0);
>>      ->vc->vc_sw->con_blank(vc, 0, 0);
>>        ->fbcon_blank(vc, 0, 0);
>>          ->update_screen(vc);
>>            ->redraw_screen(vc, 0);
>>              ->vc->vc_sw->con_switch(vc);
>>                ->fbcon_switch(vc);
>>                  ->ops->update_start(info);
>>                    ->bit_update_start(info);
>>                     ->fb_pan_display(info, &ops->var);
>>                       ->info->fbops->fb_pan_display(var, info);
>>                         ->drm_fb_helper_pan_display(var, info);
>>                           ->mutex_lock(&dev->mode_config.mutex); *this blocks*
>>
>> With this change, there is now a lot going on in the panic path. Stuff
>> that I'm not sure is safe when panicking. In addition to the
>> mutex_lock, there is also a del_timer_sync()
>> now happening in the context of panic().
>>
>> I see this bug with a 2.6.38 kernel but did a quick scan of a newer
>> kernels and did not see anything that changed in this path so I
>> suspect its still there.
>>
>> Reverting this change fixes the regression.
>>
>
> Chris Fowler reports something similar when running 2.6.38 by inducing a
> kernel panic via the oom killer -- see
> http://marc.info/?l=linux-kernel&m\x130805985022791.  I've added him to the
> cc so he can participate in the thread and cherry-pick any fixes (last
> status update was that he was going to be trying 2.6.38.8).
>

One potential fix might be to convert the mutex_lock to a try if
oops_in_progress but
I suspect oops_in_progress checks may be needed in a bunch of other places in
the screen_unblank code path.

^ permalink raw reply

* Re: [PATCH 2/2] video: omap2: Compile omap2 support only when needed
From: Tushar Behera @ 2011-06-21  4:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1308575201.2076.57.camel@deskari>

Hi,

On Monday 20 June 2011 06:36 PM, Tomi Valkeinen wrote:
> On Mon, 2011-06-20 at 16:16 +0530, Tushar Behera wrote:
>> Currently display support for omap2 is selected by default and
>> it gets built for all the configurations.
>>
>> Instead of it being a built-in feature, it's compilation should
>> depend on the config option CONFIG_FB_OMAP2.
>
> No, I don't think so. omap2 directory contains vram, vrfb and omapdss,
> all of which can be used without omapfb driver. vram and vrfb can be
> even used without omapdss driver.
Even if I build the kernel with i386_defconfig, I get some compiled 
files within drivers/video/omap2.

$ make ARCH=x86 i386_defconfig O=out_dir
$ make ARCH=x86 O=out_dir

$ ls out_dir/drivers/video/omap2
built-in.o  displays  modules.builtin  modules.order

IMHO, drivers/video/omap2/ should not be compiled if the kernel is not 
built for omap2.
>
> Is this patch fixing some real problem?
This patch does not fix any other problem.


>
>   Tomi
>
>


-- 
Tushar Behera

^ permalink raw reply

* Re: [PATCH 1/2] config: omap2+: force fb and dss support as built-in
From: Tushar Behera @ 2011-06-21  5:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1308575086.2076.55.camel@deskari>

On Monday 20 June 2011 06:34 PM, Tomi Valkeinen wrote:
> On Mon, 2011-06-20 at 16:16 +0530, Tushar Behera wrote:
>> In certain board files, there are references to vram related functions
>> which are defined in drivers/video/omap2/vram.c. Because of this direct
>> dependency, CONFIG_FB_OMAP2 should be a built-in feature.
>
> arch/arm/plat-omap/include/plat/vram.h defines dummy inline function in
> case vram.c is not compiled in, so the board files should compile fine.
>
>> As per the current architecture, CONFIG_FB_OMAP2 is dependent on
>> CONFIG_OMAP2_DSS. Hence CONFIG_OMAP2_DSS support should also be selected
>> by default.
>
> The configuration is fine as it is. And anyway, if things do not compile
> when something is configured as a module, the correct fix is hardly just
> changing the feature to be compiled built-in =).
Agreed. :)
I am not an expert in DSS. I just wanted to raise my concern.
>
>> Cc: Tony Lindgren<tony@atomide.com>
>> Cc: Samreen<samreen@ti.com>
>> Signed-off-by: Tushar Behera<tushar.behera@linaro.org>
>> ---
>> arch/arm/mach-omap2/built-in.o: In function `rx51_video_mem_init':
>> linux-linaro-2.6.39/arch/arm/mach-omap2/board-rx51-video.c:97: undefined reference to `omap_vram_set_sdram_vram'
>> arch/arm/plat-omap/built-in.o: In function `omap_reserve':
>> linux-linaro-2.6.39/arch/arm/plat-omap/common.c:66: undefined reference to `omap_vram_reserve_sdram_memblock'
>> arch/arm/plat-omap/built-in.o: In function `omap_detect_sram':
>> linux-linaro-2.6.39/arch/arm/plat-omap/sram.c:179: undefined reference to `omap_vram_reserve_sram'
>> make[1]: *** [.tmp_vmlinux1] Error 1
>> make: *** [sub-make] Error 2
>
> Compiles fine for me. Perhaps you are using some old kernel?
As mentioned in the cover letter, we get this error only if 2/2 is 
applied and 1/2 is not applied.

I tested this by applying 2/2 on v3.0-rc4 and using omap2plus_defconfig.
>
>   Tomi
>
>


-- 
Tushar Behera

^ permalink raw reply

* Re: [PATCH 2/2] video: omap2: Compile omap2 support only when
From: Tomi Valkeinen @ 2011-06-21  5:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4E0022B5.9000500@linaro.org>

On Tue, 2011-06-21 at 10:18 +0530, Tushar Behera wrote:
> Hi,
> 
> On Monday 20 June 2011 06:36 PM, Tomi Valkeinen wrote:
> > On Mon, 2011-06-20 at 16:16 +0530, Tushar Behera wrote:
> >> Currently display support for omap2 is selected by default and
> >> it gets built for all the configurations.
> >>
> >> Instead of it being a built-in feature, it's compilation should
> >> depend on the config option CONFIG_FB_OMAP2.
> >
> > No, I don't think so. omap2 directory contains vram, vrfb and omapdss,
> > all of which can be used without omapfb driver. vram and vrfb can be
> > even used without omapdss driver.
> Even if I build the kernel with i386_defconfig, I get some compiled 
> files within drivers/video/omap2.
> 
> $ make ARCH=x86 i386_defconfig O=out_dir
> $ make ARCH=x86 O=out_dir
> 
> $ ls out_dir/drivers/video/omap2
> built-in.o  displays  modules.builtin  modules.order
> 
> IMHO, drivers/video/omap2/ should not be compiled if the kernel is not 
> built for omap2.

Ok. Yes, that's a known "problem". We could have a OMAPx check there,
but then again, the driver is a driver for the DSS HW, which could, at
least in theory, used in other SoCs.

I don't think any driver should normally depend on ARCH_something or
MACH_something.

I think this is more of a "problem" with the build system. The same
thing can be seen with, for example, drivers/video/backlight/ and
drivers/video/display/ directories. In practice the created files do not
affect the kernel in any way, as far as I see.

 Tomi



^ permalink raw reply

* Re: [PATCHv2 15/28] OMAP4: HWMOD: Modify DSS opt clocks
From: Tomi Valkeinen @ 2011-06-21  6:20 UTC (permalink / raw)
  To: b-cousson; +Cc: linux-fbdev, paul, khilman, linux-omap mailing list
In-Reply-To: <1308137027.1974.39.camel@deskari>

On Wed, 2011-06-15 at 14:23 +0300, Tomi Valkeinen wrote:
> On Thu, 2011-06-09 at 16:56 +0300, Tomi Valkeinen wrote:
> > Add missing DSS optional clocks to HWMOD data for OMAP4xxx.
> > 
> > Add HWMOD_CONTROL_OPT_CLKS_IN_RESET flag for dispc to fix dispc reset.
> > 
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> 
> Benoit (and/or Paul/Kevin), can you ack this and the other HWMOD
> patches, or give comments?

Ping.

 Tomi



^ permalink raw reply

* Re: [PATCH] locomo: drop special locomo_{read/write}l in favor of
From: Dmitry Torokhov @ 2011-06-21 10:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201106201454.18070.hartleys@visionengravers.com>

On Mon, Jun 20, 2011 at 02:54:17PM -0700, H Hartley Sweeten wrote:
> All the locomo registers are 16-bit ioremap'ed memory addresses.  
> 
> Make the locomo drivers use generic purpose io routines: ioread16
> and iowrite16 instead of directly accessing memory.
> 
> There are still a couple checkpatch warnings about lines exceeding
> 79 characters.
> 
> Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>

Input parts look good to me.

Acked-by: Dmitry Torokhov <dtor@mail.ru>

-- 
Dmitry

^ permalink raw reply

* Re: [PATCHv2 20/28] OMAP: DSS2: Use PM runtime & HWMOD support
From: Kevin Hilman @ 2011-06-21 14:49 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, b-cousson, paul
In-Reply-To: <1307627810-3768-21-git-send-email-tomi.valkeinen@ti.com>

Tomi Valkeinen <tomi.valkeinen@ti.com> writes:

> Use PM runtime and HWMOD support to handle enabling and disabling of DSS
> modules.
>
> Each DSS module will have get and put functions which can be used to
> enable and disable that module. The functions use pm_runtime and hwmod
> opt-clocks to enable the hardware.
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

Runtime PM usage is much better on this version, thanks!

Like Paul, I'm not crazy about the helper functions, especially the ones
that don't do much other than call runtime PM with some debug code
around them since runtime PM already has useful debug.

However, you're the maintainer and the one who has to debug this code
more than I do, so that decision is up to you.

Acked-by: Kevin Hilman <khilman@ti.com>

Kevin

^ permalink raw reply

* Re: [PATCHv2 20/28] OMAP: DSS2: Use PM runtime & HWMOD support
From: Tomi Valkeinen @ 2011-06-21 15:18 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, linux-fbdev, b-cousson, paul
In-Reply-To: <87vcvzz1bc.fsf@ti.com>

On Tue, 2011-06-21 at 07:49 -0700, Kevin Hilman wrote:
> Tomi Valkeinen <tomi.valkeinen@ti.com> writes:
> 
> > Use PM runtime and HWMOD support to handle enabling and disabling of DSS
> > modules.
> >
> > Each DSS module will have get and put functions which can be used to
> > enable and disable that module. The functions use pm_runtime and hwmod
> > opt-clocks to enable the hardware.
> >
> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> 
> Runtime PM usage is much better on this version, thanks!
> 
> Like Paul, I'm not crazy about the helper functions, especially the ones
> that don't do much other than call runtime PM with some debug code
> around them since runtime PM already has useful debug.
> 
> However, you're the maintainer and the one who has to debug this code
> more than I do, so that decision is up to you.

I have to say I'm not familiar with runtime PM's debug (yet, I need to
check it out), but if I'm debugging DSS, I'm not interested in runtime
PM's debug concerning some other drivers or any verbose details about
runtime PM.

So by having the wrappers I can just observe DSS debug, and see when DSS
enables/disables runtime PM etc.

If runtime PM's debug allows me to easily only see debugs about DSS,
then I agree that the wrappers are extra.

 Tomi



^ permalink raw reply

* [PATCH/RFC] fbdev: Add FOURCC-based format configuration API
From: Laurent Pinchart @ 2011-06-21 15:36 UTC (permalink / raw)
  To: linux-fbdev; +Cc: linux-media, dri-devel, FlorianSchandinat
In-Reply-To: <4DDAE63A.3070203@gmx.de>

This API will be used to support YUV frame buffer formats in a standard
way.

Last but not least, create a much needed fbdev API documentation and
document the format setting APIs.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 Documentation/fb/api.txt |  284 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fb.h       |   12 ++-
 2 files changed, 294 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/fb/api.txt

A bit late, but here's a patch that implements an fbdev format configuration
API to support YUV formats. My next step is to implement a prototype in an
fbdev driver to make sure the API works well.

Thanks to Florian Tobias Schandinat for providing feedback on the initial RFC.
Comments are as usual more than welcome. If you feel like writing a couple of
lines of documentation, feel free to extend the API doc. That's much needed.

diff --git a/Documentation/fb/api.txt b/Documentation/fb/api.txt
new file mode 100644
index 0000000..d4cd6ec
--- /dev/null
+++ b/Documentation/fb/api.txt
@@ -0,0 +1,284 @@
+			The Frame Buffer Device API
+			---------------------------
+
+Last revised: June 21, 2011
+
+
+0. Introduction
+---------------
+
+This document describes the frame buffer API used by applications to interact
+with frame buffer devices. In-kernel APIs between device drivers and the frame
+buffer core are not described.
+
+Due to a lack of documentation in the original frame buffer API, drivers
+behaviours differ in subtle (and not so subtle) ways. This document describes
+the recommended API implementation, but applications should be prepared to
+deal with different behaviours.
+
+
+1. Capabilities
+---------------
+
+Device and driver capabilities are reported in the fixed screen information
+capabilities field.
+
+struct fb_fix_screeninfo {
+	...
+	__u16 capabilities;		/* see FB_CAP_*			*/
+	...
+};
+
+Application should use those capabilities to find out what features they can
+expect from the device and driver.
+
+- FB_CAP_FOURCC
+
+The driver supports the four character code (FOURCC) based format setting API.
+When supported, formats are configured using a FOURCC instead of manually
+specifying color components layout.
+
+
+2. Types and visuals
+--------------------
+
+Pixels are stored in memory in hardware-dependent formats. Applications need
+to be aware of the pixel storage format in order to write image data to the
+frame buffer memory in the format expected by the hardware.
+
+Formats are described by frame buffer types and visuals. Some visuals require
+additional information, which are stored in the variable screen information
+bits_per_pixel, grayscale, fourcc, red, green, blue and transp fields.
+
+The following types and visuals are supported.
+
+- FB_TYPE_PACKED_PIXELS
+
+Color components (usually RGB or YUV) are packed together into macropixels
+that are stored in a single plane. The exact color components layout is
+described in a visual-dependent way.
+
+Frame buffer visuals that don't use multiple color components per pixel
+(such as monochrome and pseudo-color visuals) are reported as packed frame
+buffer types, even though they don't stricly speaking pack color components
+into macropixels.
+
+- FB_TYPE_PLANES
+
+Color components are stored in separate planes. Planes are located
+contiguously in memory.
+
+- FB_VISUAL_MONO01
+
+Pixels are black or white and stored on one bit. A bit set to 1 represents a
+black pixel and a bit set to 0 a white pixel. Pixels are packed together in
+bytes with 8 pixels per byte.
+
+FB_VISUAL_MONO01 is used with FB_TYPE_PACKED_PIXELS only.
+
+- FB_VISUAL_MONO10
+
+Pixels are black or white and stored on one bit. A bit set to 1 represents a
+white pixel and a bit set to 0 a black pixel. Pixels are packed together in
+bytes with 8 pixels per byte.
+
+FB_VISUAL_MONO01 is used with FB_TYPE_PACKED_PIXELS only.
+
+- FB_VISUAL_TRUECOLOR
+
+Pixels are broken into red, green and blue components, and each component
+indexes a read-only lookup table for the corresponding value. Lookup tables
+are device-dependent, and provide linear or non-linear ramps.
+
+Each component is stored in memory according to the variable screen
+information red, green, blue and transp fields.
+
+- FB_VISUAL_PSEUDOCOLOR and FB_VISUAL_STATIC_PSEUDOCOLOR
+
+Pixel values are encoded as indices into a colormap that stores red, green and
+blue components. The colormap is read-only for FB_VISUAL_STATIC_PSEUDOCOLOR
+and read-write for FB_VISUAL_PSEUDOCOLOR.
+
+Each pixel value is stored in the number of bits reported by the variable
+screen information bits_per_pixel field. Pixels are contiguous in memory.
+
+FB_VISUAL_PSEUDOCOLOR and FB_VISUAL_STATIC_PSEUDOCOLOR are used with
+FB_TYPE_PACKED_PIXELS only.
+
+- FB_VISUAL_DIRECTCOLOR
+
+Pixels are broken into red, green and blue components, and each component
+indexes a programmable lookup table for the corresponding value.
+
+Each component is stored in memory according to the variable screen
+information red, green, blue and transp fields.
+
+- FB_VISUAL_FOURCC
+
+Pixels are stored in memory as described by the format FOURCC identifier
+stored in the variable screen information fourcc field.
+
+
+3. Screen information
+---------------------
+
+Screen information are queried by applications using the FBIOGET_FSCREENINFO
+and FBIOGET_VSCREENINFO ioctls. Those ioctls take a pointer to a
+fb_fix_screeninfo and fb_var_screeninfo structure respectively.
+
+struct fb_fix_screeninfo stores device independent unchangeable information
+about the frame buffer device and the current format. Those information can't
+be directly modified by applications, but can be changed by the driver when an
+application modifies the format.
+
+struct fb_fix_screeninfo {
+	char id[16];			/* identification string eg "TT Builtin" */
+	unsigned long smem_start;	/* Start of frame buffer mem */
+					/* (physical address) */
+	__u32 smem_len;			/* Length of frame buffer mem */
+	__u32 type;			/* see FB_TYPE_*		*/
+	__u32 type_aux;			/* Interleave for interleaved Planes */
+	__u32 visual;			/* see FB_VISUAL_*		*/
+	__u16 xpanstep;			/* zero if no hardware panning  */
+	__u16 ypanstep;			/* zero if no hardware panning  */
+	__u16 ywrapstep;		/* zero if no hardware ywrap    */
+	__u32 line_length;		/* length of a line in bytes    */
+	unsigned long mmio_start;	/* Start of Memory Mapped I/O   */
+					/* (physical address) */
+	__u32 mmio_len;			/* Length of Memory Mapped I/O  */
+	__u32 accel;			/* Indicate to driver which	*/
+					/*  specific chip/card we have	*/
+	__u16 capabilities;		/* see FB_CAP_*			*/
+	__u16 reserved[2];		/* Reserved for future compatibility */
+};
+
+struct fb_var_screeninfo stores device independent changeable information
+about a frame buffer device, its current format and video mode, as well as
+other miscellaneous parameters.
+
+struct fb_var_screeninfo {
+	__u32 xres;			/* visible resolution		*/
+	__u32 yres;
+	__u32 xres_virtual;		/* virtual resolution		*/
+	__u32 yres_virtual;
+	__u32 xoffset;			/* offset from virtual to visible */
+	__u32 yoffset;			/* resolution			*/
+
+	__u32 bits_per_pixel;		/* guess what			*/
+	union {
+		__u32 grayscale;	/* != 0 Graylevels instead of colors */
+		__u32 fourcc;		/* video mode */
+	};
+
+	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
+	struct fb_bitfield green;	/* else only length is significant */
+	struct fb_bitfield blue;
+	struct fb_bitfield transp;	/* transparency			*/
+
+	__u32 nonstd;			/* != 0 Non standard pixel format */
+
+	__u32 activate;			/* see FB_ACTIVATE_*		*/
+
+	__u32 height;			/* height of picture in mm    */
+	__u32 width;			/* width of picture in mm     */
+
+	__u32 accel_flags;		/* (OBSOLETE) see fb_info.flags */
+
+	/* Timing: All values in pixclocks, except pixclock (of course) */
+	__u32 pixclock;			/* pixel clock in ps (pico seconds) */
+	__u32 left_margin;		/* time from sync to picture	*/
+	__u32 right_margin;		/* time from picture to sync	*/
+	__u32 upper_margin;		/* time from sync to picture	*/
+	__u32 lower_margin;
+	__u32 hsync_len;		/* length of horizontal sync	*/
+	__u32 vsync_len;		/* length of vertical sync	*/
+	__u32 sync;			/* see FB_SYNC_*		*/
+	__u32 vmode;			/* see FB_VMODE_*		*/
+	__u32 rotate;			/* angle we rotate counter clockwise */
+	__u32 reserved[5];		/* Reserved for future compatibility */
+};
+
+To modify variable information, applications call the FBIOPUT_VSCREENINFO
+ioctl with a pointer to a fb_var_screeninfo structure. If the call is
+successful, the driver will update the fixed screen information accordingly.
+
+Instead of filling the complete fb_var_screeninfo structure manually,
+applications should call the FBIOGET_VSCREENINFO ioctl and modify only the
+fields they care about.
+
+
+4. Format configuration
+-----------------------
+
+Frame buffer devices offer two ways to configure the frame buffer format: the
+legacy API and the FOURCC-based API.
+
+
+The legacy API has been the only frame buffer format configuration API for a
+long time and is thus widely used by application. It is the recommended API
+for applications when using RGB and grayscale formats, as well as legacy
+non-standard formats.
+
+To select a format, applications set the fb_var_screeninfo bits_per_pixel field
+to the desired frame buffer depth. Values up to 8 will usually map to
+monochrome, grayscale or pseudocolor visuals, although this is not required.
+
+- For grayscale formats, applications set the grayscale field to a non-zero
+  value. The red, blue, green and transp fields must be set to 0 by
+  applications and ignored by drivers. Drivers must fill the red, blue and
+  green offsets to 0 and lengths to the bits_per_pixel value.
+
+- For pseudocolor formats, applications set the grayscale field to a zero
+  value. The red, blue, green and transp fields must be set to 0 by
+  applications and ignored by drivers. Drivers must fill the red, blue and
+  green offsets to 0 and lengths to the bits_per_pixel value.
+
+- For truecolor and directcolor formats, applications set the grayscale field
+  to a zero value, and the red, blue, green and transp fields to describe the
+  layout of color components in memory.
+
+struct fb_bitfield {
+	__u32 offset;			/* beginning of bitfield	*/
+	__u32 length;			/* length of bitfield		*/
+	__u32 msb_right;		/* != 0 : Most significant bit is */
+					/* right */
+};
+
+  Pixel values are bits_per_pixel wide and are split in non-overlapping red,
+  green, blue and alpha (transparency) components. Location and size of each
+  component in the pixel value are described by the fb_bitfield offset and
+  length fields. Offset are computed from the right.
+
+  Pixels are always stored in an integer number of bytes. If the number of
+  bits per pixel is not a multiple of 8, pixel values are padded to the next
+  multiple of 8 bits.
+
+Upon successful format configuration, drivers update the fb_fix_screeninfo
+type, visual and line_length fields depending on the selected format.
+
+
+The FOURCC-based API replaces format descriptions by four character codes
+(FOURCC). FOURCCs are abstract identifiers that uniquely define a format
+without explicitly describing it. This is the only API that supports YUV
+formats. Drivers are also encouraged to implement the FOURCC-based API for RGB
+and grayscale formats.
+
+Drivers that support the FOURCC-based API report this capability by setting
+the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities field.
+
+FOURCC definitions are located in the linux/videodev2.h header. However, and
+despite starting with the V4L2_PIX_FMT_prefix, they are not restricted to V4L2
+and don't require usage of the V4L2 subsystem. FOURCC documentation is
+available in Documentation/DocBook/v4l/pixfmt.xml.
+
+To select a format, applications set the FB_VMODE_FOURCC bit in the
+fb_var_screeninfo vmode field, and set the fourcc field to the desired FOURCC.
+The bits_per_pixel, red, green, blue, transp and nonstd fields must be set to
+0 by applications and ignored by drivers. Note that the grayscale and fourcc
+fields share the same memory location. Application must thus not set the
+grayscale field to 0.
+
+Upon successful format configuration, drivers update the fb_fix_screeninfo
+type, visual and line_length fields depending on the selected format. The
+visual field is set to FB_VISUAL_FOURCC.
+
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 6a82748..359e98e 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -69,6 +69,7 @@
 #define FB_VISUAL_PSEUDOCOLOR		3	/* Pseudo color (like atari) */
 #define FB_VISUAL_DIRECTCOLOR		4	/* Direct color */
 #define FB_VISUAL_STATIC_PSEUDOCOLOR	5	/* Pseudo color readonly */
+#define FB_VISUAL_FOURCC		6	/* Visual identified by a V4L2 FOURCC */
 
 #define FB_ACCEL_NONE		0	/* no hardware accelerator	*/
 #define FB_ACCEL_ATARIBLITT	1	/* Atari Blitter		*/
@@ -154,6 +155,8 @@
 
 #define FB_ACCEL_PUV3_UNIGFX	0xa0	/* PKUnity-v3 Unigfx		*/
 
+#define FB_CAP_FOURCC		1	/* Device supports FOURCC-based formats */
+
 struct fb_fix_screeninfo {
 	char id[16];			/* identification string eg "TT Builtin" */
 	unsigned long smem_start;	/* Start of frame buffer mem */
@@ -171,7 +174,8 @@ struct fb_fix_screeninfo {
 	__u32 mmio_len;			/* Length of Memory Mapped I/O  */
 	__u32 accel;			/* Indicate to driver which	*/
 					/*  specific chip/card we have	*/
-	__u16 reserved[3];		/* Reserved for future compatibility */
+	__u16 capabilities;		/* see FB_CAP_*			*/
+	__u16 reserved[2];		/* Reserved for future compatibility */
 };
 
 /* Interpretation of offset for color fields: All offsets are from the right,
@@ -220,6 +224,7 @@ struct fb_bitfield {
 #define FB_VMODE_INTERLACED	1	/* interlaced	*/
 #define FB_VMODE_DOUBLE		2	/* double scan */
 #define FB_VMODE_ODD_FLD_FIRST	4	/* interlaced: top line first */
+#define FB_VMODE_FOURCC		8	/* video mode expressed as a FOURCC */
 #define FB_VMODE_MASK		255
 
 #define FB_VMODE_YWRAP		256	/* ywrap instead of panning     */
@@ -246,7 +251,10 @@ struct fb_var_screeninfo {
 	__u32 yoffset;			/* resolution			*/
 
 	__u32 bits_per_pixel;		/* guess what			*/
-	__u32 grayscale;		/* != 0 Graylevels instead of colors */
+	union {
+		__u32 grayscale;	/* != 0 Graylevels instead of colors */
+		__u32 fourcc;		/* FOURCC format */
+	};
 
 	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
 	struct fb_bitfield green;	/* else only length is significant */
-- 
Regards,

Laurent Pinchart


^ permalink raw reply related

* Re: [PATCH/RFC] fbdev: Add FOURCC-based format configuration API
From: Geert Uytterhoeven @ 2011-06-21 20:49 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-fbdev, linux-media, dri-devel, FlorianSchandinat
In-Reply-To: <1308670579-15138-1-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Laurent,

On Tue, Jun 21, 2011 at 17:36, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> +The following types and visuals are supported.
> +
> +- FB_TYPE_PACKED_PIXELS
> +
> +- FB_TYPE_PLANES

You forgot FB_TYPE_INTERLEAVED_PLANES, FB_TYPE_TEXT, and
FB_TYPE_VGA_PLANES. Ah, that's the "feel free to extend the API doc"  :-)

> +The FOURCC-based API replaces format descriptions by four character codes
> +(FOURCC). FOURCCs are abstract identifiers that uniquely define a format
> +without explicitly describing it. This is the only API that supports YUV
> +formats. Drivers are also encouraged to implement the FOURCC-based API for RGB
> +and grayscale formats.
> +
> +Drivers that support the FOURCC-based API report this capability by setting
> +the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities field.
> +
> +FOURCC definitions are located in the linux/videodev2.h header. However, and
> +despite starting with the V4L2_PIX_FMT_prefix, they are not restricted to V4L2
> +and don't require usage of the V4L2 subsystem. FOURCC documentation is
> +available in Documentation/DocBook/v4l/pixfmt.xml.
> +
> +To select a format, applications set the FB_VMODE_FOURCC bit in the
> +fb_var_screeninfo vmode field, and set the fourcc field to the desired FOURCC.
> +The bits_per_pixel, red, green, blue, transp and nonstd fields must be set to
> +0 by applications and ignored by drivers. Note that the grayscale and fourcc
> +fields share the same memory location. Application must thus not set the
> +grayscale field to 0.

These are the only parts I don't like: (ab)using the vmode field (this
isn't really a
vmode flag), and the union of grayscale and fourcc (avoid unions where
possible).

What about storing the FOURCC value in nonstd instead?
As FOURCC values are always 4 ASCII characters (hence all 4 bytes must
be non-zero),
I don't think there are any conflicts with existing values of nonstd.
To make it even safer and easier to parse, you could set bit 31 of
nonstd as a FOURCC
indicator.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [PATCH] fsl-diu-fb: remove the ioctl interface
From: Timur Tabi @ 2011-06-21 21:27 UTC (permalink / raw)
  To: lethal, linux-fbdev, agust, yorksun, linuxppc-dev

The ioctl interface in the Freescale DIU framebuffer driver is just a
collection of miscellaneous functions which were only used in a one-time
demo application that was never distributed.  Plus, the ioctls were spread
across two types (both conflicting), and the demo app didn't even use all
of them.

Removing the ioctl interface also allows us to clean up the header file and
remove other unusued stuff.

Signed-off-by: Timur Tabi <timur@freescale.com>
---

There's a warning about dummy_ad_addr that will be fixed in a future patch.

 Documentation/ioctl/ioctl-number.txt |    2 -
 drivers/video/fsl-diu-fb.c           |  157 ++++++++++------------------------
 include/linux/fsl-diu-fb.h           |   94 --------------------
 3 files changed, 44 insertions(+), 209 deletions(-)

diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 3a46e36..6c83c07 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -108,7 +108,6 @@ Code  Seq#(hex)	Include File		Comments
 'E'	00-0F	xen/evtchn.h		conflict!
 'F'	all	linux/fb.h		conflict!
 'F'	01-02	drivers/scsi/pmcraid.h	conflict!
-'F'	20	drivers/video/fsl-diu-fb.h	conflict!
 'F'	20	drivers/video/intelfb/intelfb.h	conflict!
 'F'	20	linux/ivtvfb.h		conflict!
 'F'	20	linux/matroxfb.h	conflict!
@@ -147,7 +146,6 @@ Code  Seq#(hex)	Include File		Comments
 'M'	01-16	mtd/mtd-abi.h		conflict!
 		and drivers/mtd/mtdchar.c
 'M'	01-03	drivers/scsi/megaraid/megaraid_sas.h
-'M'	00-0F	drivers/video/fsl-diu-fb.h	conflict!
 'N'	00-1F	drivers/usb/scanner.h
 'O'     00-06   mtd/ubi-user.h		UBI
 'P'	all	linux/soundcard.h	conflict!
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index bedf5be..db2abaf 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -37,6 +37,50 @@
 #include <linux/fsl-diu-fb.h>
 #include "edid.h"
 
+/* Minimum value that the pixel clock can be set to in pico seconds
+ * This is determined by platform clock/3 where the minimum platform
+ * clock is 533MHz. This gives 5629 pico seconds.
+ */
+#define MIN_PIX_CLK	5629
+#define MAX_PIX_CLK	96096
+
+#define FSL_AOI_NUM	6	/* 5 AOIs and one dummy AOI */
+
+/* INT_STATUS/INT_MASK field descriptions */
+#define INT_VSYNC	0x01	/* Vsync interrupt  */
+#define INT_VSYNC_WB	0x02	/* Vsync interrupt for write back operation */
+#define INT_UNDRUN	0x04	/* Under run exception interrupt */
+#define INT_PARERR	0x08	/* Display parameters error interrupt */
+#define INT_LS_BF_VS	0x10	/* Lines before vsync. interrupt */
+
+/* Panels'operation modes */
+#define MFB_TYPE_OUTPUT	0	/* Panel output to display */
+#define MFB_TYPE_OFF	1	/* Panel off */
+#define MFB_TYPE_WB	2	/* Panel written back to memory */
+#define MFB_TYPE_TEST	3	/* Panel generate color bar */
+
+/* HW cursor parameters */
+#define MAX_CURS	32
+
+struct diu_hw {
+	struct diu *diu_reg;
+	spinlock_t reg_lock;
+	__u32 mode;		/* DIU operation mode */
+};
+
+struct diu_addr {
+	__u8 __iomem *vaddr;	/* Virtual address */
+	dma_addr_t paddr;	/* Physical address */
+	__u32 offset;
+};
+
+struct diu_pool {
+	struct diu_addr ad;
+	struct diu_addr gamma;
+	struct diu_addr pallete;
+	struct diu_addr cursor;
+};
+
 /*
  * These parameters give default parameters
  * for video output 1024x768,
@@ -991,118 +1035,6 @@ static int fsl_diu_blank(int blank_mode, struct fb_info *info)
 	return 0;
 }
 
-static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
-		       unsigned long arg)
-{
-	struct mfb_info *mfbi = info->par;
-	struct diu_ad *ad = mfbi->ad;
-	struct mfb_chroma_key ck;
-	unsigned char global_alpha;
-	struct aoi_display_offset aoi_d;
-	__u32 pix_fmt;
-	void __user *buf = (void __user *)arg;
-
-	if (!arg)
-		return -EINVAL;
-	switch (cmd) {
-	case MFB_SET_PIXFMT:
-		if (copy_from_user(&pix_fmt, buf, sizeof(pix_fmt)))
-			return -EFAULT;
-		ad->pix_fmt = pix_fmt;
-		pr_debug("Set pixel format to 0x%08x\n", ad->pix_fmt);
-		break;
-	case MFB_GET_PIXFMT:
-		pix_fmt = ad->pix_fmt;
-		if (copy_to_user(buf, &pix_fmt, sizeof(pix_fmt)))
-			return -EFAULT;
-		pr_debug("get pixel format 0x%08x\n", ad->pix_fmt);
-		break;
-	case MFB_SET_AOID:
-		if (copy_from_user(&aoi_d, buf, sizeof(aoi_d)))
-			return -EFAULT;
-		mfbi->x_aoi_d = aoi_d.x_aoi_d;
-		mfbi->y_aoi_d = aoi_d.y_aoi_d;
-		pr_debug("set AOI display offset of index %d to (%d,%d)\n",
-				 mfbi->index, aoi_d.x_aoi_d, aoi_d.y_aoi_d);
-		fsl_diu_check_var(&info->var, info);
-		fsl_diu_set_aoi(info);
-		break;
-	case MFB_GET_AOID:
-		aoi_d.x_aoi_d = mfbi->x_aoi_d;
-		aoi_d.y_aoi_d = mfbi->y_aoi_d;
-		if (copy_to_user(buf, &aoi_d, sizeof(aoi_d)))
-			return -EFAULT;
-		pr_debug("get AOI display offset of index %d (%d,%d)\n",
-				mfbi->index, aoi_d.x_aoi_d, aoi_d.y_aoi_d);
-		break;
-	case MFB_GET_ALPHA:
-		global_alpha = mfbi->g_alpha;
-		if (copy_to_user(buf, &global_alpha, sizeof(global_alpha)))
-			return -EFAULT;
-		pr_debug("get global alpha of index %d\n", mfbi->index);
-		break;
-	case MFB_SET_ALPHA:
-		/* set panel information */
-		if (copy_from_user(&global_alpha, buf, sizeof(global_alpha)))
-			return -EFAULT;
-		ad->src_size_g_alpha = (ad->src_size_g_alpha & (~0xff)) |
-							(global_alpha & 0xff);
-		mfbi->g_alpha = global_alpha;
-		pr_debug("set global alpha for index %d\n", mfbi->index);
-		break;
-	case MFB_SET_CHROMA_KEY:
-		/* set panel winformation */
-		if (copy_from_user(&ck, buf, sizeof(ck)))
-			return -EFAULT;
-
-		if (ck.enable &&
-		   (ck.red_max < ck.red_min ||
-		    ck.green_max < ck.green_min ||
-		    ck.blue_max < ck.blue_min))
-			return -EINVAL;
-
-		if (!ck.enable) {
-			ad->ckmax_r = 0;
-			ad->ckmax_g = 0;
-			ad->ckmax_b = 0;
-			ad->ckmin_r = 255;
-			ad->ckmin_g = 255;
-			ad->ckmin_b = 255;
-		} else {
-			ad->ckmax_r = ck.red_max;
-			ad->ckmax_g = ck.green_max;
-			ad->ckmax_b = ck.blue_max;
-			ad->ckmin_r = ck.red_min;
-			ad->ckmin_g = ck.green_min;
-			ad->ckmin_b = ck.blue_min;
-		}
-		pr_debug("set chroma key\n");
-		break;
-	case FBIOGET_GWINFO:
-		if (mfbi->type = MFB_TYPE_OFF)
-			return -ENODEV;
-		/* get graphic window information */
-		if (copy_to_user(buf, ad, sizeof(*ad)))
-			return -EFAULT;
-		break;
-	case FBIOGET_HWCINFO:
-		pr_debug("FBIOGET_HWCINFO:0x%08x\n", FBIOGET_HWCINFO);
-		break;
-	case FBIOPUT_MODEINFO:
-		pr_debug("FBIOPUT_MODEINFO:0x%08x\n", FBIOPUT_MODEINFO);
-		break;
-	case FBIOGET_DISPINFO:
-		pr_debug("FBIOGET_DISPINFO:0x%08x\n", FBIOGET_DISPINFO);
-		break;
-
-	default:
-		printk(KERN_ERR "Unknown ioctl command (0x%08X)\n", cmd);
-		return -ENOIOCTLCMD;
-	}
-
-	return 0;
-}
-
 /* turn on fb if count = 1
  */
 static int fsl_diu_open(struct fb_info *info, int user)
@@ -1162,7 +1094,6 @@ static struct fb_ops fsl_diu_ops = {
 	.fb_fillrect = cfb_fillrect,
 	.fb_copyarea = cfb_copyarea,
 	.fb_imageblit = cfb_imageblit,
-	.fb_ioctl = fsl_diu_ioctl,
 	.fb_open = fsl_diu_open,
 	.fb_release = fsl_diu_release,
 };
diff --git a/include/linux/fsl-diu-fb.h b/include/linux/fsl-diu-fb.h
index 781d467..234c38e 100644
--- a/include/linux/fsl-diu-fb.h
+++ b/include/linux/fsl-diu-fb.h
@@ -20,55 +20,8 @@
 #ifndef __FSL_DIU_FB_H__
 #define __FSL_DIU_FB_H__
 
-/* Arbitrary threshold to determine the allocation method
- * See mpc8610fb_set_par(), map_video_memory(), and unmap_video_memory()
- */
-#define MEM_ALLOC_THRESHOLD (1024*768*4+32)
-/* Minimum value that the pixel clock can be set to in pico seconds
- * This is determined by platform clock/3 where the minimum platform
- * clock is 533MHz. This gives 5629 pico seconds.
- */
-#define MIN_PIX_CLK 5629
-#define MAX_PIX_CLK 96096
-
 #include <linux/types.h>
 
-struct mfb_alpha {
-	int enable;
-	int alpha;
-};
-
-struct mfb_chroma_key {
-	int enable;
-	__u8  red_max;
-	__u8  green_max;
-	__u8  blue_max;
-	__u8  red_min;
-	__u8  green_min;
-	__u8  blue_min;
-};
-
-struct aoi_display_offset {
-	int x_aoi_d;
-	int y_aoi_d;
-};
-
-#define MFB_SET_CHROMA_KEY	_IOW('M', 1, struct mfb_chroma_key)
-#define MFB_SET_BRIGHTNESS	_IOW('M', 3, __u8)
-
-#define MFB_SET_ALPHA		0x80014d00
-#define MFB_GET_ALPHA		0x40014d00
-#define MFB_SET_AOID		0x80084d04
-#define MFB_GET_AOID		0x40084d04
-#define MFB_SET_PIXFMT		0x80014d08
-#define MFB_GET_PIXFMT		0x40014d08
-
-#define FBIOGET_GWINFO		0x46E0
-#define FBIOPUT_GWINFO		0x46E1
-
-#ifdef __KERNEL__
-#include <linux/spinlock.h>
-
 /*
  * These are the fields of area descriptor(in DDR memory) for every plane
  */
@@ -165,39 +118,6 @@ struct diu {
 	__be32 plut;
 } __attribute__ ((packed));
 
-struct diu_hw {
-	struct diu *diu_reg;
-	spinlock_t reg_lock;
-
-	__u32 mode;		/* DIU operation mode */
-};
-
-struct diu_addr {
-	__u8 __iomem *vaddr;	/* Virtual address */
-	dma_addr_t paddr;	/* Physical address */
-	__u32 	   offset;
-};
-
-struct diu_pool {
-	struct diu_addr ad;
-	struct diu_addr gamma;
-	struct diu_addr pallete;
-	struct diu_addr cursor;
-};
-
-#define FSL_DIU_BASE_OFFSET	0x2C000	/* Offset of DIU */
-#define INT_LCDC		64	/* DIU interrupt number */
-
-#define FSL_AOI_NUM	6	/* 5 AOIs and one dummy AOI */
-				/* 1 for plane 0, 2 for plane 1&2 each */
-
-/* Minimum X and Y resolutions */
-#define MIN_XRES	64
-#define MIN_YRES	64
-
-/* HW cursor parameters */
-#define MAX_CURS		32
-
 /* Modes of operation of DIU */
 #define MFB_MODE0	0	/* DIU off */
 #define MFB_MODE1	1	/* All three planes output to display */
@@ -205,18 +125,4 @@ struct diu_pool {
 #define MFB_MODE3	3	/* All three planes written back to memory */
 #define MFB_MODE4	4	/* Color bar generation */
 
-/* INT_STATUS/INT_MASK field descriptions */
-#define INT_VSYNC	0x01	/* Vsync interrupt  */
-#define INT_VSYNC_WB	0x02	/* Vsync interrupt for write back operation */
-#define INT_UNDRUN	0x04	/* Under run exception interrupt */
-#define INT_PARERR	0x08	/* Display parameters error interrupt */
-#define INT_LS_BF_VS	0x10	/* Lines before vsync. interrupt */
-
-/* Panels'operation modes */
-#define MFB_TYPE_OUTPUT	0	/* Panel output to display */
-#define MFB_TYPE_OFF	1	/* Panel off */
-#define MFB_TYPE_WB	2	/* Panel written back to memory */
-#define MFB_TYPE_TEST	3	/* Panel generate color bar */
-
-#endif /* __KERNEL__ */
 #endif /* __FSL_DIU_FB_H__ */
-- 
1.7.3.4



^ permalink raw reply related

* Re: [PATCH/RFC] fbdev: Add FOURCC-based format configuration API
From: Laurent Pinchart @ 2011-06-21 22:31 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-fbdev, linux-media, dri-devel, FlorianSchandinat
In-Reply-To: <BANLkTim6wUaeZCya=9dMvU7iHj4W4E57Fg@mail.gmail.com>

Hi Geert,

On Tuesday 21 June 2011 22:49:14 Geert Uytterhoeven wrote:
> On Tue, Jun 21, 2011 at 17:36, Laurent Pinchart wrote:
> > +The following types and visuals are supported.
> > +
> > +- FB_TYPE_PACKED_PIXELS
> > +
> > +- FB_TYPE_PLANES
> 
> You forgot FB_TYPE_INTERLEAVED_PLANES, FB_TYPE_TEXT, and
> FB_TYPE_VGA_PLANES. Ah, that's the "feel free to extend the API doc"  :-)

To be honest, I don't know how they work. That's why I haven't documented 
them.

> > +The FOURCC-based API replaces format descriptions by four character
> > codes +(FOURCC). FOURCCs are abstract identifiers that uniquely define a
> > format +without explicitly describing it. This is the only API that
> > supports YUV +formats. Drivers are also encouraged to implement the
> > FOURCC-based API for RGB +and grayscale formats.
> > +
> > +Drivers that support the FOURCC-based API report this capability by
> > setting +the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities
> > field. +
> > +FOURCC definitions are located in the linux/videodev2.h header. However,
> > and +despite starting with the V4L2_PIX_FMT_prefix, they are not
> > restricted to V4L2 +and don't require usage of the V4L2 subsystem.
> > FOURCC documentation is +available in
> > Documentation/DocBook/v4l/pixfmt.xml.
> > +
> > +To select a format, applications set the FB_VMODE_FOURCC bit in the
> > +fb_var_screeninfo vmode field, and set the fourcc field to the desired
> > FOURCC. +The bits_per_pixel, red, green, blue, transp and nonstd fields
> > must be set to +0 by applications and ignored by drivers. Note that the
> > grayscale and fourcc +fields share the same memory location. Application
> > must thus not set the +grayscale field to 0.
> 
> These are the only parts I don't like: (ab)using the vmode field (this
> isn't really a vmode flag), and the union of grayscale and fourcc (avoid
> unions where possible).

I've proposed adding a FB_NONSTD_FORMAT bit to the nonstd field as a FOURCC 
mode indicator in my initial RFC. Florian Tobias Schandinat wasn't very happy 
with that, and proposed using the vmode field instead.

Given that there's virtually no fbdev documentation, whether the vmode field 
and/or nonstd field are good fit for a FOURCC mode indicator is subject to 
interpretation.

> What about storing the FOURCC value in nonstd instead?

Wouldn't that be a union of nonstd and fourcc ? :-) FOURCC-based format 
setting will be a standard fbdev API, I'm not very keen on storing it in the 
nonstd field without a union.

> As FOURCC values are always 4 ASCII characters (hence all 4 bytes must
> be non-zero), I don't think there are any conflicts with existing values of
> nonstd. To make it even safer and easier to parse, you could set bit 31 of
> nonstd as a FOURCC indicator.

I would then create a union between nonstd and fourcc, and document nonstd as 
being used for the legacy API only. Most existing drivers use a couple of 
nonstd bits only. The driver that (ab)uses nonstd the most is pxafb and uses 
bits 22:0. Bits 31:24 are never used as far as I can tell, so nonstd & 
0xff000000 != 0 could be used as a FOURCC mode test.

This assumes that FOURCCs will never have their last character set to '\0'. Is 
that a safe assumption for the future ?

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH] fsl-diu-fb: remove the ioctl interface
From: Anatolij Gustschin @ 2011-06-21 22:38 UTC (permalink / raw)
  To: Timur Tabi; +Cc: linuxppc-dev, linux-fbdev, lethal, yorksun
In-Reply-To: <1308691655-3416-1-git-send-email-timur@freescale.com>

On Tue, 21 Jun 2011 16:27:35 -0500
Timur Tabi <timur@freescale.com> wrote:

> The ioctl interface in the Freescale DIU framebuffer driver is just a
> collection of miscellaneous functions which were only used in a one-time
> demo application that was never distributed.  Plus, the ioctls were spread
> across two types (both conflicting), and the demo app didn't even use all
> of them.
> 
> Removing the ioctl interface also allows us to clean up the header file and
> remove other unusued stuff.

No! We are using ioctl interface of this driver in many video
rendering applications on overlay planes on huge number of boards.
So, please don't remove it.

Anatolij

^ permalink raw reply

* Re: [PATCH] fsl-diu-fb: remove the ioctl interface
From: Tabi Timur-B04825 @ 2011-06-21 23:13 UTC (permalink / raw)
  To: Anatolij Gustschin
  Cc: sun york-R58495, linux-fbdev@vger.kernel.org, lethal@linux-sh.org,
	Tabi Timur-B04825, linuxppc-dev@ozlabs.org
In-Reply-To: <20110622003853.1041385c@wker>

Anatolij Gustschin wrote:
> No! We are using ioctl interface of this driver in many video
> rendering applications on overlay planes on huge number of boards.
> So, please don't remove it.

Ok, I had no idea anyone was using it.

Can you email me details about how you use the ioctl interface?  If I can't 
remove it, maybe I can clean it up.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* [PATCH V4 0/5] ARM: EXYNOS4: Add support EXYNOS4 FIMD
From: JinGoo Han @ 2011-06-22  3:19 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
	linux-fbdev, Jong-Hun
  Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
	Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
	JinGoo Han

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 1242 bytes --]

This patch series is based on the latest
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

This was originally submitted by Jonghun Han <jonghun.han@samsung.com>
http://www.spinics.net/lists/arm-kernel/msg101781.html

This patch adds support FIMD(Fully Interactive Mobile Display) on Exynos4.
The 4th patch is update for s3c-fb and others are for platform data.

v2: change clock name of exynos4 FIMD: "fimd" -> "lcd"
     use 'has_clksel' variable in order to distinguish FIMD version
     add 'lcd_clk' that can be used for only lcd pixel clock
     add callback 'enable_clk()' to enable parent clock 'sclk_fimd'.
v3: remove the callback from the platform data structure
v4: move clk_enable(sfb->lcd_clk) under the if statement

o To Kukjin Kim
[PATCH V4 1/5] ARM: EXYNOS4: Change clock name for FIMD
[PATCH V4 2/5] ARM: EXYNOS4: Add FIMD resource definition
[PATCH V4 3/5] ARM: EXYNOS4: Add platform device and helper functions for FIMD
[PATCH V4 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD and LTE480WV platform-lcd

o To Paul Mundt
[PATCH V4 4/5] video: s3c-fb: Add support EXYNOS4 FIMDÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±ýöÝzÿâžØ^n‡r¡ö¦zË\x1aëh™¨è­Ú&£ûàz¿äz¹Þ—ú+€Ê+zf£¢·hšˆ§~†­†Ûiÿÿïêÿ‘êçz_è®\x0fæj:+v‰¨þ)ߣøm

^ permalink raw reply

* [PATCH V4 1/5] ARM: EXYNOS4: Change clock name for FIMD
From: JinGoo Han @ 2011-06-22  3:42 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
	"linux-fbdev@vger.kernel.org" <linux-f>
  Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
	Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
	JinGoo Han

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1252", Size: 924 bytes --]

This patch changes clock name for FIMD from "fimd" to "lcd".

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/clock.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 871f9d5..12e6853 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -433,12 +433,12 @@ static struct clk init_clocks_off[] = {
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 3),
 	}, {
-		.name		= "fimd",
+		.name		= "lcd",
 		.id		= 0,
 		.enable		= exynos4_clk_ip_lcd0_ctrl,
 		.ctrlbit	= (1 << 0),
 	}, {
-		.name		= "fimd",
+		.name		= "lcd",
 		.id		= 1,
 		.enable		= exynos4_clk_ip_lcd1_ctrl,
 		.ctrlbit	= (1 << 0),
-- 
1.7.1

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±ýöÝzÿâžØ^n‡r¡ö¦zË\x1aëh™¨è­Ú&£ûàz¿äz¹Þ—ú+€Ê+zf£¢·hšˆ§~†­†Ûiÿÿïêÿ‘êçz_è®\x0fæj:+v‰¨þ)ߣøm

^ permalink raw reply related

* [PATCH V4 2/5] ARM: EXYNOS4: Add FIMD resource definition
From: JinGoo Han @ 2011-06-22  3:44 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
	"linux-fbdev@vger.kernel.org" <linux-f>
  Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
	Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
	JinGoo Han

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 2133 bytes --]

From: Jonghun Han <jonghun.han@samsung.com>

This patch adds resource definitions for EXYNOS4 FIMD.
IRQ and SFR definitions are added.

Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/include/mach/irqs.h |    8 ++++++++
 arch/arm/mach-exynos4/include/mach/map.h  |    5 +++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h
index 5d03730..2cd2090 100644
--- a/arch/arm/mach-exynos4/include/mach/irqs.h
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -73,6 +73,14 @@
 #define IRQ_SYSMMU_MFC_M1_0	COMBINER_IRQ(5, 6)
 #define IRQ_SYSMMU_PCIE_0	COMBINER_IRQ(5, 7)
 
+#define IRQ_FIMD0_FIFO		COMBINER_IRQ(11, 0)
+#define IRQ_FIMD0_VSYNC		COMBINER_IRQ(11, 1)
+#define IRQ_FIMD0_SYSTEM	COMBINER_IRQ(11, 2)
+
+#define IRQ_FIMD1_FIFO		COMBINER_IRQ(12, 0)
+#define IRQ_FIMD1_VSYNC		COMBINER_IRQ(12, 1)
+#define IRQ_FIMD1_SYSTEM	COMBINER_IRQ(12, 2)
+
 #define IRQ_PDMA0		COMBINER_IRQ(21, 0)
 #define IRQ_PDMA1		COMBINER_IRQ(21, 1)
 
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
index 0009e77..94006f7 100644
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -93,6 +93,9 @@
 #define EXYNOS4_PA_MIPI_CSIS0		0x11880000
 #define EXYNOS4_PA_MIPI_CSIS1		0x11890000
 
+#define EXYNOS4_PA_FIMD0		0x11C00000
+#define EXYNOS4_PA_FIMD1		0x12000000
+
 #define EXYNOS4_PA_HSMMC(x)		(0x12510000 + ((x) * 0x10000))
 
 #define EXYNOS4_PA_SATA			0x12560000
@@ -140,6 +143,8 @@
 #define S5P_PA_FIMC3			EXYNOS4_PA_FIMC3
 #define S5P_PA_MIPI_CSIS0		EXYNOS4_PA_MIPI_CSIS0
 #define S5P_PA_MIPI_CSIS1		EXYNOS4_PA_MIPI_CSIS1
+#define S5P_PA_FIMD0			EXYNOS4_PA_FIMD0
+#define S5P_PA_FIMD1			EXYNOS4_PA_FIMD1
 #define S5P_PA_ONENAND			EXYNOS4_PA_ONENAND
 #define S5P_PA_ONENAND_DMA		EXYNOS4_PA_ONENAND_DMA
 #define S5P_PA_SDRAM			EXYNOS4_PA_SDRAM
-- 
1.7.1

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±ýöÝzÿâžØ^n‡r¡ö¦zË\x1aëh™¨è­Ú&£ûàz¿äz¹Þ—ú+€Ê+zf£¢·hšˆ§~†­†Ûiÿÿïêÿ‘êçz_è®\x0fæj:+v‰¨þ)ߣøm

^ permalink raw reply related

* [PATCH V4 3/5] ARM: EXYNOS4: Add platform device and helper functions
From: JinGoo Han @ 2011-06-22  3:46 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
	"linux-fbdev@vger.kernel.org" <linux-f>
  Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
	Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
	JinGoo Han

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 11522 bytes --]

From: Jonghun Han <jonghun.han@samsung.com>

This patch adds platform device s5p_device_fimd0 for EXYNOS4 FIMD0.
EXYNOS4 has two FIMDs(FIMD0, FIMD1). FIMD1 will be added later.
Some definitions used to enable EXYNOS4 FIMD0 are added.

Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/Kconfig                |    9 ++++
 arch/arm/mach-exynos4/Makefile               |    1 +
 arch/arm/mach-exynos4/cpu.c                  |    4 +-
 arch/arm/mach-exynos4/include/mach/regs-fb.h |   21 ++++++++
 arch/arm/mach-exynos4/setup-fimd0-24bpp.c    |   47 ++++++++++++++++++
 arch/arm/plat-s5p/Kconfig                    |    5 ++
 arch/arm/plat-s5p/Makefile                   |    1 +
 arch/arm/plat-s5p/dev-fimd0.c                |   67 ++++++++++++++++++++++++++
 arch/arm/plat-samsung/include/plat/devs.h    |    1 +
 arch/arm/plat-samsung/include/plat/fb-core.h |   15 ++++++
 arch/arm/plat-samsung/include/plat/fb.h      |   15 ++++++
 11 files changed, 185 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-exynos4/include/mach/regs-fb.h
 create mode 100644 arch/arm/mach-exynos4/setup-fimd0-24bpp.c
 create mode 100644 arch/arm/plat-s5p/dev-fimd0.c

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 1435fc3..8428ac7 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -25,6 +25,11 @@ config EXYNOS4_DEV_AHCI
 	help
 	  Compile in platform device definitions for AHCI
 
+config EXYNOS4_SETUP_FIMD0_24BPP
+	bool
+	help
+	  Common setup code for FIMD0 with a 24bpp RGB display helper.
+
 config EXYNOS4_DEV_PD
 	bool
 	help
@@ -103,6 +108,7 @@ menu "EXYNOS4 Machines"
 config MACH_SMDKC210
 	bool "SMDKC210"
 	select CPU_EXYNOS4210
+	select S5P_DEV_FIMD0
 	select S3C_DEV_RTC
 	select S3C_DEV_WDT
 	select S3C_DEV_I2C1
@@ -112,6 +118,7 @@ config MACH_SMDKC210
 	select S3C_DEV_HSMMC3
 	select EXYNOS4_DEV_PD
 	select EXYNOS4_DEV_SYSMMU
+	select EXYNOS4_SETUP_FIMD0_24BPP
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_SDHCI
 	help
@@ -120,6 +127,7 @@ config MACH_SMDKC210
 config MACH_SMDKV310
 	bool "SMDKV310"
 	select CPU_EXYNOS4210
+	select S5P_DEV_FIMD0
 	select S3C_DEV_RTC
 	select S3C_DEV_WDT
 	select S3C_DEV_I2C1
@@ -130,6 +138,7 @@ config MACH_SMDKV310
 	select SAMSUNG_DEV_KEYPAD
 	select EXYNOS4_DEV_PD
 	select EXYNOS4_DEV_SYSMMU
+	select EXYNOS4_SETUP_FIMD0_24BPP
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_KEYPAD
 	select EXYNOS4_SETUP_SDHCI
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 60fe5ec..aa4d1f4 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_EXYNOS4_DEV_PD)		+= dev-pd.o
 obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)	+= dev-sysmmu.o
 
 obj-$(CONFIG_EXYNOS4_SETUP_FIMC)	+= setup-fimc.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMD0_24BPP)	+= setup-fimd0-24bpp.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C1)	+= setup-i2c1.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C2)	+= setup-i2c2.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C3)	+= setup-i2c3.o
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index 9babe44..778a5b0 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -19,9 +19,10 @@
 
 #include <plat/cpu.h>
 #include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/fb-core.h>
 #include <plat/exynos4.h>
 #include <plat/sdhci.h>
-#include <plat/devs.h>
 #include <plat/fimc-core.h>
 
 #include <mach/regs-irq.h>
@@ -132,6 +133,7 @@ void __init exynos4_map_io(void)
 	s3c_fimc_setname(1, "exynos4-fimc");
 	s3c_fimc_setname(2, "exynos4-fimc");
 	s3c_fimc_setname(3, "exynos4-fimc");
+	s5p_fb_setname(0, "exynos4-fb");	/* FIMD0 */
 }
 
 void __init exynos4_init_clocks(int xtal)
diff --git a/arch/arm/mach-exynos4/include/mach/regs-fb.h b/arch/arm/mach-exynos4/include/mach/regs-fb.h
new file mode 100644
index 0000000..f320105
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-fb.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Dummy framebuffer to allow build for the moment.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MACH_REGS_FB_H
+#define __ASM_ARCH_MACH_REGS_FB_H __FILE__
+
+#include <plat/regs-fb-v4.h>
+
+static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
+{
+	return 0x2400 + (window * 256 * 4) + reg;
+}
+
+#endif /* __ASM_ARCH_MACH_REGS_FB_H */
diff --git a/arch/arm/mach-exynos4/setup-fimd0-24bpp.c b/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
new file mode 100644
index 0000000..3ca8555
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
@@ -0,0 +1,47 @@
+/* linux/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Base Exynos4 setup information for 24bpp LCD framebuffer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+void exynos4_fimd0_gpio_setup_24bpp(void)
+{
+	unsigned int reg = 0;
+
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2));
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2));
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2));
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2));
+
+	/*
+	 * Set DISPLAY_CONTROL register for Display path selection.
+	 *
+	 * DISPLAY_CONTROL[1:0]
+	 * ---------------------
+	 *  00 | MIE
+	 *  01 | MDINE
+	 *  10 | FIMD : selected
+	 *  11 | FIMD
+	 */
+	reg = __raw_readl(S3C_VA_SYS + 0x0210);
+	reg |= (1 << 1);
+	__raw_writel(reg, S3C_VA_SYS + 0x0210);
+}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index e98f5c5..46de16e 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -70,6 +70,11 @@ config S5P_DEV_FIMC3
 	help
 	  Compile in platform device definitions for FIMC controller 3
 
+config S5P_DEV_FIMD0
+	bool
+	help
+	  Compile in platform device definitions for FIMD controller 0
+
 config S5P_DEV_ONENAND
 	bool
 	help
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index e234cc4..eec7e24 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_S5P_DEV_FIMC0)	+= dev-fimc0.o
 obj-$(CONFIG_S5P_DEV_FIMC1)	+= dev-fimc1.o
 obj-$(CONFIG_S5P_DEV_FIMC2)	+= dev-fimc2.o
 obj-$(CONFIG_S5P_DEV_FIMC3)	+= dev-fimc3.o
+obj-$(CONFIG_S5P_DEV_FIMD0)	+= dev-fimd0.o
 obj-$(CONFIG_S5P_DEV_ONENAND)	+= dev-onenand.o
 obj-$(CONFIG_S5P_DEV_CSIS0)	+= dev-csis0.o
 obj-$(CONFIG_S5P_DEV_CSIS1)	+= dev-csis1.o
diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c
new file mode 100644
index 0000000..9e7176c
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimd0.c
@@ -0,0 +1,67 @@
+/* linux/arch/arm/plat-s5p/dev-fimd0.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Core file for Samsung Display Controller (FIMD) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/fb.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s5p_fimd0_resource[] = {
+	[0] = {
+		.start  = S5P_PA_FIMD0,
+		.end    = S5P_PA_FIMD0 + SZ_32K - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = IRQ_FIMD0_VSYNC,
+		.end    = IRQ_FIMD0_VSYNC,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start  = IRQ_FIMD0_FIFO,
+		.end    = IRQ_FIMD0_FIFO,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start  = IRQ_FIMD0_SYSTEM,
+		.end    = IRQ_FIMD0_SYSTEM,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static u64 fimd0_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimd0 = {
+	.name           = "s5p-fb",
+	.id             = 0,
+	.num_resources  = ARRAY_SIZE(s5p_fimd0_resource),
+	.resource       = s5p_fimd0_resource,
+	.dev            = {
+		.dma_mask               = &fimd0_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
+	},
+};
+
+void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
+{
+	s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+			&s5p_device_fimd0);
+}
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 4af108f..370bd2b 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -45,6 +45,7 @@ extern struct platform_device s3c64xx_device_ac97;
 extern struct platform_device s3c_device_ts;
 
 extern struct platform_device s3c_device_fb;
+extern struct platform_device s5p_device_fimd0;
 extern struct platform_device s3c_device_ohci;
 extern struct platform_device s3c_device_lcd;
 extern struct platform_device s3c_device_wdt;
diff --git a/arch/arm/plat-samsung/include/plat/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h
index bca383e..6abcbf1 100644
--- a/arch/arm/plat-samsung/include/plat/fb-core.h
+++ b/arch/arm/plat-samsung/include/plat/fb-core.h
@@ -26,4 +26,19 @@ static inline void s3c_fb_setname(char *name)
 #endif
 }
 
+/* Re-define device name depending on support. */
+static inline void s5p_fb_setname(int id, char *name)
+{
+	switch (id) {
+#ifdef CONFIG_S5P_DEV_FIMD0
+	case 0:
+		s5p_device_fimd0.name = name;
+	break;
+#endif
+	default:
+		printk(KERN_ERR "%s: invalid device id(%d)\n", __func__, id);
+	break;
+	}
+}
+
 #endif /* __ASM_PLAT_FB_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index cb3ca3a..01f10e4 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -74,6 +74,14 @@ struct s3c_fb_platdata {
 extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
 
 /**
+ * s5p_fimd0_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ *      so the machine data can mark the data __initdata so that any unused
+ *      machines will end up dumping their data at runtime.
+ */
+extern void s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
  * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
  *
  * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
@@ -94,4 +102,11 @@ extern void s5pc100_fb_gpio_setup_24bpp(void);
  */
 extern void s5pv210_fb_gpio_setup_24bpp(void);
 
+/**
+ * exynos4_fimd0_gpio_setup_24bpp() - Exynos4 setup function for 24bpp LCD0
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface 0.
+ */
+extern void exynos4_fimd0_gpio_setup_24bpp(void);
+
 #endif /* __PLAT_S3C_FB_H */
-- 
1.7.1

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±ýöÝzÿâžØ^n‡r¡ö¦zË\x1aëh™¨è­Ú&£ûàz¿äz¹Þ—ú+€Ê+zf£¢·hšˆ§~†­†Ûiÿÿïêÿ‘êçz_è®\x0fæj:+v‰¨þ)ߣøm

^ permalink raw reply related

* [PATCH V4 4/5] video: s3c-fb: Add support EXYNOS4 FIMD
From: JinGoo Han @ 2011-06-22  3:47 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
	"linux-fbdev@vger.kernel.org" <linux-f>
  Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
	Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
	JinGoo Han

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 6997 bytes --]

This patch adds struct s3c_fb_driverdata s3c_fb_data_exynos4 for EXYNOS4
and adds lcd clock gating support.

FIMD driver needs two clocks for FIMD IP and LCD pixel clock. Previously,
both clocks are provided by using bus clock such as HCLK. However, EXYNOS4
can not select HCLK for LCD pixel clock because the EXYNOS4 FIMD IP does not
have the CLKSEL bit of VIDCON0. So, FIMD driver should provide the lcd clock
using SCLK_FIMD as LCD pixel clock for EXYNOS4.

The driver selects enabling lcd clock according to has_clksel which means
the CLKSEL bit of VIDCON0. If there is has_clksel, the driver will not
enable the lcd clock using SCLK_FIMD because bus clock using HCLK is used
a LCD pixel clock.

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 drivers/video/Kconfig  |    2 +-
 drivers/video/s3c-fb.c |   82 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 549b960..963b8b7 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2027,7 +2027,7 @@ config FB_TMIO_ACCELL
 
 config FB_S3C
 	tristate "Samsung S3C framebuffer support"
-	depends on FB && S3C_DEV_FB
+	depends on FB && (S3C_DEV_FB || S5P_DEV_FIMD0)
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 4aecf21..d480452 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -81,6 +81,7 @@ struct s3c_fb;
  * @palette: Address of palette memory, or 0 if none.
  * @has_prtcon: Set if has PRTCON register.
  * @has_shadowcon: Set if has SHADOWCON register.
+ * @has_clksel: Set if VIDCON0 register has CLKSEL bit.
  */
 struct s3c_fb_variant {
 	unsigned int	is_2443:1;
@@ -98,6 +99,7 @@ struct s3c_fb_variant {
 
 	unsigned int	has_prtcon:1;
 	unsigned int	has_shadowcon:1;
+	unsigned int	has_clksel:1;
 };
 
 /**
@@ -186,6 +188,7 @@ struct s3c_fb_vsync {
  * @dev: The device that we bound to, for printing, etc.
  * @regs_res: The resource we claimed for the IO registers.
  * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
+ * @lcd_clk: The clk (sclk) feeding pixclk.
  * @regs: The mapped hardware registers.
  * @variant: Variant information for this hardware.
  * @enabled: A bitmask of enabled hardware windows.
@@ -200,6 +203,7 @@ struct s3c_fb {
 	struct device		*dev;
 	struct resource		*regs_res;
 	struct clk		*bus_clk;
+	struct clk		*lcd_clk;
 	void __iomem		*regs;
 	struct s3c_fb_variant	 variant;
 
@@ -336,10 +340,15 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
  */
 static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
 {
-	unsigned long clk = clk_get_rate(sfb->bus_clk);
+	unsigned long clk;
 	unsigned long long tmp;
 	unsigned int result;
 
+	if (sfb->variant.has_clksel)
+		clk = clk_get_rate(sfb->bus_clk);
+	else
+		clk = clk_get_rate(sfb->lcd_clk);
+
 	tmp = (unsigned long long)clk;
 	tmp *= pixclk;
 
@@ -1354,13 +1363,24 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
 
 	clk_enable(sfb->bus_clk);
 
+	if (!sfb->variant.has_clksel) {
+		sfb->lcd_clk = clk_get(dev, "sclk_fimd");
+		if (IS_ERR(sfb->lcd_clk)) {
+			dev_err(dev, "failed to get lcd clock\n");
+			ret = PTR_ERR(sfb->lcd_clk);
+			goto err_bus_clk;
+		}
+
+		clk_enable(sfb->lcd_clk);
+	}
+
 	pm_runtime_enable(sfb->dev);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(dev, "failed to find registers\n");
 		ret = -ENOENT;
-		goto err_clk;
+		goto err_lcd_clk;
 	}
 
 	sfb->regs_res = request_mem_region(res->start, resource_size(res),
@@ -1368,7 +1388,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
 	if (!sfb->regs_res) {
 		dev_err(dev, "failed to claim register region\n");
 		ret = -ENOENT;
-		goto err_clk;
+		goto err_lcd_clk;
 	}
 
 	sfb->regs = ioremap(res->start, resource_size(res));
@@ -1450,7 +1470,13 @@ err_ioremap:
 err_req_region:
 	release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
 
-err_clk:
+err_lcd_clk:
+	if (!sfb->variant.has_clksel) {
+		clk_disable(sfb->lcd_clk);
+		clk_put(sfb->lcd_clk);
+	}
+
+err_bus_clk:
 	clk_disable(sfb->bus_clk);
 	clk_put(sfb->bus_clk);
 
@@ -1481,6 +1507,11 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
 
 	iounmap(sfb->regs);
 
+	if (!sfb->variant.has_clksel) {
+		clk_disable(sfb->lcd_clk);
+		clk_put(sfb->lcd_clk);
+	}
+
 	clk_disable(sfb->bus_clk);
 	clk_put(sfb->bus_clk);
 
@@ -1510,6 +1541,9 @@ static int s3c_fb_suspend(struct device *dev)
 		s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
 	}
 
+	if (!sfb->variant.has_clksel)
+		clk_disable(sfb->lcd_clk);
+
 	clk_disable(sfb->bus_clk);
 	return 0;
 }
@@ -1524,6 +1558,9 @@ static int s3c_fb_resume(struct device *dev)
 
 	clk_enable(sfb->bus_clk);
 
+	if (!sfb->variant.has_clksel)
+		clk_enable(sfb->lcd_clk);
+
 	/* setup gpio and output polarity controls */
 	pd->setup_gpio();
 	writel(pd->vidcon1, sfb->regs + VIDCON1);
@@ -1755,6 +1792,7 @@ static struct s3c_fb_driverdata s3c_fb_data_64xx = {
 		},
 
 		.has_prtcon	= 1,
+		.has_clksel	= 1,
 	},
 	.win[0]	= &s3c_fb_data_64xx_wins[0],
 	.win[1]	= &s3c_fb_data_64xx_wins[1],
@@ -1785,6 +1823,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = {
 		},
 
 		.has_prtcon	= 1,
+		.has_clksel	= 1,
 	},
 	.win[0]	= &s3c_fb_data_s5p_wins[0],
 	.win[1]	= &s3c_fb_data_s5p_wins[1],
@@ -1815,6 +1854,37 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = {
 		},
 
 		.has_shadowcon	= 1,
+		.has_clksel	= 1,
+	},
+	.win[0]	= &s3c_fb_data_s5p_wins[0],
+	.win[1]	= &s3c_fb_data_s5p_wins[1],
+	.win[2]	= &s3c_fb_data_s5p_wins[2],
+	.win[3]	= &s3c_fb_data_s5p_wins[3],
+	.win[4]	= &s3c_fb_data_s5p_wins[4],
+};
+
+static struct s3c_fb_driverdata s3c_fb_data_exynos4 = {
+	.variant = {
+		.nr_windows	= 5,
+		.vidtcon	= VIDTCON0,
+		.wincon		= WINCON(0),
+		.winmap		= WINxMAP(0),
+		.keycon		= WKEYCON,
+		.osd		= VIDOSD_BASE,
+		.osd_stride	= 16,
+		.buf_start	= VIDW_BUF_START(0),
+		.buf_size	= VIDW_BUF_SIZE(0),
+		.buf_end	= VIDW_BUF_END(0),
+
+		.palette = {
+			[0] = 0x2400,
+			[1] = 0x2800,
+			[2] = 0x2c00,
+			[3] = 0x3000,
+			[4] = 0x3400,
+		},
+
+		.has_shadowcon	= 1,
 	},
 	.win[0]	= &s3c_fb_data_s5p_wins[0],
 	.win[1]	= &s3c_fb_data_s5p_wins[1],
@@ -1843,6 +1913,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s3c2443 = {
 			[0] = 0x400,
 			[1] = 0x800,
 		},
+		.has_clksel	= 1,
 	},
 	.win[0] = &(struct s3c_fb_win_variant) {
 		.palette_sz	= 256,
@@ -1870,6 +1941,9 @@ static struct platform_device_id s3c_fb_driver_ids[] = {
 		.name		= "s5pv210-fb",
 		.driver_data	= (unsigned long)&s3c_fb_data_s5pv210,
 	}, {
+		.name		= "exynos4-fb",
+		.driver_data	= (unsigned long)&s3c_fb_data_exynos4,
+	}, {
 		.name		= "s3c2443-fb",
 		.driver_data	= (unsigned long)&s3c_fb_data_s3c2443,
 	},
-- 
1.7.1

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±ýöÝzÿâžØ^n‡r¡ö¦zË\x1aëh™¨è­Ú&£ûàz¿äz¹Þ—ú+€Ê+zf£¢·hšˆ§~†­†Ûiÿÿïêÿ‘êçz_è®\x0fæj:+v‰¨þ)ߣøm

^ permalink raw reply related

* [PATCH V4 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD and
From: JinGoo Han @ 2011-06-22  3:48 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
	"linux-fbdev@vger.kernel.org" <linux-f>
  Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
	Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
	JinGoo Han

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1252", Size: 9808 bytes --]

From: Jonghun Han <jonghun.han@samsung.com>

This patch adds support EXYNOS4 FIMD0 and LTE480WV LCD pannel.

Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/mach-smdkc210.c |  114 +++++++++++++++++++++++++++++++++
 arch/arm/mach-exynos4/mach-smdkv310.c |  114 +++++++++++++++++++++++++++++++++
 2 files changed, 228 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c
index e645f7a..360a50a 100644
--- a/arch/arm/mach-exynos4/mach-smdkc210.c
+++ b/arch/arm/mach-exynos4/mach-smdkc210.c
@@ -9,26 +9,33 @@
 */
 
 #include <linux/serial_core.h>
+#include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/lcd.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/smsc911x.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
+#include <linux/clk.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
+#include <video/platform_lcd.h>
+
 #include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
 #include <plat/exynos4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/fb.h>
 #include <plat/sdhci.h>
 #include <plat/iic.h>
 #include <plat/pd.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKC210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -111,6 +118,69 @@ static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
 	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 1);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+		/* fire nRESET on power up */
+		gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+		gpio_direction_output(EXYNOS4_GPX0(6), 1);
+		mdelay(100);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 0);
+		mdelay(10);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 1);
+		mdelay(10);
+
+		gpio_free(EXYNOS4_GPX0(6));
+	} else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 0);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+	}
+}
+
+static struct plat_lcd_data smdkc210_lcd_lte480wv_data = {
+	.set_power      = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkc210_lcd_lte480wv = {
+	.name                   = "platform-lcd",
+	.dev.parent             = &s5p_device_fimd0.dev,
+	.dev.platform_data      = &smdkc210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+	.win_mode = {
+		.left_margin    = 13,
+		.right_margin   = 8,
+		.upper_margin   = 7,
+		.lower_margin   = 5,
+		.hsync_len      = 3,
+		.vsync_len      = 1,
+		.xres   = 800,
+		.yres   = 480,
+	},
+	.max_bpp        = 32,
+	.default_bpp    = 24,
+};
+
+static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = {
+	.win[0]		= &smdkc210_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
+};
+
 static struct resource smdkc210_smsc911x_resources[] = {
 	[0] = {
 		.start	= EXYNOS4_PA_SROM_BANK(1),
@@ -165,6 +235,8 @@ static struct platform_device *smdkc210_devices[] __initdata = {
 	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_sysmmu,
 	&samsung_asoc_dma,
+	&s5p_device_fimd0,
+	&smdkc210_lcd_lte480wv,
 	&smdkc210_smsc911x,
 };
 
@@ -191,6 +263,44 @@ static void __init smdkc210_smsc911x_init(void)
 		     (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
 }
 
+static int __init smdkc210_fimd0_setup_clock(void)
+{
+	struct clk *sclk = NULL;
+	struct clk *mout_mpll = NULL;
+
+	u32 rate = 0;
+
+	sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
+	if (IS_ERR(sclk)) {
+		printk(KERN_ERR "failed to get sclk for fimd\n");
+		goto err_clk2;
+	}
+
+	mout_mpll = clk_get(NULL, "mout_mpll");
+	if (IS_ERR(mout_mpll)) {
+		printk(KERN_ERR "failed to get mout_mpll\n");
+		goto err_clk1;
+	}
+
+	clk_set_parent(sclk, mout_mpll);
+	if (!rate)
+		rate = 134000000;
+
+	clk_set_rate(sclk, rate);
+
+	clk_put(sclk);
+	clk_put(mout_mpll);
+
+	return 0;
+
+err_clk1:
+	clk_put(mout_mpll);
+err_clk2:
+	clk_put(sclk);
+
+	return -EINVAL;
+}
+
 static void __init smdkc210_map_io(void)
 {
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -210,7 +320,11 @@ static void __init smdkc210_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
 	s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
 
+	s5p_fimd0_set_platdata(&smdkc210_lcd0_pdata);
+
 	platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
+
+	smdkc210_fimd0_setup_clock();
 }
 
 MACHINE_START(SMDKC210, "SMDKC210")
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
index 1526764..7bc12b5 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -9,28 +9,35 @@
 */
 
 #include <linux/serial_core.h>
+#include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/lcd.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/smsc911x.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
+#include <linux/clk.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
+#include <video/platform_lcd.h>
+
 #include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
 #include <plat/exynos4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/fb.h>
 #include <plat/keypad.h>
 #include <plat/sdhci.h>
 #include <plat/iic.h>
 #include <plat/pd.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKV310_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -113,6 +120,69 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
 	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 1);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+		/* fire nRESET on power up */
+		gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+		gpio_direction_output(EXYNOS4_GPX0(6), 1);
+		mdelay(100);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 0);
+		mdelay(10);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 1);
+		mdelay(10);
+
+		gpio_free(EXYNOS4_GPX0(6));
+	} else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 0);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+	}
+}
+
+static struct plat_lcd_data smdkv310_lcd_lte480wv_data = {
+	.set_power      = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkv310_lcd_lte480wv = {
+	.name                   = "platform-lcd",
+	.dev.parent             = &s5p_device_fimd0.dev,
+	.dev.platform_data      = &smdkv310_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win0 = {
+	.win_mode = {
+		.left_margin    = 13,
+		.right_margin   = 8,
+		.upper_margin   = 7,
+		.lower_margin   = 5,
+		.hsync_len      = 3,
+		.vsync_len      = 1,
+		.xres   = 800,
+		.yres   = 480,
+	},
+	.max_bpp        = 32,
+	.default_bpp    = 24,
+};
+
+static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = {
+	.win[0]		= &smdkv310_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
+};
+
 static struct resource smdkv310_smsc911x_resources[] = {
 	[0] = {
 		.start	= EXYNOS4_PA_SROM_BANK(1),
@@ -187,6 +257,8 @@ static struct platform_device *smdkv310_devices[] __initdata = {
 	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_sysmmu,
 	&samsung_asoc_dma,
+	&s5p_device_fimd0,
+	&smdkv310_lcd_lte480wv,
 	&smdkv310_smsc911x,
 };
 
@@ -213,6 +285,44 @@ static void __init smdkv310_smsc911x_init(void)
 		     (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
 }
 
+static int __init smdkv310_fimd0_setup_clock(void)
+{
+	struct clk *sclk = NULL;
+	struct clk *mout_mpll = NULL;
+
+	u32 rate = 0;
+
+	sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
+	if (IS_ERR(sclk)) {
+		printk(KERN_ERR "failed to get sclk for fimd\n");
+		goto err_clk2;
+	}
+
+	mout_mpll = clk_get(NULL, "mout_mpll");
+	if (IS_ERR(mout_mpll)) {
+		printk(KERN_ERR "failed to get mout_mpll\n");
+		goto err_clk1;
+	}
+
+	clk_set_parent(sclk, mout_mpll);
+	if (!rate)
+		rate = 134000000;
+
+	clk_set_rate(sclk, rate);
+
+	clk_put(sclk);
+	clk_put(mout_mpll);
+
+	return 0;
+
+err_clk1:
+	clk_put(mout_mpll);
+err_clk2:
+	clk_put(sclk);
+
+	return -EINVAL;
+}
+
 static void __init smdkv310_map_io(void)
 {
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -232,9 +342,13 @@ static void __init smdkv310_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
 	s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
 
+	s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
+
 	samsung_keypad_set_platdata(&smdkv310_keypad_data);
 
 	platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
+
+	smdkv310_fimd0_setup_clock();
 }
 
 MACHINE_START(SMDKV310, "SMDKV310")
-- 
1.7.1

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±ýöÝzÿâžØ^n‡r¡ö¦zË\x1aëh™¨è­Ú&£ûàz¿äz¹Þ—ú+€Ê+zf£¢·hšˆ§~†­†Ûiÿÿïêÿ‘êçz_è®\x0fæj:+v‰¨þ)ߣøm

^ permalink raw reply related

* Some questions about DRM(Direct Rendering Manager)
From: daeinki @ 2011-06-22  4:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

I'm writing Samsung SoC based DRM framework and this one includes FIMD
and HDMI driver as hardware dependent modules. and for now, encoder,
connector, crtc and fb module has been materialized almost. but I'm
contending with  framebuffer setting issue(created fb_info should be
registered to linux framebuffer through register_framebuffer() or not)as
default framebuffer at booting time.

at drm_fb_helper_single_fb_probe() of drm_fb_helper.c file, fb_helper's
fb_probe callback is called and this one creates new framebuffer and
returns a value more then 0 if true. internally, this process creates an
fb_info object and drm_framebuffer and then drm_framebuffer would be
added to mode_config.fb_list of the drm_device.

a value returned, new_fb is used to decide that it calls
register_framebuffer() or drm_fb_helper_set_par(). at this point, I am
confused it's a good way to call register_framebuffer() otherwise
drm_fb_helper_set_par(). if register_framebuffer() is called then I
guess drm_fb_helper_set_par() or drm_crtc_helper_set_config() should be
called somewhere subsequently to apply this one to real hardware because
previous process is just for maintaining data logically.(not set up data
to h/w)

it's a right way to call register_framebuffer() and then
drm_fb_helper_set_par() or drm_crtc_helper_set_config()? otherwise just
only drm_fb_helper_set_par() or drm_crtc_helper_set_config() ignoring
register_framebuffer()? and what is the purpose of using
register_framebuffer()?

In my case, first, register_framebuffer() is called and then if desired
default crtc id is matched with drm_fb_helper->crtc_info[0 ~ n].crtc_id,
it gets mode_set of drm_fb_helper->crtc_info[n] and then  it calls
drm_crtc_helper_set_config(mode_set). at this time, all the hardware
configurations would be completed.

thank you in advance.

Best Regards
Inki Dae.

^ permalink raw reply

* Re: [PATCH/RFC] fbdev: Add FOURCC-based format configuration API
From: Florian Tobias Schandinat @ 2011-06-22  5:45 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Geert Uytterhoeven, linux-fbdev, linux-media, dri-devel
In-Reply-To: <201106220031.57972.laurent.pinchart@ideasonboard.com>

Hi Geert, Laurent,

On 06/21/2011 10:31 PM, Laurent Pinchart wrote:
> Hi Geert,
>
> On Tuesday 21 June 2011 22:49:14 Geert Uytterhoeven wrote:
>> On Tue, Jun 21, 2011 at 17:36, Laurent Pinchart wrote:
>>> +The FOURCC-based API replaces format descriptions by four character
>>> codes +(FOURCC). FOURCCs are abstract identifiers that uniquely define a
>>> format +without explicitly describing it. This is the only API that
>>> supports YUV +formats. Drivers are also encouraged to implement the
>>> FOURCC-based API for RGB +and grayscale formats.
>>> +
>>> +Drivers that support the FOURCC-based API report this capability by
>>> setting +the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities
>>> field. +
>>> +FOURCC definitions are located in the linux/videodev2.h header. However,
>>> and +despite starting with the V4L2_PIX_FMT_prefix, they are not
>>> restricted to V4L2 +and don't require usage of the V4L2 subsystem.
>>> FOURCC documentation is +available in
>>> Documentation/DocBook/v4l/pixfmt.xml.
>>> +
>>> +To select a format, applications set the FB_VMODE_FOURCC bit in the
>>> +fb_var_screeninfo vmode field, and set the fourcc field to the desired
>>> FOURCC. +The bits_per_pixel, red, green, blue, transp and nonstd fields
>>> must be set to +0 by applications and ignored by drivers. Note that the
>>> grayscale and fourcc +fields share the same memory location. Application
>>> must thus not set the +grayscale field to 0.
>>
>> These are the only parts I don't like: (ab)using the vmode field (this
>> isn't really a vmode flag), and the union of grayscale and fourcc (avoid
>> unions where possible).
>
> I've proposed adding a FB_NONSTD_FORMAT bit to the nonstd field as a FOURCC
> mode indicator in my initial RFC. Florian Tobias Schandinat wasn't very happy
> with that, and proposed using the vmode field instead.
>
> Given that there's virtually no fbdev documentation, whether the vmode field
> and/or nonstd field are good fit for a FOURCC mode indicator is subject to
> interpretation.

The reason for my suggestion is that the vmode field is accepted to contain only 
flags and at least to me there is no hard line what is part of the video mode 
and what is not. In contrast the nonstd field is already used in a lot of 
different (incompatible) ways. I think if we only use the nonstd field for 
handling FOURCC it is likely that some problems will appear.

>> What about storing the FOURCC value in nonstd instead?
>
> Wouldn't that be a union of nonstd and fourcc ? :-) FOURCC-based format
> setting will be a standard fbdev API, I'm not very keen on storing it in the
> nonstd field without a union.
>
>> As FOURCC values are always 4 ASCII characters (hence all 4 bytes must
>> be non-zero), I don't think there are any conflicts with existing values of
>> nonstd. To make it even safer and easier to parse, you could set bit 31 of
>> nonstd as a FOURCC indicator.
>
> I would then create a union between nonstd and fourcc, and document nonstd as
> being used for the legacy API only. Most existing drivers use a couple of
> nonstd bits only. The driver that (ab)uses nonstd the most is pxafb and uses
> bits 22:0. Bits 31:24 are never used as far as I can tell, so nonstd&
> 0xff000000 != 0 could be used as a FOURCC mode test.
>
> This assumes that FOURCCs will never have their last character set to '\0'. Is
> that a safe assumption for the future ?

Yes, I think. The information I found indicates that space should be used for 
padding, so a \0 shouldn't exist.
I think using only the nonstd field and requiring applications to check the 
capabilities would be possible, although not fool proof ;)

Great work, Laurent, do you have plans to modify fbset to allow using this 
format API from the command line?


Regards,

Florian Tobias Schandinat

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox