Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* Re: [PATCH 4/8] net: freescale: replace CONFIG_8xx by CONFIG_PPC_8xx
From: David Miller @ 2015-03-12 19:27 UTC (permalink / raw)
  To: christophe.leroy
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, vitb,
	linux-kernel, netdev, linux-mtd, user-mode-linux-user,
	pantelis.antoniou, linuxppc-dev
In-Reply-To: <20150312152354.A47721A241F@localhost.localdomain>

From: Christophe Leroy <christophe.leroy@c-s.fr>
Date: Thu, 12 Mar 2015 16:23:54 +0100 (CET)

> Two config options exist to define powerpc MPC8xx:
> * CONFIG_PPC_8xx
> * CONFIG_8xx
> In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
> communication co-processor
> 
> arch/powerpc/platforms/Kconfig.cputype has contained the following
> comment about CONFIG_8xx item for some years:
> "# this is temp to handle compat with arch=ppc"
> 
> It looks like not many places still have that old CONFIG_8xx used,
> so it is likely to be a good time to get rid of it completely ?
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

Acked-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply

* Re: [PATCH 7/8] isdn: replace CONFIG_8xx by CONFIG_PPC_8xx
From: David Miller @ 2015-03-12 19:27 UTC (permalink / raw)
  To: christophe.leroy
  Cc: isdn, linux-serial, user-mode-linux-devel, netdev, linux-kernel,
	linux-fbdev, linux-mtd, user-mode-linux-user, linuxppc-dev
In-Reply-To: <20150312152409.E7B5C1A2422@localhost.localdomain>

From: Christophe Leroy <christophe.leroy@c-s.fr>
Date: Thu, 12 Mar 2015 16:24:09 +0100 (CET)

> Two config options exist to define powerpc MPC8xx:
> * CONFIG_PPC_8xx
> * CONFIG_8xx
> In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
> communication co-processor
> 
> arch/powerpc/platforms/Kconfig.cputype has contained the following
> comment about CONFIG_8xx item for some years:
> "# this is temp to handle compat with arch=ppc"
> 
> It looks like not many places still have that old CONFIG_8xx used,
> so it is likely to be a good time to get rid of it completely ?
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

Acked-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply

* Re: [PATCH 7/8] isdn: replace CONFIG_8xx by CONFIG_PPC_8xx
From: Sergei Shtylyov @ 2015-03-12 18:52 UTC (permalink / raw)
  To: Christophe Leroy, Karsten Keil
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, netdev,
	linux-kernel, linux-mtd, user-mode-linux-user, linuxppc-dev
In-Reply-To: <20150312152409.E7B5C1A2422@localhost.localdomain>

Hello.

On 03/12/2015 06:24 PM, Christophe Leroy wrote:

> Two config options exist to define powerpc MPC8xx:
> * CONFIG_PPC_8xx
> * CONFIG_8xx
> In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
> communication co-processor

> arch/powerpc/platforms/Kconfig.cputype has contained the following
> comment about CONFIG_8xx item for some years:
> "# this is temp to handle compat with arch=ppc"

> It looks like not many places still have that old CONFIG_8xx used,
> so it is likely to be a good time to get rid of it completely ?

> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

[...]

> diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig
> index 09df54f..ad9deab 100644
> --- a/drivers/isdn/hardware/mISDN/Kconfig
> +++ b/drivers/isdn/hardware/mISDN/Kconfig
[...]
> @@ -28,7 +28,7 @@ config MISDN_HFCMULTI_8xx
>   	depends on MISDN
>   	depends on MISDN_HFCMULTI
>   	depends on 8xx

    Eh, how about this one?

> -	default 8xx
> +	default PPC_8xx
>   	help
>   	  Enable support for the XHFC embedded solution from Speech Design.

WBR, Sergei


^ permalink raw reply

* [PATCH 0/8] powerpc/8xx: Getting rid of CONFIG_8xx
From: Christophe Leroy @ 2015-03-12 15:24 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Vitaly Bordug, scottwood, Jeff Dike, Richard Weinberger,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen,
	Pantelis Antoniou, Greg Kroah-Hartman, Jiri Slaby,
	David Woodhouse, Brian Norris, Karsten Keil
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, netdev,
	linux-kernel, linux-mtd, user-mode-linux-user, linuxppc-dev

Two config options exist to define powerpc MPC8xx:
* CONFIG_PPC_8xx
* CONFIG_8xx
In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
communication co-processor

arch/powerpc/platforms/Kconfig.cputype has contained the following
comment about CONFIG_8xx item for some years:
"# this is temp to handle compat with arch=ppc"

It looks like not many places still have that old CONFIG_8xx used,
so it is likely to be a good time to get rid of it completely ?

Patchset is composed of the following patches:
[1/8] powerpc: replace CONFIG_8xx by CONFIG_PPC_8xx
[2/8] um: replace CONFIG_8xx by CONFIG_PPC_8xx
[3/8] video: replace CONFIG_8xx by CONFIG_PPC_8xx
[4/8] net: freescale: replace CONFIG_8xx by CONFIG_PPC_8xx
[5/8] tty: cpm_uart: replace CONFIG_8xx by CONFIG_CPM1
[6/8] mtd: replace CONFIG_8xx by CONFIG_PPC_8xx
[7/8] isdn: replace CONFIG_8xx by CONFIG_PPC_8xx
[8/8] powerpc: get rid of CONFIG_8xx

All but the last one are independant and can be applied in any
order. Only the 8th one requires the first 7 patches to be applied.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

---
 arch/powerpc/Kconfig                             | 10 +++++-----
 arch/powerpc/Makefile                            |  2 +-
 arch/powerpc/boot/Makefile                       |  4 ++--
 arch/powerpc/boot/util.S                         |  6 +++---
 arch/powerpc/include/asm/cache.h                 |  2 +-
 arch/powerpc/include/asm/cputable.h              |  4 ++--
 arch/powerpc/include/asm/fs_pd.h                 |  2 +-
 arch/powerpc/include/asm/pgtable-ppc32.h         |  2 +-
 arch/powerpc/include/asm/ppc_asm.h               |  4 ++--
 arch/powerpc/include/asm/reg.h                   | 10 +++++-----
 arch/powerpc/include/asm/timex.h                 |  4 ++--
 arch/powerpc/kernel/Makefile                     |  2 +-
 arch/powerpc/kernel/cputable.c                   |  4 ++--
 arch/powerpc/kernel/irq.c                        |  2 +-
 arch/powerpc/kernel/kgdb.c                       |  4 ++--
 arch/powerpc/kernel/misc_32.S                    |  4 ++--
 arch/powerpc/kernel/traps.c                      |  6 +++---
 arch/powerpc/kernel/vdso32/gettimeofday.S        |  2 +-
 arch/powerpc/mm/fault.c                          |  4 ++--
 arch/powerpc/mm/init_32.c                        |  4 ++--
 arch/powerpc/mm/mem.c                            |  2 +-
 arch/powerpc/mm/mmu_decl.h                       | 12 ++++++------
 arch/powerpc/mm/tlb_nohash_low.S                 |  2 +-
 arch/powerpc/platforms/8xx/Kconfig               |  3 +--
 arch/powerpc/platforms/Kconfig.cputype           |  7 +------
 arch/powerpc/sysdev/Makefile                     |  2 +-
 arch/powerpc/sysdev/fsl_soc.c                    |  3 ++-
 arch/powerpc/sysdev/fsl_soc.h                    |  3 ++-
 arch/powerpc/xmon/xmon.c                         |  2 +-
 arch/um/sys-ppc/misc.S                           | 12 ++++++------
 drivers/isdn/hardware/mISDN/Kconfig              |  4 ++--
 drivers/mtd/maps/Kconfig                         |  2 +-
 drivers/net/ethernet/freescale/fs_enet/mac-fec.c |  2 +-
 drivers/net/ethernet/freescale/fs_enet/mac-scc.c |  2 +-
 drivers/tty/serial/Kconfig                       |  2 +-
 drivers/tty/serial/cpm_uart/Makefile             |  2 +-
 drivers/tty/serial/cpm_uart/cpm_uart.h           |  2 +-
 drivers/video/console/Kconfig                    |  2 +-
 38 files changed, 72 insertions(+), 76 deletions(-)

^ permalink raw reply

* [PATCH 8/8] powerpc: get rid of CONFIG_8xx
From: Christophe Leroy @ 2015-03-12 15:24 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Vitaly Bordug, scottwood
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, netdev,
	linux-kernel, linux-mtd, user-mode-linux-user, linuxppc-dev

Two config options exist to define powerpc MPC8xx:
* CONFIG_PPC_8xx
* CONFIG_8xx
In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
communication co-processor

arch/powerpc/platforms/Kconfig.cputype has contained the following
comment about CONFIG_8xx item for some years:
"# this is temp to handle compat with arch=ppc"

It looks like not many places still have that old CONFIG_8xx used,
so it is likely to be a good time to get rid of it completely ?

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

---
 arch/powerpc/platforms/Kconfig.cputype | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 6d481ff..beca3ce 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -32,7 +32,6 @@ config PPC_85xx
 config PPC_8xx
 	bool "Freescale 8xx"
 	select FSL_SOC
-	select 8xx
 	select PPC_LIB_RHEAP
 
 config 40x
@@ -157,10 +156,6 @@ config TUNE_CELL
 	  itself, so the resulting kernel will keep running on all other
 	  machines.
 
-# this is temp to handle compat with arch=ppc
-config 8xx
-	bool
-
 config E500
 	select FSL_EMB_PERFMON
 	select PPC_FSL_BOOK3E
-- 
2.1.0


^ permalink raw reply related

* [PATCH 7/8] isdn: replace CONFIG_8xx by CONFIG_PPC_8xx
From: Christophe Leroy @ 2015-03-12 15:24 UTC (permalink / raw)
  To: Karsten Keil
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, netdev,
	linux-kernel, linux-mtd, user-mode-linux-user, linuxppc-dev

Two config options exist to define powerpc MPC8xx:
* CONFIG_PPC_8xx
* CONFIG_8xx
In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
communication co-processor

arch/powerpc/platforms/Kconfig.cputype has contained the following
comment about CONFIG_8xx item for some years:
"# this is temp to handle compat with arch=ppc"

It looks like not many places still have that old CONFIG_8xx used,
so it is likely to be a good time to get rid of it completely ?

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

---
 drivers/isdn/hardware/mISDN/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig
index 09df54f..ad9deab 100644
--- a/drivers/isdn/hardware/mISDN/Kconfig
+++ b/drivers/isdn/hardware/mISDN/Kconfig
@@ -13,7 +13,7 @@ config MISDN_HFCPCI
 
 config MISDN_HFCMULTI
 	tristate "Support for HFC multiport cards (HFC-4S/8S/E1)"
-	depends on PCI || 8xx
+	depends on PCI || PPC_8xx
 	depends on MISDN
 	help
 	  Enable support for cards with Cologne Chip AG's HFC multiport
@@ -28,7 +28,7 @@ config MISDN_HFCMULTI_8xx
 	depends on MISDN
 	depends on MISDN_HFCMULTI
 	depends on 8xx
-	default 8xx
+	default PPC_8xx
 	help
 	  Enable support for the XHFC embedded solution from Speech Design.
 
-- 
2.1.0


^ permalink raw reply related

* [PATCH 6/8] mtd: replace CONFIG_8xx by CONFIG_PPC_8xx
From: Christophe Leroy @ 2015-03-12 15:24 UTC (permalink / raw)
  To: David Woodhouse, Brian Norris
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, netdev,
	linux-kernel, linux-mtd, user-mode-linux-user, linuxppc-dev

Two config options exist to define powerpc MPC8xx:
* CONFIG_PPC_8xx
* CONFIG_8xx
In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
communication co-processor

arch/powerpc/platforms/Kconfig.cputype has contained the following
comment about CONFIG_8xx item for some years:
"# this is temp to handle compat with arch=ppc"

It looks like not many places still have that old CONFIG_8xx used,
so it is likely to be a good time to get rid of it completely ?

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

---
 drivers/mtd/maps/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index ba801d2..e715ae9 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -242,7 +242,7 @@ config MTD_L440GX
 
 config MTD_CFI_FLAGADM
 	tristate "CFI Flash device mapping on FlagaDM"
-	depends on 8xx && MTD_CFI
+	depends on PPC_8xx && MTD_CFI
 	help
 	  Mapping for the Flaga digital module. If you don't have one, ignore
 	  this setting.
-- 
2.1.0


^ permalink raw reply related

* [PATCH 5/8] tty: cpm_uart: replace CONFIG_8xx by CONFIG_CPM1
From: Christophe Leroy @ 2015-03-12 15:23 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, netdev,
	linux-kernel, linux-mtd, user-mode-linux-user, linuxppc-dev

Two config options exist to define powerpc MPC8xx:
* CONFIG_PPC_8xx
* CONFIG_8xx
In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
communication co-processor

arch/powerpc/platforms/Kconfig.cputype has contained the following
comment about CONFIG_8xx item for some years:
"# this is temp to handle compat with arch=ppc"

It looks like not many places still have that old CONFIG_8xx used,
so it is likely to be a good time to get rid of it completely ?

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

---
 drivers/tty/serial/Kconfig             | 2 +-
 drivers/tty/serial/cpm_uart/Makefile   | 2 +-
 drivers/tty/serial/cpm_uart/cpm_uart.h | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index c9dbc62..6086586 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -868,7 +868,7 @@ config SERIAL_PMACZILOG_CONSOLE
 
 config SERIAL_CPM
 	tristate "CPM SCC/SMC serial port support"
-	depends on CPM2 || 8xx
+	depends on CPM2 || CPM1
 	select SERIAL_CORE
 	help
 	  This driver supports the SCC and SMC serial ports on Motorola 
diff --git a/drivers/tty/serial/cpm_uart/Makefile b/drivers/tty/serial/cpm_uart/Makefile
index e072724..896a5d5 100644
--- a/drivers/tty/serial/cpm_uart/Makefile
+++ b/drivers/tty/serial/cpm_uart/Makefile
@@ -6,6 +6,6 @@ obj-$(CONFIG_SERIAL_CPM) += cpm_uart.o
 
 # Select the correct platform objects.
 cpm_uart-objs-$(CONFIG_CPM2)	+= cpm_uart_cpm2.o
-cpm_uart-objs-$(CONFIG_8xx)	+= cpm_uart_cpm1.o
+cpm_uart-objs-$(CONFIG_CPM1)	+= cpm_uart_cpm1.o
 
 cpm_uart-objs	:= cpm_uart_core.o $(cpm_uart-objs-y)
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart.h b/drivers/tty/serial/cpm_uart/cpm_uart.h
index cf34d26..0ad027b 100644
--- a/drivers/tty/serial/cpm_uart/cpm_uart.h
+++ b/drivers/tty/serial/cpm_uart/cpm_uart.h
@@ -19,7 +19,7 @@
 
 #if defined(CONFIG_CPM2)
 #include "cpm_uart_cpm2.h"
-#elif defined(CONFIG_8xx)
+#elif defined(CONFIG_CPM1)
 #include "cpm_uart_cpm1.h"
 #endif
 
-- 
2.1.0


^ permalink raw reply related

* [PATCH 4/8] net: freescale: replace CONFIG_8xx by CONFIG_PPC_8xx
From: Christophe Leroy @ 2015-03-12 15:23 UTC (permalink / raw)
  To: Vitaly Bordug, Pantelis Antoniou
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, netdev,
	linux-kernel, linux-mtd, user-mode-linux-user, linuxppc-dev

Two config options exist to define powerpc MPC8xx:
* CONFIG_PPC_8xx
* CONFIG_8xx
In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
communication co-processor

arch/powerpc/platforms/Kconfig.cputype has contained the following
comment about CONFIG_8xx item for some years:
"# this is temp to handle compat with arch=ppc"

It looks like not many places still have that old CONFIG_8xx used,
so it is likely to be a good time to get rid of it completely ?

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

---
 drivers/net/ethernet/freescale/fs_enet/mac-fec.c | 2 +-
 drivers/net/ethernet/freescale/fs_enet/mac-scc.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
index b34214e..0e02bb4 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
@@ -38,7 +38,7 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 #include <asm/8xx_immap.h>
 #include <asm/pgtable.h>
 #include <asm/cpm1.h>
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
index 7a184e8..eec8963 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
@@ -37,7 +37,7 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 #include <asm/8xx_immap.h>
 #include <asm/pgtable.h>
 #include <asm/cpm1.h>
-- 
2.1.0


^ permalink raw reply related

* [PATCH 3/8] video: replace CONFIG_8xx by CONFIG_PPC_8xx
From: Christophe Leroy @ 2015-03-12 15:23 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, netdev,
	linux-kernel, linux-mtd, user-mode-linux-user, linuxppc-dev

Two config options exist to define powerpc MPC8xx:
* CONFIG_PPC_8xx
* CONFIG_8xx
In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
communication co-processor

arch/powerpc/platforms/Kconfig.cputype has contained the following
comment about CONFIG_8xx item for some years:
"# this is temp to handle compat with arch=ppc"

It looks like not many places still have that old CONFIG_8xx used,
so it is likely to be a good time to get rid of it completely ?

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

---
 drivers/video/console/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index ba97efc..6ee84c3 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -6,7 +6,7 @@ menu "Console display driver support"
 
 config VGA_CONSOLE
 	bool "VGA text console" if EXPERT || !X86
-	depends on !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && \
+	depends on !4xx && !PPC_8xx && !SPARC && !M68K && !PARISC && !FRV && \
 		!SUPERH && !BLACKFIN && !AVR32 && !MN10300 && !CRIS && \
 		(!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) && \
 		!ARM64
-- 
2.1.0


^ permalink raw reply related

* [PATCH 2/8] um: replace CONFIG_8xx by CONFIG_PPC_8xx
From: Christophe Leroy @ 2015-03-12 15:23 UTC (permalink / raw)
  To: Jeff Dike, Richard Weinberger
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, netdev,
	linux-kernel, linux-mtd, user-mode-linux-user, linuxppc-dev

Two config options exist to define powerpc MPC8xx:
* CONFIG_PPC_8xx
* CONFIG_8xx
In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
communication co-processor

arch/powerpc/platforms/Kconfig.cputype has contained the following
comment about CONFIG_8xx item for some years:
"# this is temp to handle compat with arch=ppc"

It looks like not many places still have that old CONFIG_8xx used,
so it is likely to be a good time to get rid of it completely ?

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

---
 arch/um/sys-ppc/misc.S | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/um/sys-ppc/misc.S b/arch/um/sys-ppc/misc.S
index 1364b7d..163e0b2 100644
--- a/arch/um/sys-ppc/misc.S
+++ b/arch/um/sys-ppc/misc.S
@@ -18,7 +18,7 @@
 #include <asm/processor.h>
 #include "ppc_asm.h"
 
-#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
+#if defined(CONFIG_4xx) || defined(CONFIG_PPC_8xx)
 #define CACHE_LINE_SIZE		16
 #define LG_CACHE_LINE_SIZE	4
 #define MAX_COPY_PREFETCH	1
@@ -26,7 +26,7 @@
 #define CACHE_LINE_SIZE		32
 #define LG_CACHE_LINE_SIZE	5
 #define MAX_COPY_PREFETCH	4
-#endif /* CONFIG_4xx || CONFIG_8xx */
+#endif /* CONFIG_4xx || CONFIG_PPC_8xx */
 
 	.text
 
@@ -38,7 +38,7 @@
 _GLOBAL(clear_page)
 	li	r0,4096/CACHE_LINE_SIZE
 	mtctr	r0
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 	li	r4, 0
 1:	stw	r4, 0(r3)
 	stw	r4, 4(r3)
@@ -72,7 +72,7 @@ _GLOBAL(copy_page)
 	addi	r4,r4,-4
 	li	r5,4
 
-#ifndef CONFIG_8xx
+#ifndef CONFIG_PPC_8xx
 #if MAX_COPY_PREFETCH > 1
 	li	r0,MAX_COPY_PREFETCH
 	li	r11,4
@@ -84,12 +84,12 @@ _GLOBAL(copy_page)
 	dcbt	r5,r4
 	li	r11,CACHE_LINE_SIZE+4
 #endif /* MAX_COPY_PREFETCH */
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_PPC_8xx */
 
 	li	r0,4096/CACHE_LINE_SIZE
 	mtctr	r0
 1:
-#ifndef CONFIG_8xx
+#ifndef CONFIG_PPC_8xx
 	dcbt	r11,r4
 	dcbz	r5,r3
 #endif
-- 
2.1.0


^ permalink raw reply related

* [PATCH 1/8] powerpc: replace CONFIG_8xx by CONFIG_PPC_8xx
From: Christophe Leroy @ 2015-03-12 15:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Vitaly Bordug, scottwood
  Cc: linux-fbdev, linux-serial, user-mode-linux-devel, netdev,
	linux-kernel, linux-mtd, user-mode-linux-user, linuxppc-dev

Two config options exist to define powerpc MPC8xx:
* CONFIG_PPC_8xx
* CONFIG_8xx
In addition, CONFIG_PPC_8xx also defines CONFIG_CPM1 as
communication co-processor

arch/powerpc/platforms/Kconfig.cputype has contained the following
comment about CONFIG_8xx item for some years:
"# this is temp to handle compat with arch=ppc"

It looks like not many places still have that old CONFIG_8xx used,
so it is likely to be a good time to get rid of it completely ?

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

---
 arch/powerpc/Kconfig                      | 10 +++++-----
 arch/powerpc/Makefile                     |  2 +-
 arch/powerpc/boot/Makefile                |  4 ++--
 arch/powerpc/boot/util.S                  |  6 +++---
 arch/powerpc/include/asm/cache.h          |  2 +-
 arch/powerpc/include/asm/cputable.h       |  4 ++--
 arch/powerpc/include/asm/fs_pd.h          |  2 +-
 arch/powerpc/include/asm/pgtable-ppc32.h  |  2 +-
 arch/powerpc/include/asm/ppc_asm.h        |  4 ++--
 arch/powerpc/include/asm/reg.h            | 10 +++++-----
 arch/powerpc/include/asm/timex.h          |  4 ++--
 arch/powerpc/kernel/Makefile              |  2 +-
 arch/powerpc/kernel/cputable.c            |  4 ++--
 arch/powerpc/kernel/irq.c                 |  2 +-
 arch/powerpc/kernel/kgdb.c                |  4 ++--
 arch/powerpc/kernel/misc_32.S             |  4 ++--
 arch/powerpc/kernel/traps.c               |  6 +++---
 arch/powerpc/kernel/vdso32/gettimeofday.S |  2 +-
 arch/powerpc/mm/fault.c                   |  4 ++--
 arch/powerpc/mm/init_32.c                 |  4 ++--
 arch/powerpc/mm/mem.c                     |  2 +-
 arch/powerpc/mm/mmu_decl.h                | 12 ++++++------
 arch/powerpc/mm/tlb_nohash_low.S          |  2 +-
 arch/powerpc/platforms/8xx/Kconfig        |  3 +--
 arch/powerpc/platforms/Kconfig.cputype    |  2 +-
 arch/powerpc/sysdev/Makefile              |  2 +-
 arch/powerpc/sysdev/fsl_soc.c             |  3 ++-
 arch/powerpc/sysdev/fsl_soc.h             |  3 ++-
 arch/powerpc/xmon/xmon.c                  |  2 +-
 29 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9b780e0..0ed5b4e 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -327,7 +327,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE
 
 config MATH_EMULATION
 	bool "Math emulation"
-	depends on 4xx || 8xx || PPC_MPC832x || BOOKE
+	depends on 4xx || PPC_8xx || PPC_MPC832x || BOOKE
 	---help---
 	  Some PowerPC chips designed for embedded applications do not have
 	  a floating-point unit and therefore do not implement the
@@ -797,9 +797,9 @@ config PPC_PCI_CHOICE
 
 config PCI
 	bool "PCI support" if PPC_PCI_CHOICE
-	default y if !40x && !CPM2 && !8xx && !PPC_83xx \
+	default y if !40x && !CPM2 && !PPC_8xx && !PPC_83xx \
 		&& !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON
-	default PCI_QSPAN if !4xx && !CPM2 && 8xx
+	default PCI_QSPAN if !4xx && !CPM2 && PPC_8xx
 	select GENERIC_PCI_IOMAP
 	help
 	  Find out whether your system includes a PCI bus. PCI is the name of
@@ -815,7 +815,7 @@ config PCI_SYSCALL
 
 config PCI_QSPAN
 	bool "QSpan PCI"
-	depends on !4xx && !CPM2 && 8xx
+	depends on !4xx && !CPM2 && PPC_8xx
 	select PPC_I8259
 	help
 	  Say Y here if you have a system based on a Motorola 8xx-series
@@ -1033,7 +1033,7 @@ config CONSISTENT_SIZE
 
 config PIN_TLB
 	bool "Pinned Kernel TLBs (860 ONLY)"
-	depends on ADVANCED_OPTIONS && 8xx
+	depends on ADVANCED_OPTIONS && PPC_8xx
 endmenu
 
 if PPC64
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index fc502e0..bd6bd46 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -211,7 +211,7 @@ KBUILD_AFLAGS += $(cpu-as-y)
 KBUILD_CFLAGS += $(cpu-as-y)
 
 head-y				:= arch/powerpc/kernel/head_$(CONFIG_WORD_SIZE).o
-head-$(CONFIG_8xx)		:= arch/powerpc/kernel/head_8xx.o
+head-$(CONFIG_PPC_8xx)		:= arch/powerpc/kernel/head_8xx.o
 head-$(CONFIG_40x)		:= arch/powerpc/kernel/head_40x.o
 head-$(CONFIG_44x)		:= arch/powerpc/kernel/head_44x.o
 head-$(CONFIG_FSL_BOOKE)	:= arch/powerpc/kernel/head_fsl_booke.o
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 8a5bc1c..99c2276 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -78,7 +78,7 @@ src-wlib-y := string.S crt0.S crtsavres.S stdio.c main.c \
 		uartlite.c mpc52xx-psc.c
 src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c
 src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
-src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c
+src-wlib-$(CONFIG_PPC_8xx) += mpc8xx.c planetcore.c fsl-soc.c
 src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c
 src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c
 
@@ -95,7 +95,7 @@ src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c treeboot-bamboo.c \
 				treeboot-iss4xx.c treeboot-currituck.c \
 				treeboot-akebono.c \
 				simpleboot.c fixed-head.S virtex.c
-src-plat-$(CONFIG_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c
+src-plat-$(CONFIG_PPC_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c
 src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c
 src-plat-$(CONFIG_PPC_82xx) += cuboot-pq2.c fixed-head.S ep8248e.c cuboot-824x.c
 src-plat-$(CONFIG_PPC_83xx) += cuboot-83xx.c fixed-head.S redboot-83xx.c
diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S
index 243b849..7be8f29 100644
--- a/arch/powerpc/boot/util.S
+++ b/arch/powerpc/boot/util.S
@@ -71,7 +71,7 @@ udelay:
 	add	r4,r4,r5
 	addi	r4,r4,-1
 	divw	r4,r4,r5	/* BUS ticks */
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 1:	mftbu	r5
 	mftb	r6
 	mftbu	r7
@@ -84,7 +84,7 @@ udelay:
 	bne	1b		/* Get [synced] base time */
 	addc	r9,r6,r4	/* Compute end time */
 	addze	r8,r5
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 2:	mftbu	r5
 #else
 2:	mfspr	r5, SPRN_TBRU
@@ -92,7 +92,7 @@ udelay:
 	cmpw	0,r5,r8
 	blt	2b
 	bgt	3f
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 	mftb	r6
 #else
 	mfspr	r6, SPRN_TBRL
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index 34a05a1..36a8bc0 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -6,7 +6,7 @@
 #include <asm/reg.h>
 
 /* bytes per L1 cache line */
-#if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
+#if defined(CONFIG_PPC_8xx) || defined(CONFIG_403GCX)
 #define L1_CACHE_SHIFT		4
 #define MAX_COPY_PREFETCH	1
 #elif defined(CONFIG_PPC_E500MC)
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 5cf5a6d..f7905be 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -474,7 +474,7 @@ enum {
 #else
 	    CPU_FTRS_GENERIC_32 |
 #endif
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 	    CPU_FTRS_8XX |
 #endif
 #ifdef CONFIG_40x
@@ -525,7 +525,7 @@ enum {
 #else
 	    CPU_FTRS_GENERIC_32 &
 #endif
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 	    CPU_FTRS_8XX &
 #endif
 #ifdef CONFIG_40x
diff --git a/arch/powerpc/include/asm/fs_pd.h b/arch/powerpc/include/asm/fs_pd.h
index f79d6c7..8def56e 100644
--- a/arch/powerpc/include/asm/fs_pd.h
+++ b/arch/powerpc/include/asm/fs_pd.h
@@ -26,7 +26,7 @@
 #define cpm2_unmap(addr) do {} while(0)
 #endif
 
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 #include <asm/8xx_immap.h>
 
 extern immap_t __iomem *mpc8xx_immr;
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
index 64b52b1..022e008 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -113,7 +113,7 @@ extern int icache_44x_need_flush;
 #include <asm/pte-book3e.h>
 #elif defined(CONFIG_FSL_BOOKE)
 #include <asm/pte-fsl-booke.h>
-#elif defined(CONFIG_8xx)
+#elif defined(CONFIG_PPC_8xx)
 #include <asm/pte-8xx.h>
 #else /* CONFIG_6xx */
 #include <asm/pte-hash32.h>
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 7e46125..c680989 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -389,7 +389,7 @@ BEGIN_FTR_SECTION_NESTED(96);		\
 	cmpwi dest,0;			\
 	beq-  90b;			\
 END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
-#elif defined(CONFIG_8xx)
+#elif defined(CONFIG_PPC_8xx)
 #define MFTB(dest)			mftb dest
 #else
 #define MFTB(dest)			mfspr dest, SPRN_TBRL
@@ -440,7 +440,7 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945)
  * and they must be used.
  */
 
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
+#if !defined(CONFIG_4xx) && !defined(CONFIG_PPC_8xx)
 #define tlbia					\
 	li	r4,1024;			\
 	mtctr	r4;				\
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 1c874fb..6277c35 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -22,9 +22,9 @@
 #include <asm/reg_fsl_emb.h>
 #endif
 
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 #include <asm/reg_8xx.h>
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_PPC_8xx */
 
 #define MSR_SF_LG	63              /* Enable 64 bit mode */
 #define MSR_ISF_LG	61              /* Interrupt 64b mode valid on 630 */
@@ -126,7 +126,7 @@
 #define MSR_KERNEL	(MSR_ | MSR_64BIT)
 #define MSR_USER32	(MSR_ | MSR_PR | MSR_EE)
 #define MSR_USER64	(MSR_USER32 | MSR_64BIT)
-#elif defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_8xx)
+#elif defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_8xx)
 /* Default MSR for kernel mode. */
 #define MSR_KERNEL	(MSR_ME|MSR_RI|MSR_IR|MSR_DR)
 #define MSR_USER	(MSR_KERNEL|MSR_PR|MSR_EE)
@@ -1058,7 +1058,7 @@
 #endif
 #endif
 
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 #define SPRN_SPRG_SCRATCH0	SPRN_SPRG0
 #define SPRN_SPRG_SCRATCH1	SPRN_SPRG1
 #define SPRN_SPRG_SCRATCH2	SPRN_SPRG2
@@ -1243,7 +1243,7 @@ static inline unsigned long mfvtb (void)
 
 #else /* __powerpc64__ */
 
-#if defined(CONFIG_8xx)
+#if defined(CONFIG_PPC_8xx)
 #define mftbl()		({unsigned long rval;	\
 			asm volatile("mftbl %0" : "=r" (rval)); rval;})
 #define mftbu()		({unsigned long rval;	\
diff --git a/arch/powerpc/include/asm/timex.h b/arch/powerpc/include/asm/timex.h
index 2cf846e..0fc017f 100644
--- a/arch/powerpc/include/asm/timex.h
+++ b/arch/powerpc/include/asm/timex.h
@@ -29,7 +29,7 @@ static inline cycles_t get_cycles(void)
 	ret = 0;
 
 	__asm__ __volatile__(
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 		"97:	mftb %0\n"
 #else
 		"97:	mfspr %0, %2\n"
@@ -45,7 +45,7 @@ static inline cycles_t get_cycles(void)
 		"	.long 0\n"
 		"	.long 0\n"
 		".previous"
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 		: "=r" (ret) : "i" (CPU_FTR_601));
 #else
 		: "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL));
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 502cf69..c6032fc 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -84,7 +84,7 @@ extra-y				:= head_$(CONFIG_WORD_SIZE).o
 extra-$(CONFIG_40x)		:= head_40x.o
 extra-$(CONFIG_44x)		:= head_44x.o
 extra-$(CONFIG_FSL_BOOKE)	:= head_fsl_booke.o
-extra-$(CONFIG_8xx)		:= head_8xx.o
+extra-$(CONFIG_PPC_8xx)		:= head_8xx.o
 extra-y				+= vmlinux.lds
 
 obj-$(CONFIG_RELOCATABLE_PPC32)	+= reloc_32.o
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index f337666..598f9f8 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1169,7 +1169,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.platform		= "ppc603",
 	},
 #endif /* CONFIG_PPC_BOOK3S_32 */
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 	{	/* 8xx */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x00500000,
@@ -1183,7 +1183,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.dcache_bsize		= 16,
 		.platform		= "ppc823",
 	},
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_PPC_8xx */
 #ifdef CONFIG_40x
 	{	/* 403GC */
 		.pvr_mask		= 0xffffff00,
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 4509603..ebdba2e 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -24,7 +24,7 @@
  * mask register (of which only 16 are defined), hence the weird shifting
  * and complement of the cached_irq_mask.  I want to be able to stuff
  * this right into the SIU SMASK register.
- * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
+ * Many of the prep/chrp functions are conditional compiled on CONFIG_PPC_8xx
  * to reduce code space and undefined function references.
  */
 
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index e77c3cc..f4bc715 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -67,9 +67,9 @@ static struct hard_trap_info
 #endif
 #else /* ! (defined(CONFIG_40x) || defined(CONFIG_BOOKE)) */
 	{ 0x0d00, 0x05 /* SIGTRAP */ },		/* single-step */
-#if defined(CONFIG_8xx)
+#if defined(CONFIG_PPC_8xx)
 	{ 0x1000, 0x04 /* SIGILL */  },		/* software emulation */
-#else /* ! CONFIG_8xx */
+#else /* ! CONFIG_PPC_8xx */
 	{ 0x0f00, 0x04 /* SIGILL */  },		/* performance monitor */
 	{ 0x0f20, 0x08 /* SIGFPE */  },		/* altivec unavailable */
 	{ 0x1300, 0x05 /* SIGTRAP */ }, 	/* instruction address break */
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 7c6bb4b..ba84868 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -297,7 +297,7 @@ _GLOBAL(real_writeb)
  * This is a no-op on the 601.
  */
 _GLOBAL(flush_instruction_cache)
-#if defined(CONFIG_8xx)
+#if defined(CONFIG_PPC_8xx)
 	isync
 	lis	r5, IDC_INVALL@h
 	mtspr	SPRN_IC_CST, r5
@@ -334,7 +334,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
 	mfspr	r3,SPRN_HID0
 	ori	r3,r3,HID0_ICFI
 	mtspr	SPRN_HID0,r3
-#endif /* CONFIG_8xx/4xx */
+#endif /* CONFIG_PPC_8xx/CONFIG_4xx */
 	isync
 	blr
 
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 19e4744..d2f1146 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -716,7 +716,7 @@ void machine_check_exception(struct pt_regs *regs)
 	if (recover > 0)
 		goto bail;
 
-#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
+#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PCI)
 	/* the qspan pci read routines can cause machine checks -- Cort
 	 *
 	 * yuck !!! that totally needs to go away ! There are better ways
@@ -1524,7 +1524,7 @@ void performance_monitor_exception(struct pt_regs *regs)
 	perf_irq(regs);
 }
 
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 void SoftwareEmulation(struct pt_regs *regs)
 {
 	CHECK_FULL_REGS(regs);
@@ -1540,7 +1540,7 @@ void SoftwareEmulation(struct pt_regs *regs)
 
 	_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
 }
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_PPC_8xx */
 
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
 static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
index 6b2b696..4bc65b4 100644
--- a/arch/powerpc/kernel/vdso32/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -232,7 +232,7 @@ __do_get_tspec:
 	lwz	r6,(CFG_TB_ORIG_STAMP+4)(r9)
 
 	/* Get a stable TB value */
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 2:	mftbu	r3
 	mftbl	r4
 	mftbu	r0
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index b396868..5bc2728 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -378,7 +378,7 @@ good_area:
 		   address matching DABR, eciwx, etc. */
 		goto bad_area;
 #endif /* CONFIG_6xx */
-#if defined(CONFIG_8xx)
+#if defined(CONFIG_PPC_8xx)
         /* The MPC8xx seems to always set 0x80000000, which is
          * "undefined".  Of those that can be set, this is the only
          * one which seems bad.
@@ -386,7 +386,7 @@ good_area:
 	if (error_code & 0x10000000)
                 /* Guarded storage error. */
 		goto bad_area;
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_PPC_8xx */
 
 	if (is_exec) {
 		/*
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index a10be66..c64ac35 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -194,7 +194,7 @@ void __init MMU_init(void)
 	memblock_set_current_limit(lowmem_end_addr);
 }
 
-#ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */
+#ifdef CONFIG_PPC_8xx /* No 8xx specific .c file to put that in ... */
 void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 				phys_addr_t first_memblock_size)
 {
@@ -211,4 +211,4 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 	memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
 #endif
 }
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_PPC_8xx */
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index b7285a5..43b2e02 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -423,7 +423,7 @@ void flush_dcache_icache_page(struct page *page)
 		__flush_dcache_icache(start);
 		kunmap_atomic(start);
 	}
-#elif defined(CONFIG_8xx) || defined(CONFIG_PPC64)
+#elif defined(CONFIG_PPC_8xx) || defined(CONFIG_PPC64)
 	/* On 8xx there is no need to kmap since highmem is not supported */
 	__flush_dcache_icache(page_address(page)); 
 #else
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 78c45f3..4669340 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -27,7 +27,7 @@
 /*
  * On 40x and 8xx, we directly inline tlbia and tlbivax
  */
-#if defined(CONFIG_40x) || defined(CONFIG_8xx)
+#if defined(CONFIG_40x) || defined(CONFIG_PPC_8xx)
 static inline void _tlbil_all(void)
 {
 	asm volatile ("sync; tlbia; isync" : : : "memory");
@@ -38,7 +38,7 @@ static inline void _tlbil_pid(unsigned int pid)
 }
 #define _tlbil_pid_noind(pid)	_tlbil_pid(pid)
 
-#else /* CONFIG_40x || CONFIG_8xx */
+#else /* CONFIG_40x || CONFIG_PPC_8xx */
 extern void _tlbil_all(void);
 extern void _tlbil_pid(unsigned int pid);
 #ifdef CONFIG_PPC_BOOK3E
@@ -46,12 +46,12 @@ extern void _tlbil_pid_noind(unsigned int pid);
 #else
 #define _tlbil_pid_noind(pid)	_tlbil_pid(pid)
 #endif
-#endif /* !(CONFIG_40x || CONFIG_8xx) */
+#endif /* !(CONFIG_40x || CONFIG_PPC_8xx) */
 
 /*
  * On 8xx, we directly inline tlbie, on others, it's extern
  */
-#ifdef CONFIG_8xx
+#ifdef CONFIG_PPC_8xx
 static inline void _tlbil_va(unsigned long address, unsigned int pid,
 			     unsigned int tsize, unsigned int ind)
 {
@@ -67,7 +67,7 @@ static inline void _tlbil_va(unsigned long address, unsigned int pid,
 {
 	__tlbil_va(address, pid);
 }
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_PPC_8xx */
 
 #if defined(CONFIG_PPC_BOOK3E) || defined(CONFIG_PPC_47x)
 extern void _tlbivax_bcast(unsigned long address, unsigned int pid,
@@ -132,7 +132,7 @@ extern void wii_memory_fixups(void);
 /* ...and now those things that may be slightly different between processor
  * architectures.  -- Dan
  */
-#if defined(CONFIG_8xx)
+#if defined(CONFIG_PPC_8xx)
 #define MMU_init_hw()		do { } while(0)
 #define mmu_mapin_ram(top)	(0UL)
 
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index 43ff3c7..c282e56 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -60,7 +60,7 @@ _GLOBAL(__tlbil_va)
 	isync
 1:	blr
 
-#elif defined(CONFIG_8xx)
+#elif defined(CONFIG_PPC_8xx)
 
 /*
  * Nothing to do for 8xx, everything is inline
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
index 1572504..8e01da6 100644
--- a/arch/powerpc/platforms/8xx/Kconfig
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -5,7 +5,6 @@ config CPM1
 choice
 	prompt "8xx Machine Type"
 	depends on PPC_8xx
-	depends on 8xx
 	default MPC885ADS
 
 config MPC8XXFADS
@@ -92,7 +91,7 @@ endmenu
 #
 
 menu "MPC8xx CPM Options"
-	depends on 8xx
+	depends on PPC_8xx
 
 # This doesn't really belong here, but it is convenient to ask
 # 8xx specific questions.
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 76483e3..6d481ff 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -391,7 +391,7 @@ config NR_CPUS
 
 config NOT_COHERENT_CACHE
 	bool
-	depends on 4xx || 8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON
+	depends on 4xx || PPC_8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON
 	default n if PPC_47x
 	default y
 
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index f7cb2a1..8c70ee1 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -54,7 +54,7 @@ obj-$(CONFIG_CPM)		+= cpm_common.o
 obj-$(CONFIG_CPM2)		+= cpm2.o cpm2_pic.o
 obj-$(CONFIG_QUICC_ENGINE)	+= cpm_common.o
 obj-$(CONFIG_PPC_DCR)		+= dcr.o
-obj-$(CONFIG_8xx)		+= mpc8xx_pic.o cpm1.o
+obj-$(CONFIG_PPC_8xx)		+= mpc8xx_pic.o cpm1.o
 obj-$(CONFIG_UCODE_PATCH)	+= micropatch.o
 
 obj-$(CONFIG_PPC_MPC512x)	+= mpc5xxx_clocks.o
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 99269c0..88f969b 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -103,7 +103,8 @@ u32 fsl_get_sys_freq(void)
 }
 EXPORT_SYMBOL(fsl_get_sys_freq);
 
-#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx)
+#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) \
+    || defined(CONFIG_PPC_8xx)
 
 static u32 brgfreq = -1;
 
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 4c5a19e..6aa94aa 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -7,7 +7,8 @@
 struct spi_device;
 
 extern phys_addr_t get_immrbase(void);
-#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx)
+#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) \
+    || defined(CONFIG_PPC_8xx)
 extern u32 get_brgfreq(void);
 extern u32 get_baudrate(void);
 #else
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index e599259..b5197b3 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1181,7 +1181,7 @@ bpt_cmds(void)
 
 	cmd = inchar();
 	switch (cmd) {
-#ifndef CONFIG_8xx
+#ifndef CONFIG_PPC_8xx
 	case 'd':	/* bd - hardware data breakpoint */
 		mode = 7;
 		cmd = inchar();
-- 
2.1.0


^ permalink raw reply related

* Re: [PATCHv2] framebuffer: don't link fb_devio into kernel image unconditionally
From: Harald Geyer @ 2015-03-12 13:43 UTC (permalink / raw)
  To: linux-fbdev

CONFIG_FB_DEFERRED_IO is defined as bool while CONFIG_FB is defined as
tristate. Currently fb_defio.o is linked into the kernel image even if
CONFIG_FB=m.

I fix this by updating the Makefile to link fb_defio.o into fb.o and thus
go into one place with the other core framebuffer code.

Signed-off-by: Harald Geyer <harald@ccbib.org>
---
changes since v1:
remove MODULE_LICENSE("GPL"); line from fb_defio.c

 drivers/video/fbdev/core/Makefile   |    2 +-
 drivers/video/fbdev/core/fb_defio.c |    2 --
 2 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
index 67f28e2..23d86a8 100644
--- a/drivers/video/fbdev/core/Makefile
+++ b/drivers/video/fbdev/core/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_FB_CMDLINE)          += fb_cmdline.o
 obj-$(CONFIG_FB)                  += fb.o
 fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
                                      modedb.o fbcvt.o
+fb-$(CONFIG_FB_DEFERRED_IO)       += fb_defio.o
 fb-objs                           := $(fb-y)
 
 obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
@@ -14,4 +15,3 @@ obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
 obj-$(CONFIG_FB_SYS_FOPS)      += fb_sys_fops.o
 obj-$(CONFIG_FB_SVGALIB)       += svgalib.o
 obj-$(CONFIG_FB_DDC)           += fb_ddc.o
-obj-$(CONFIG_FB_DEFERRED_IO)   += fb_defio.o
diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c
index 900aa4e..2082c37 100644
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -241,5 +241,3 @@ void fb_deferred_io_cleanup(struct fb_info *info)
 	mutex_destroy(&fbdefio->lock);
 }
 EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
-
-MODULE_LICENSE("GPL");
-- 
1.7.2.5


^ permalink raw reply related

* Re: [PATCH] staging: sm750fb: if else block checkpath warnings
From: Greg KH @ 2015-03-12 10:44 UTC (permalink / raw)
  To: Ragavendra BN
  Cc: sudipm.mukherjee, teddy.wang, linux-fbdev, devel, linux-kernel
In-Reply-To: <20150312103319.GA19906@localhost.localdomain>

On Thu, Mar 12, 2015 at 03:33:19AM -0700, Ragavendra BN wrote:
> Signed-off-by: Ragavendra BN <ragavendra.bn@gmail.com>
> 

This goes on the bottom of the changelog text.


> This patch fixes the coding style warnings found by checkpath.pl for
> the if else block

It also does something else, so I have to reject this.  Please be very
specific as to what you are doing here.

thanks,

greg k-h

^ permalink raw reply

* [PATCH] staging: sm750fb: if else block checkpath warnings
From: Ragavendra BN @ 2015-03-12 10:33 UTC (permalink / raw)
  To: sudipm.mukherjee, teddy.wang, gregkh, linux-fbdev, devel,
	linux-kernel

Signed-off-by: Ragavendra BN <ragavendra.bn@gmail.com>

This patch fixes the coding style warnings found by checkpath.pl for
the if else block

---
 drivers/staging/sm750fb/ddk750_chip.c |   25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c
index 2c12dd0..041a05a 100644
--- a/drivers/staging/sm750fb/ddk750_chip.c
+++ b/drivers/staging/sm750fb/ddk750_chip.c
@@ -11,7 +11,8 @@ typedef struct _pllcalparam{
 pllcalparam;
 
 
-logical_chip_type_t getChipType(){
+logical_chip_type_t getChipType()
+{
 	unsigned short physicalID;
 	char physicalRev;
 	logical_chip_type_t chip;
@@ -19,22 +20,16 @@ logical_chip_type_t getChipType(){
 	physicalID = devId750;//either 0x718 or 0x750
 	physicalRev = revId750;
 
-    if (physicalID = 0x718)
-    {
-        chip = SM718;
-    }
-    else if (physicalID = 0x750)
-    {
-        chip = SM750;
+	if (physicalID = 0x718) {
+		chip = SM718;
+	} else if (physicalID = 0x750) {
+		chip = SM750;
 		/* SM750 and SM750LE are different in their revision ID only. */
-		if (physicalRev = SM750LE_REVISION_ID){
+		if (physicalRev = SM750LE_REVISION_ID)
 			chip = SM750LE;
-		}
-    }
-    else
-    {
-        chip = SM_UNKNOWN;
-    }
+	} else {
+		chip = SM_UNKNOWN;
+	}
 
 	return chip;
 }
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH] staging: sm750fb: moved open brace next to declaration
From: Dan Carpenter @ 2015-03-12  9:50 UTC (permalink / raw)
  To: Ragavendra BN
  Cc: sudipm.mukherjee, teddy.wang, gregkh, linux-fbdev, devel,
	linux-kernel
In-Reply-To: <20150312093155.GA28806@localhost.localdomain>

On Thu, Mar 12, 2015 at 02:31:55AM -0700, Ragavendra BN wrote:
> Signed-off-by: Ragavendra BN <ragavendra.bn@gmail.com [user]>

Don't include this.  Fix your From header so it has your legal name.
Remover the [user] part.

> 
> This patch fixes the coding style warning found by checkpath.pl for the
> open braces next to declaration.

No signed-off.

> ---
>  drivers/staging/sm750fb/ddk750_chip.c |    3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c
> index b71169e..2c12dd0 100644
> --- a/drivers/staging/sm750fb/ddk750_chip.c
> +++ b/drivers/staging/sm750fb/ddk750_chip.c
> @@ -11,8 +11,7 @@ typedef struct _pllcalparam{
>  pllcalparam;
>  
>  
> -logical_chip_type_t getChipType()
> -{
> +logical_chip_type_t getChipType(){

This is not correct.  The braces were better in the original.

regards,
dan carpenter


^ permalink raw reply

* [PATCH 10/10] bindings: video: Xylon framebuffer driver binding
From: Davor Joja @ 2015-03-11 15:27 UTC (permalink / raw)
  To: linux-kernel, linux-fbdev, tomi.valkeinen, geert; +Cc: Davor Joja
In-Reply-To: <1426087631-9952-1-git-send-email-davorjoja@logicbricks.com>

Xylon framebuffer driver binding description.

Signed-off-by: Davor Joja <davorjoja@logicbricks.com>
---
 .../devicetree/bindings/video/xylon-fb.txt         | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/xylon-fb.txt

diff --git a/Documentation/devicetree/bindings/video/xylon-fb.txt b/Documentation/devicetree/bindings/video/xylon-fb.txt
new file mode 100644
index 0000000..665166f
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/xylon-fb.txt
@@ -0,0 +1,52 @@
+Binding for Xylon FB driver
+
+Xylon FB driver supports Xylon configurable video controller
+logiCVC FPGA IP core device.
+
+Required properties:
+ - compatible: value must be "xylon,fb-3.00.a"
+ - device: the phandle for logiCVC video controller device
+
+Optional properties:
+ - clocks: the phandle for the pixel clock generator
+ - console-layer: layer ID for FB console (0 - 4)
+      If omitted, FB console started on default layer ID 0.
+      Note: FB console can be started only on layer configured with one
+      of parameters combination below:
+      ===================
+      bits-per-pixel    type    transparency
+      ===================
+             8           yuv       clut32
+             8           rgb       clut16
+             8           rgb       clut32
+             8           rgb       layer
+            16           rgb       layer
+            32           rgb       layer
+            32           rgb       pixel
+      ===================
+
+ - edid-video-mode: video mode set to preferred EDID resolution
+      If omitted, configured according to "video-mode" property.
+ - edid-print: prints EDID description in system log
+      Must be used only with "edid-video-mode".
+      If omitted, functionality is not available.
+ - vsync-irq: generate interrupt on vertical synchronization pulse
+ - video-mode: preferred video mode resolution
+      If omitted, configures logiCVC to default video resolution "1024x768".
+   - M: Coordinated Video Timings (CVT)
+   - R: reduced video timings for digital displays
+   - i: calculate for an interlaced mode
+   - m: add margins to calculation calculation
+        (1.8% of xres rounded down to 8 pixels and 1.8% of yres).
+Example:
+
+	xylon_fb {
+		compatible = "xylon,fb-3.00.a";
+		clocks = <&clkout_0>;
+		device = <&logicvc_0>;
+		console-layer = <0>;
+		edid-video-mode;
+		edid-print;
+		vsync-irq;
+		video-mode = "1920x1080MR";
+	};
\ No newline at end of file
-- 
1.9.1


^ permalink raw reply related

* [PATCH 09/10] bindings: video: Xylon logiCVC IP core device binding
From: Davor Joja @ 2015-03-11 15:27 UTC (permalink / raw)
  To: linux-kernel, linux-fbdev, tomi.valkeinen, geert; +Cc: Davor Joja
In-Reply-To: <1426087631-9952-1-git-send-email-davorjoja@logicbricks.com>

Xylon logiCVC IP core binding description.

Signed-off-by: Davor Joja <davorjoja@logicbricks.com>
---
 .../devicetree/bindings/video/xylon-logicvc.txt    | 207 +++++++++++++++++++++
 1 file changed, 207 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/xylon-logicvc.txt

diff --git a/Documentation/devicetree/bindings/video/xylon-logicvc.txt b/Documentation/devicetree/bindings/video/xylon-logicvc.txt
new file mode 100644
index 0000000..d49c574
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/xylon-logicvc.txt
@@ -0,0 +1,207 @@
+Binding for Xylon logiCVC configurable video controller IP core
+
+Required properties:
+ - compatible: "xylon,logicvc-3.00.a", "xylon,logicvc-4.00.a"
+ - reg: MMIO base address and size of the logiCVC IP core address space
+ - interrupts-parent: the phandle for interrupt controller
+ - interrupts: the interrupt number
+ - pixel-stride: layer width in pixels
+      Common for all available logiCVC standard layers.
+
+ - layer_N: layer has its own configuration described with below properties,
+      where N is layer ID in range 0 - 4
+   - bits-per-pixel: layer bits per pixel configuration (8, 16, 32)
+         Layer is configured to be used with specified pixel width in bits.
+         Pixels written to layer video memory must match in size to configured
+         "bits-per-pixel" value.
+         Note: Allowed "transparency" for values of "bits-per-pixel":
+
+         =======================+             bits-per-pixel             transparency
+         =======================+                   8                       clut16
+                   8                       clut32
+                   8                       layer
+                   16                      layer
+                   32                      layer, pixel
+         =======================+
+   - type: layer type (rgb, yuv, alpha)
+         Layer is configured to be used with specified color space.
+         Pixels written to layer video memory must match specified color format.
+         Type is set to "alpha" if layer contains only pixel alpha values
+         used by layer above. Permitted layer IDs for configuring layer alpha
+         are 1 and 3.
+   - transparency: layer transparency (clut16, clut32, layer, pixel)
+         logiCVC layer can be configured to have transparency control on
+         CLUT, layer or pixel level.
+         "CLUT" mode enables controlling of layer transparency by changing
+         alpha value in logiCVC CLUT registers.
+         "Layer" mode enables controlling of layer transparency by changing
+         alpha value in single logiCVC register.
+         "Pixel" mode enables controlling of pixel transparency by changing
+         dedicated alpha bits of specific pixel in video memory.
+         Note: "transparency" property is not used if "type" property is set
+         to "alpha".
+
+Optional properties:
+ - background-layer-bits-per-pixel: background layer bits per pixel (8, 16, 32)
+      If omitted, last available layer is logiCVC standard layer, which has its
+      own video memory of specific size, color format and specified
+      bits per pixel.
+      If 8, 16 or 32, last available layer is logiCVC background layer,
+      with only specified bits per pixel value.
+ - background-layer-type: background layer type (rgb, yuv)
+      Must be used only when "background-layer-bits-per-pixel" exist.
+      If set to "rgb", in case of 32 bits per pixel, background color register
+      must be written with XRGB8888 value. In case of 16 bits per pixel,
+      background color register must be written with RGB565 value.
+      If set to "yuv", background color register must be written with XYUV8888
+      value.
+ - hsync-active-low: horizontal synchronization pulse is active low "L"
+      If omitted, generated horizontal synchronization pulse polarity is logic
+      high "H".
+ - vsync-active-low: vertical synchronization pulse is active low "L"
+      If omitted, generated vertical synchronization pulse polarity is logic
+      high "H".
+ - pixel-data-invert: output pixel data polarity is inverted
+      If omitted, logiCVC outputs pixel data at default interface polarity.
+ - pixel-data-output-trigger-high: output pixel data triggers on rising edge
+      If omitted, logiCVC outputs pixel data on falling edge of pixel clock.
+ - readable-regs: all logiCVC registers are available for reading
+      If omitted, only Interrupt Status, Power Control and IP Version registers
+      are available for reading.
+ - size-position: logiCVC functionality for controlling on screen layer size
+      and position available
+      If omitted, functionality not available.
+ - component-swap: swap the order of colour components inside the pixel
+ - data-enable-active-low: data enable signal is active low "L"
+      If omitted, generated data enable polarity is logic high "H".
+ - display-interface-itu656: modifies RGB to YUV conversion coefficients
+ - address: layer video memory address for layer_N where
+      N is layer ID in range 0 - 4.
+      logiCVC can be configured to have layer video memory address hardcoded
+      as layer register reset value. This video memory is not part of the system
+      memory. Still it is accessible by CPU and HW devices.
+      If omitted, layer video memory address is set dynamically by
+      device driver.Layer video memory address can be changed dynamically
+      despite the hardcoded address.
+      Note: Additionally, address range parameter can be set. It defines range
+      of video memory in bytes starting from provided address. It is mandatory
+      for physically last layer in memory. If range parameter is omitted for
+      physically last layer, range will be by default set to 2048 lines.
+      If omitted for any other layer then physically last layer,
+      range will be calculated according to address of next physical layer.
+ - buffer-offset: buffer address offset represented in number of lines
+      Used only for HW buffer switching.
+      If omitted, buffer offset variable is by default set to "0".
+ - power-delay: delay in ms after enabling display power supply
+      If omitted, delay is by default set to "0".
+ - signal-delay: delay in ms after enabling display control and data signals
+      in parallel and LVDS interface
+      If omitted, delay is by default set to "0".
+ - display-timings: custom display video mode timing parameters
+      If omitted, driver will use its default video mode timings.
+      native-mode optional parameter determines which video mode timings from
+      the list are used. If native-mode parameter is omitted, first available
+      video mode timings are used.
+
+Example:
+
+	logicvc_0: logicvc@40000000 {
+		compatible = "xylon,logicvc-4.00.a";
+		reg = <0x40030000 0x6000>;
+		interrupt-parent = <&ps7_scugic_0>;
+		interrupts = <0 59 4>;
+		background-layer-bits-per-pixel = <32>;
+		background-layer-type = "rgb";
+		display-interface-itu656;
+		hsync-active-low;
+		vsync-active-low;
+		data-enable-active-low;
+		pixel-data-invert;
+		pixel-data-output-trigger-high;
+		readable-regs;
+		size-position;
+		pixel-stride = <2048>;
+		power-delay = <100>;
+		signal-delay = <50>;
+		layer_0 {
+			address = <0x30000000>
+			buffer-offset = <512>;
+			bits-per-pixel = <16>;
+			type = "yuv";
+			transparency = "layer";
+			component-swap;
+		};
+		layer_1 {
+			address = <0x30600000>;
+			bits-per-pixel = <32>;
+			type = "rgb";
+			transparency = "pixel";
+		};
+		layer_2 {
+			address = <0x31F50000>;
+			bits-per-pixel = <8>;
+			type = "rgb";
+			transparency = "clut32";
+		};
+		layer_3 {
+			address = <0x3216C000 0xCA8000>;
+			bits-per-pixel = <16>;
+			type = "rgb";
+			transparency = "layer";
+		};
+
+		display-timings {
+			native-mode = <&wsxga>;
+			hd720p: 1280x720 {
+				clock-frequency = <74250000>;
+				hactive = <1280>;
+				vactive = <720>;
+				hfront-porch = <110>;
+				hback-porch = <220>;
+				hsync-len = <40>;
+				vfront-porch = <5>;
+				vback-porch = <20>;
+				vsync-len = <5>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <1>;
+				pixelclk-active = <1>;
+			};
+			wsxga: 1680x1050 {
+				clock-frequency = <119000000>;
+				hactive = <1680>;
+				vactive = <1050>;
+				hfront-porch = <48>;
+				hback-porch = <80>;
+				hsync-len = <32>;
+				vfront-porch = <3>;
+				vback-porch = <21>;
+				vsync-len = <6>;
+			};
+			hd1080p: 1920x1080 {
+				clock-frequency = <148500000>;
+				hactive = <1920>;
+				vactive = <1080>;
+				hfront-porch = <88>;
+				hback-porch = <148>;
+				hsync-len = <44>;
+				vfront-porch = <4>;
+				vback-porch = <36>;
+				vsync-len = <5>;
+			};
+			TM050RBH01: 800x480 {
+				clock-frequency = <30000000>;
+				hactive = <800>;
+				vactive = <480>;
+				hfront-porch = <40>;
+				hback-porch = <40>;
+				hsync-len = <48>;
+				vfront-porch = <13>;
+				vback-porch = <29>;
+				vsync-len = <3>;
+			};
+		};
+	};
-- 
1.9.1


^ permalink raw reply related

* [PATCH 08/10] fbdev: Xylon framebuffer driver to fbdev Kconfig and Makefile
From: Davor Joja @ 2015-03-11 15:27 UTC (permalink / raw)
  To: linux-kernel, linux-fbdev, tomi.valkeinen, geert; +Cc: Davor Joja
In-Reply-To: <1426087631-9952-1-git-send-email-davorjoja@logicbricks.com>

Adding Xylon framebuffer driver to fbdev Kconfig and Makefile.

Signed-off-by: Davor Joja <davorjoja@logicbricks.com>
---
 drivers/video/fbdev/Kconfig  | 1 +
 drivers/video/fbdev/Makefile | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index b3dd417..3bd0693 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -2454,6 +2454,7 @@ source "drivers/video/fbdev/omap/Kconfig"
 source "drivers/video/fbdev/omap2/Kconfig"
 source "drivers/video/fbdev/exynos/Kconfig"
 source "drivers/video/fbdev/mmp/Kconfig"
+source "drivers/video/fbdev/xylon/Kconfig"
 
 config FB_SH_MOBILE_MERAM
 	tristate "SuperH Mobile MERAM read ahead support"
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 1979aff..57cb259 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -132,6 +132,7 @@ obj-$(CONFIG_FB_JZ4740)		  += jz4740_fb.o
 obj-$(CONFIG_FB_PUV3_UNIGFX)      += fb-puv3.o
 obj-$(CONFIG_FB_HYPERV)		  += hyperv_fb.o
 obj-$(CONFIG_FB_OPENCORES)	  += ocfb.o
+obj-$(CONFIG_FB_XYLON)		  += xylon/
 
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_UVESA)            += uvesafb.o
-- 
1.9.1


^ permalink raw reply related

* [PATCH 07/10] uapi: linux: Xylon framebuffer driver header file
From: Davor Joja @ 2015-03-11 15:27 UTC (permalink / raw)
  To: linux-kernel, linux-fbdev, tomi.valkeinen, geert; +Cc: Davor Joja
In-Reply-To: <1426087631-9952-1-git-send-email-davorjoja@logicbricks.com>

Driver header file containing structures and IOCTLs for user space
applications to be able to use advanced logiCVC hw functionality.

Signed-off-by: Davor Joja <davorjoja@logicbricks.com>
---
 include/uapi/linux/xylonfb.h | 85 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 include/uapi/linux/xylonfb.h

diff --git a/include/uapi/linux/xylonfb.h b/include/uapi/linux/xylonfb.h
new file mode 100644
index 0000000..662c02f
--- /dev/null
+++ b/include/uapi/linux/xylonfb.h
@@ -0,0 +1,85 @@
+/*
+ * Xylon logiCVC frame buffer driver IOCTL parameters
+ *
+ * Copyright (C) 2015 Xylon d.o.o.
+ * Author: Davor Joja <davor.joja@logicbricks.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __XYLONFB_H__
+#define __XYLONFB_H__
+
+#include <linux/types.h>
+
+struct xylonfb_hw_access {
+	__u32 offset;
+	__u32 value;
+	bool set;
+};
+
+/* Used only with logiCVC 3.x */
+struct xylonfb_layer_buffer {
+	__u8 id;
+	bool set;
+};
+
+struct xylonfb_layer_color {
+	__u32 raw_rgb;
+	__u8 use_raw;
+	__u8 r;
+	__u8 g;
+	__u8 b;
+	bool set;
+};
+
+struct xylonfb_layer_geometry {
+	__u16 x;
+	__u16 y;
+	__u16 width;
+	__u16 height;
+	__u16 x_offset;
+	__u16 y_offset;
+	bool set;
+};
+
+struct xylonfb_layer_transparency {
+	__u8 alpha;
+	bool set;
+};
+
+/* Xylon FB IOCTL's */
+#define XYLONFB_IOW(num, dtype)		_IOW('x', num, dtype)
+#define XYLONFB_IOR(num, dtype)		_IOR('x', num, dtype)
+#define XYLONFB_IOWR(num, dtype)	_IOWR('x', num, dtype)
+#define XYLONFB_IO(num)			_IO('x', num)
+
+#define XYLONFB_VSYNC_CTRL		XYLONFB_IOR(30, bool)
+#define XYLONFB_LAYER_IDX		XYLONFB_IOR(31, unsigned int)
+#define XYLONFB_LAYER_ALPHA		\
+	XYLONFB_IOR(32, struct xylonfb_layer_transparency)
+#define XYLONFB_LAYER_COLOR_TRANSP_CTRL	XYLONFB_IOW(33, bool)
+#define XYLONFB_LAYER_COLOR_TRANSP \
+	XYLONFB_IOR(34, struct xylonfb_layer_color)
+#define XYLONFB_LAYER_GEOMETRY \
+	XYLONFB_IOR(35, struct xylonfb_layer_geometry)
+#define XYLONFB_LAYER_BUFFER \
+	XYLONFB_IOR(36, struct xylonfb_layer_buffer)
+#define XYLONFB_LAYER_BUFFER_OFFSET	XYLONFB_IOR(37, unsigned int)
+#define XYLONFB_BACKGROUND_COLOR \
+	XYLONFB_IOR(38, struct xylonfb_layer_color)
+#define XYLONFB_LAYER_EXT_BUFF_SWITCH	XYLONFB_IOW(39, bool)
+#define XYLONFB_HW_ACCESS \
+	XYLONFB_IOR(40, struct xylonfb_hw_access)
+#define XYLONFB_IP_CORE_VERSION		XYLONFB_IOR(41, __u32)
+#define XYLONFB_WAIT_EDID		XYLONFB_IOW(42, unsigned int)
+#define XYLONFB_GET_EDID		XYLONFB_IOR(43, char)
+
+#endif /* __XYLONFB_H__ */
-- 
1.9.1


^ permalink raw reply related

* [PATCH 06/10] fbdev: xylon: Framebuffer driver kernel and make configuration
From: Davor Joja @ 2015-03-11 15:27 UTC (permalink / raw)
  To: linux-kernel, linux-fbdev, tomi.valkeinen, geert; +Cc: Davor Joja
In-Reply-To: <1426087631-9952-1-git-send-email-davorjoja@logicbricks.com>

Driver kernel and build configuration.

Signed-off-by: Davor Joja <davorjoja@logicbricks.com>
---
 drivers/video/fbdev/xylon/Kconfig  | 31 +++++++++++++++++++++++++++++++
 drivers/video/fbdev/xylon/Makefile |  3 +++
 2 files changed, 34 insertions(+)
 create mode 100644 drivers/video/fbdev/xylon/Kconfig
 create mode 100644 drivers/video/fbdev/xylon/Makefile

diff --git a/drivers/video/fbdev/xylon/Kconfig b/drivers/video/fbdev/xylon/Kconfig
new file mode 100644
index 0000000..74278ad
--- /dev/null
+++ b/drivers/video/fbdev/xylon/Kconfig
@@ -0,0 +1,31 @@
+menuconfig FB_XYLON
+	tristate "Xylon logiCVC frame buffer support"
+	depends on FB
+	default n
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+	help
+	  Choose this option if you want to use the Xylon logiCVC as frame
+	  buffer device. Without the support of PCI & AGP.
+
+config FB_XYLON_PIXCLK
+	bool "Xylon logiCVC pixel clock"
+	depends on FB_XYLON
+	default n
+	help
+	  logiCVC pixel clock generated from:
+	  - External generator not controllable by Xylon framebuffer driver
+	    This is default selection.
+	  - Generators controllable by Xylon framebuffer driver
+
+config FB_XYLON_PIXCLK_LOGICLK
+	bool "Xylon logiCLK pixel clock generator"
+	depends on FB_XYLON && FB_XYLON_PIXCLK
+	default n
+	select COMMON_CLK_LOGICLK
+	help
+	  Support for controlling pixel clock generation from
+	  Xylon logiCLK FGPA IP core.
diff --git a/drivers/video/fbdev/xylon/Makefile b/drivers/video/fbdev/xylon/Makefile
new file mode 100644
index 0000000..3baa96a
--- /dev/null
+++ b/drivers/video/fbdev/xylon/Makefile
@@ -0,0 +1,3 @@
+xylonfb-y := xylonfb_main.o xylonfb_core.o xylonfb_ioctl.o xylonfb_pixclk.o
+
+obj-$(CONFIG_FB_XYLON) += xylonfb.o
-- 
1.9.1


^ permalink raw reply related

* [PATCH 05/10] fbdev: xylon: logiCVC IP core definitions
From: Davor Joja @ 2015-03-11 15:27 UTC (permalink / raw)
  To: linux-kernel, linux-fbdev, tomi.valkeinen, geert; +Cc: Davor Joja
In-Reply-To: <1426087631-9952-1-git-send-email-davorjoja@logicbricks.com>

Driver hw parameters and definitions for logiCVC IP core.

Signed-off-by: Davor Joja <davorjoja@logicbricks.com>
---
 drivers/video/fbdev/xylon/logicvc.h | 192 ++++++++++++++++++++++++++++++++++++
 1 file changed, 192 insertions(+)
 create mode 100644 drivers/video/fbdev/xylon/logicvc.h

diff --git a/drivers/video/fbdev/xylon/logicvc.h b/drivers/video/fbdev/xylon/logicvc.h
new file mode 100644
index 0000000..7c1266e
--- /dev/null
+++ b/drivers/video/fbdev/xylon/logicvc.h
@@ -0,0 +1,192 @@
+/*
+ * Xylon logiCVC IP core parameters
+ *
+ * Copyright (C) 2015 Xylon d.o.o.
+ * Author: Davor Joja <davor.joja@logicbricks.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LOGICVC_H__
+#define __LOGICVC_H__
+
+/*
+ * All logiCVC registers are only 32-bit accessible.
+ * All logiCVC registers are aligned to 8 byte boundary.
+ */
+#define LOGICVC_REG_STRIDE		8
+#define LOGICVC_HSYNC_FRONT_PORCH_ROFF	(0  * LOGICVC_REG_STRIDE)
+#define LOGICVC_HSYNC_ROFF		(1  * LOGICVC_REG_STRIDE)
+#define LOGICVC_HSYNC_BACK_PORCH_ROFF	(2  * LOGICVC_REG_STRIDE)
+#define LOGICVC_HRES_ROFF		(3  * LOGICVC_REG_STRIDE)
+#define LOGICVC_VSYNC_FRONT_PORCH_ROFF	(4  * LOGICVC_REG_STRIDE)
+#define LOGICVC_VSYNC_ROFF		(5  * LOGICVC_REG_STRIDE)
+#define LOGICVC_VSYNC_BACK_PORCH_ROFF	(6  * LOGICVC_REG_STRIDE)
+#define LOGICVC_VRES_ROFF		(7  * LOGICVC_REG_STRIDE)
+#define LOGICVC_CTRL_ROFF		(8  * LOGICVC_REG_STRIDE)
+#define LOGICVC_DTYPE_ROFF		(9  * LOGICVC_REG_STRIDE)
+#define LOGICVC_BACKGROUND_COLOR_ROFF	(10 * LOGICVC_REG_STRIDE)
+#define LOGICVC_CLUT_SELECT_ROFF	(12 * LOGICVC_REG_STRIDE)
+#define LOGICVC_INT_STAT_ROFF		(13 * LOGICVC_REG_STRIDE)
+#define LOGICVC_INT_MASK_ROFF		(14 * LOGICVC_REG_STRIDE)
+#define LOGICVC_POWER_CTRL_ROFF		(15 * LOGICVC_REG_STRIDE)
+#define LOGICVC_IP_VERSION_ROFF		(31 * LOGICVC_REG_STRIDE)
+/* Version 3.x */
+#define LOGICVC_VBUFF_SELECT_ROFF	(11 * LOGICVC_REG_STRIDE)
+
+/*
+ * logiCVC layer registers offsets (common for each layer)
+ * Last possible logiCVC layer (No.4) implements only "Layer memory address"
+ * and "Layer control" registers.
+ */
+/* Version 3.x */
+#define LOGICVC_LAYER_HOFF_ROFF		(0 * LOGICVC_REG_STRIDE)
+#define LOGICVC_LAYER_VOFF_ROFF		(1 * LOGICVC_REG_STRIDE)
+/* Version 4.x */
+#define LOGICVC_LAYER_ADDR_ROFF		(0 * LOGICVC_REG_STRIDE)
+/* Common */
+#define LOGICVC_LAYER_HPOS_ROFF		(2 * LOGICVC_REG_STRIDE)
+#define LOGICVC_LAYER_VPOS_ROFF		(3 * LOGICVC_REG_STRIDE)
+#define LOGICVC_LAYER_HSIZE_ROFF	(4 * LOGICVC_REG_STRIDE)
+#define LOGICVC_LAYER_VSIZE_ROFF	(5 * LOGICVC_REG_STRIDE)
+#define LOGICVC_LAYER_ALPHA_ROFF	(6 * LOGICVC_REG_STRIDE)
+#define LOGICVC_LAYER_CTRL_ROFF		(7 * LOGICVC_REG_STRIDE)
+#define LOGICVC_LAYER_TRANSP_COLOR_ROFF	(8 * LOGICVC_REG_STRIDE)
+
+/* logiCVC interrupt bits */
+#define LOGICVC_INT_L0_UPDATED		(1 << 0)
+#define LOGICVC_INT_L1_UPDATED		(1 << 1)
+#define LOGICVC_INT_L2_UPDATED		(1 << 2)
+#define LOGICVC_INT_L3_UPDATED		(1 << 3)
+#define LOGICVC_INT_L4_UPDATED		(1 << 4)
+#define LOGICVC_INT_V_SYNC		(1 << 5)
+#define LOGICVC_INT_E_VIDEO_VALID	(1 << 6)
+#define LOGICVC_INT_FIFO_UNDERRUN	(1 << 7)
+#define LOGICVC_INT_L0_CLUT_SW		(1 << 8)
+#define LOGICVC_INT_L1_CLUT_SW		(1 << 9)
+#define LOGICVC_INT_L2_CLUT_SW		(1 << 10)
+#define LOGICVC_INT_L3_CLUT_SW		(1 << 11)
+#define LOGICVC_INT_L4_CLUT_SW		(1 << 12)
+
+/* logiCVC layer base offsets */
+#define LOGICVC_LAYER_OFFSET		0x80
+#define LOGICVC_LAYER_BASE_OFFSET	0x100
+#define LOGICVC_LAYER_BASE_END		0x338
+#define LOGICVC_LAYER_0_OFFSET		(0 * LOGICVC_LAYER_OFFSET)
+#define LOGICVC_LAYER_1_OFFSET		(1 * LOGICVC_LAYER_OFFSET)
+#define LOGICVC_LAYER_2_OFFSET		(2 * LOGICVC_LAYER_OFFSET)
+#define LOGICVC_LAYER_3_OFFSET		(3 * LOGICVC_LAYER_OFFSET)
+#define LOGICVC_LAYER_4_OFFSET		(4 * LOGICVC_LAYER_OFFSET)
+
+/* logiCVC layer CLUT base offsets */
+#define LOGICVC_CLUT_OFFSET		0x800
+#define LOGICVC_CLUT_BASE_OFFSET	0x1000
+#define LOGICVC_CLUT_L0_CLUT_0_OFFSET	(0 * LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L0_CLUT_1_OFFSET	(1 * LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L1_CLUT_0_OFFSET	(2 * LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L1_CLUT_1_OFFSET	(3 * LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L2_CLUT_0_OFFSET	(4 * LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L2_CLUT_1_OFFSET	(5 * LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L3_CLUT_0_OFFSET	(6 * LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L3_CLUT_1_OFFSET	(7 * LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L4_CLUT_0_OFFSET	(8 * LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_L4_CLUT_1_OFFSET	(9 * LOGICVC_CLUT_OFFSET)
+#define LOGICVC_CLUT_REGISTER_SIZE	8
+#define LOGICVC_CLUT_0_INDEX_OFFSET	2
+#define LOGICVC_CLUT_1_INDEX_OFFSET	1
+
+/* logiCVC registers range */
+#define LOGICVC_REGISTERS_RANGE		0x6000
+#define LOGICVC_LAYER_REGISTERS_RANGE	0x80
+
+/* logiCVC control register bits */
+#define LOGICVC_CTRL_HSYNC			(1 << 0)
+#define LOGICVC_CTRL_HSYNC_INVERT		(1 << 1)
+#define LOGICVC_CTRL_VSYNC			(1 << 2)
+#define LOGICVC_CTRL_VSYNC_INVERT		(1 << 3)
+#define LOGICVC_CTRL_DATA_ENABLE		(1 << 4)
+#define LOGICVC_CTRL_DATA_ENABLE_INVERT		(1 << 5)
+#define LOGICVC_CTRL_PIXEL_DATA_INVERT		(1 << 7)
+#define LOGICVC_CTRL_PIXEL_DATA_TRIGGER_INVERT	(1 << 8)
+#define LOGICVC_CTRL_DISABLE_LAYER_UPDATE	(1 << 9)
+
+/* logiCVC layer control register bits */
+#define LOGICVC_LAYER_CTRL_ENABLE			(1 << 0)
+#define LOGICVC_LAYER_CTRL_COLOR_TRANSPARENCY_DISABLE	(1 << 1)
+#define LOGICVC_LAYER_CTRL_EXTERNAL_BUFFER_SWITCH	(1 << 2)
+#define LOGICVC_LAYER_CTRL_INTERLACE		(1 << 3)
+#define LOGICVC_LAYER_CTRL_PIXEL_FORMAT_ABGR	(1 << 4)
+
+/* logiCVC register initial values */
+#define LOGICVC_DTYPE_REG_INIT	0
+
+/* logiCVC display power signals */
+#define LOGICVC_EN_BLIGHT_MSK	(1 << 0)
+#define LOGICVC_EN_VDD_MSK	(1 << 1)
+#define LOGICVC_EN_VEE_MSK	(1 << 2)
+#define LOGICVC_V_EN_MSK	(1 << 3)
+
+/* logiCVC various definitions */
+#define LOGICVC_MAJOR_REVISION_SHIFT	11
+#define LOGICVC_MAJOR_REVISION_MASK	0x3F
+#define LOGICVC_MINOR_REVISION_SHIFT	5
+#define LOGICVC_MINOR_REVISION_MASK	0x3F
+#define LOGICVC_PATCH_LEVEL_MASK	0x1F
+
+#define LOGICVC_MAX_LAYER_BUFFERS	3
+#define LOGICVC_MIN_XRES		64
+#define LOGICVC_MIN_VRES		1
+#define LOGICVC_MAX_XRES		2048
+#define LOGICVC_MAX_VRES		2048
+#define LOGICVC_CLUT_SIZE		256
+
+#define LOGICVC_COEFF_Y_R		29900
+#define LOGICVC_COEFF_Y_G		58700
+#define LOGICVC_COEFF_Y_B		11400
+#define LOGICVC_COEFF_Y			0
+#define LOGICVC_COEFF_U			12800000
+#define LOGICVC_COEFF_V			12800000
+#define LOGICVC_COEFF_U_R		16868
+#define LOGICVC_COEFF_U_G		33107
+#define LOGICVC_COEFF_U_B		49970
+#define LOGICVC_COEFF_V_R		49980
+#define LOGICVC_COEFF_V_G		41850
+#define LOGICVC_COEFF_V_B		8128
+#define LOGICVC_COEFF_ITU656_Y		1600000
+#define LOGICVC_COEFF_ITU656_U_R	17258
+#define LOGICVC_COEFF_ITU656_U_G	33881
+#define LOGICVC_COEFF_ITU656_U_B	51140
+#define LOGICVC_COEFF_ITU656_V_R	51138
+#define LOGICVC_COEFF_ITU656_V_G	42820
+#define LOGICVC_COEFF_ITU656_V_B	8316
+#define LOGICVC_YUV_NORM		100000
+#define LOGICVC_COEFF_R_U		1402524
+#define LOGICVC_COEFF_R			179000000
+#define LOGICVC_COEFF_G_U		714403
+#define LOGICVC_COEFF_G_V		344340
+#define LOGICVC_COEFF_G			135000000
+#define LOGICVC_COEFF_B_V		1773049
+#define LOGICVC_COEFF_B			226000000
+#define LOGICVC_RGB_NORM		1000000
+
+enum xylonfb_layer_type {
+	LOGICVC_LAYER_RGB,
+	LOGICVC_LAYER_YUV,
+	LOGICVC_LAYER_ALPHA
+};
+
+enum xylonfb_alpha_type {
+	LOGICVC_ALPHA_LAYER,
+	LOGICVC_ALPHA_PIXEL,
+	LOGICVC_ALPHA_CLUT_16BPP,
+	LOGICVC_ALPHA_CLUT_32BPP
+};
+
+#endif /* __LOGICVC_H__ */
-- 
1.9.1


^ permalink raw reply related

* [PATCH 04/10] fbdev: xylon: Framebuffer driver pixel clock
From: Davor Joja @ 2015-03-11 15:27 UTC (permalink / raw)
  To: linux-kernel, linux-fbdev, tomi.valkeinen, geert; +Cc: Davor Joja
In-Reply-To: <1426087631-9952-1-git-send-email-davorjoja@logicbricks.com>

Driver pixel clock control functionality supporting optional Xylon logiCLK IP
core clock generator.

Signed-off-by: Davor Joja <davorjoja@logicbricks.com>
---
 drivers/video/fbdev/xylon/xylonfb_pixclk.c | 119 +++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)
 create mode 100644 drivers/video/fbdev/xylon/xylonfb_pixclk.c

diff --git a/drivers/video/fbdev/xylon/xylonfb_pixclk.c b/drivers/video/fbdev/xylon/xylonfb_pixclk.c
new file mode 100644
index 0000000..d63dbeb
--- /dev/null
+++ b/drivers/video/fbdev/xylon/xylonfb_pixclk.c
@@ -0,0 +1,119 @@
+/*
+ * Xylon logiCVC frame buffer driver pixel clock control
+ *
+ * Copyright (C) 2015 Xylon d.o.o.
+ * Author: Davor Joja <davor.joja@logicbricks.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+struct xylonfb_pixclk {
+	struct device *dev;
+	struct device_node *dn;
+	struct clk *clk;
+};
+
+#if defined(CONFIG_FB_XYLON_PIXCLK_LOGICLK)
+static const struct of_device_id logiclk_of_match[] = {
+	{ .compatible = "xylon,logiclk-1.02.b" },
+	{/* end of table */}
+};
+static struct xylonfb_pixclk logiclk;
+#endif
+
+bool xylonfb_hw_pixclk_supported(struct device *dev, struct device_node *dn);
+void xylonfb_hw_pixclk_unload(struct device_node *dn);
+int xylonfb_hw_pixclk_set(struct device *dev, struct device_node *dn,
+			  unsigned long pixclk_khz);
+
+#if defined(CONFIG_FB_XYLON_PIXCLK)
+static int xylonfb_hw_pixclk_set_freq(struct device *dev,
+				      struct device_node *dn,
+				      unsigned long freq_khz)
+{
+	struct clk *clk = NULL;
+
+#if defined(CONFIG_FB_XYLON_PIXCLK_LOGICLK)
+	if (dn = logiclk.dn)
+		clk = logiclk.clk;
+#endif
+
+	if (clk && clk_set_rate(clk, (freq_khz * 1000))) {
+		dev_err(dev, "failed set pixel clock frequency\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif
+
+bool xylonfb_hw_pixclk_supported(struct device *dev, struct device_node *dn)
+{
+#if defined(CONFIG_FB_XYLON_PIXCLK)
+	struct clk **clk;
+	bool clk_dev = false;
+
+#if defined(CONFIG_FB_XYLON_PIXCLK_LOGICLK)
+	if (of_match_node(logiclk_of_match, of_get_parent(dn))) {
+		clk = &logiclk.clk;
+		logiclk.dev = dev;
+		logiclk.dn = dn;
+		clk_dev = true;
+	}
+#endif
+
+	if (clk_dev) {
+		*clk = devm_clk_get(dev, NULL);
+		if (IS_ERR(*clk)) {
+			dev_err(dev, "failed get pixel clock\n");
+			return false;
+		}
+		if (clk_prepare_enable(*clk)) {
+			dev_err(dev,
+				"failed prepare/enable pixel clock\n");
+			return false;
+		}
+
+		return true;
+	} else {
+		return false;
+	}
+#else
+	return true;
+#endif
+}
+
+void xylonfb_hw_pixclk_unload(struct device_node *dn)
+{
+	struct clk *clk = NULL;
+
+#if defined(CONFIG_FB_XYLON_PIXCLK_LOGICLK)
+	clk = logiclk.clk;
+#endif
+
+	if (clk)
+		clk_disable_unprepare(clk);
+}
+
+int xylonfb_hw_pixclk_set(struct device *dev, struct device_node *dn,
+			  unsigned long pixclk_khz)
+{
+#if defined(CONFIG_FB_XYLON_PIXCLK)
+	return xylonfb_hw_pixclk_set_freq(dev, dn, pixclk_khz);
+#else
+	dev_warn(dev, "pixel clock control not supported\n");
+	return -ENODEV;
+#endif
+}
-- 
1.9.1


^ permalink raw reply related

* [PATCH 03/10] fbdev: xylon: Framebuffer driver ioctl
From: Davor Joja @ 2015-03-11 15:27 UTC (permalink / raw)
  To: linux-kernel, linux-fbdev, tomi.valkeinen, geert; +Cc: Davor Joja
In-Reply-To: <1426087631-9952-1-git-send-email-davorjoja@logicbricks.com>

Driver IOCTL providing advanced video controller functionality used by user
space applications.

Signed-off-by: Davor Joja <davorjoja@logicbricks.com>
---
 drivers/video/fbdev/xylon/xylonfb_ioctl.c | 672 ++++++++++++++++++++++++++++++
 1 file changed, 672 insertions(+)
 create mode 100644 drivers/video/fbdev/xylon/xylonfb_ioctl.c

diff --git a/drivers/video/fbdev/xylon/xylonfb_ioctl.c b/drivers/video/fbdev/xylon/xylonfb_ioctl.c
new file mode 100644
index 0000000..131bdcf
--- /dev/null
+++ b/drivers/video/fbdev/xylon/xylonfb_ioctl.c
@@ -0,0 +1,672 @@
+/*
+ * Xylon logiCVC frame buffer driver IOCTL functionality
+ *
+ * Copyright (C) 2015 Xylon d.o.o.
+ * Author: Davor Joja <davor.joja@logicbricks.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <uapi/linux/xylonfb.h>
+
+#include "logicvc.h"
+#include "xylonfb_core.h"
+
+static int xylonfb_get_vblank(struct fb_vblank *vblank, struct fb_info *fbi)
+{
+	vblank->flags |= FB_VBLANK_HAVE_VSYNC;
+
+	return 0;
+}
+
+static void xylonfb_vsync_ctrl(struct fb_info *fbi, bool enable)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	u32 imr;
+
+	mutex_lock(&data->irq_mutex);
+
+	imr = data->reg_access.get_reg_val(data->dev_base,
+					   LOGICVC_INT_MASK_ROFF, ld);
+	if (enable) {
+		imr &= (~LOGICVC_INT_V_SYNC);
+		writel(LOGICVC_INT_V_SYNC,
+		       data->dev_base + LOGICVC_INT_STAT_ROFF);
+	} else {
+		imr |= LOGICVC_INT_V_SYNC;
+	}
+
+	data->reg_access.set_reg_val(imr, data->dev_base,
+				     LOGICVC_INT_MASK_ROFF, ld);
+
+	mutex_unlock(&data->irq_mutex);
+}
+
+int xylonfb_vsync_wait(u32 crt, struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	int ret, count;
+
+	mutex_lock(&data->irq_mutex);
+
+	count = data->vsync.count;
+
+	ret = wait_event_interruptible_timeout(data->vsync.wait,
+					       (count != data->vsync.count),
+					       HZ/10);
+
+	mutex_unlock(&data->irq_mutex);
+
+	if (ret < 0)
+		return ret;
+	else if (ret = 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static unsigned int alpha_normalized(unsigned int alpha, unsigned int used_bits,
+				     bool set)
+{
+	if (set)
+		return alpha / (255 / ((1 << used_bits) - 1));
+	else
+		return (((255 << 16) / ((1 << used_bits) - 1)) * alpha) >> 16;
+}
+
+static int xylonfb_layer_alpha(struct xylonfb_layer_data *ld, u8 *alpha,
+			       bool set)
+{
+	struct xylonfb_data *data = ld->data;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+	unsigned int used_bits;
+	u32 val;
+
+	if (fd->transparency != LOGICVC_ALPHA_LAYER)
+		return -EPERM;
+
+	switch (fd->type) {
+	case LOGICVC_LAYER_YUV:
+		used_bits = 8;
+		break;
+	case LOGICVC_LAYER_RGB:
+		switch (fd->bpp) {
+		case 8:
+			used_bits = 3;
+			break;
+		case 16:
+			used_bits = 6;
+			break;
+		case 32:
+			used_bits = 8;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (!set) {
+		val = data->reg_access.get_reg_val(ld->base,
+						   LOGICVC_LAYER_ALPHA_ROFF,
+						   ld);
+		*alpha = (u8)(val & (0xFF >> (8 - used_bits)));
+	}
+
+	/* get/set normalized alpha value */
+	*alpha = alpha_normalized(*alpha, used_bits, set);
+
+	if (set)
+		data->reg_access.set_reg_val(*alpha, ld->base,
+					     LOGICVC_LAYER_ALPHA_ROFF,
+					     ld);
+
+	return 0;
+}
+
+static int xylonfb_layer_buff(struct fb_info *fbi,
+			      struct xylonfb_layer_buffer *layer_buff,
+			      bool set)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	unsigned int layer_id = ld->fd->id;
+	u32 reg;
+
+	if (set) {
+		if (layer_buff->id >= LOGICVC_MAX_LAYER_BUFFERS)
+			return -EINVAL;
+
+		reg = readl(ld->data->dev_base + LOGICVC_VBUFF_SELECT_ROFF);
+		reg |= (1 << (10 + layer_id));
+		reg &= ~(0x03 << (layer_id << 1));
+		reg |= (layer_buff->id << (layer_id << 1));
+		writel(reg, ld->data->dev_base + LOGICVC_VBUFF_SELECT_ROFF);
+
+		xylonfb_vsync_wait(0, fbi);
+	} else {
+		reg = readl(ld->data->dev_base + LOGICVC_VBUFF_SELECT_ROFF);
+		reg >>= ((layer_id << 1));
+		layer_buff->id = reg & 0x03;
+	}
+
+	return 0;
+}
+
+static void xylonfb_rgb_yuv(u32 c1, u32 c2, u32 c3, u32 *pixel,
+			    struct xylonfb_layer_data *ld, bool rgb2yuv)
+{
+	struct xylonfb_data *data = ld->data;
+	u32 r, g, b, y, u, v;
+
+	if (rgb2yuv) {
+		y = ((data->coeff.cyr * c1) + (data->coeff.cyg * c2) +
+		     (data->coeff.cyb * c3) + data->coeff.cy) /
+		     LOGICVC_YUV_NORM;
+		u = ((-data->coeff.cur * c1) - (data->coeff.cug * c2) +
+		     (data->coeff.cub * c3) + LOGICVC_COEFF_U) /
+		     LOGICVC_YUV_NORM;
+		v = ((data->coeff.cvr * c1) - (data->coeff.cvg * c2) -
+		     (data->coeff.cvb * c3) + LOGICVC_COEFF_V) /
+		     LOGICVC_YUV_NORM;
+
+		*pixel = (0xFF << 24) | (y << 16) | (u << 8) | v;
+	} else {
+		r = ((c1 * LOGICVC_RGB_NORM) + (LOGICVC_COEFF_R_U * c2) -
+		     LOGICVC_COEFF_R) / LOGICVC_RGB_NORM;
+		g = ((c1 * LOGICVC_RGB_NORM) - (LOGICVC_COEFF_G_U * c2) -
+		     (LOGICVC_COEFF_G_V * c3) + LOGICVC_COEFF_G) /
+		     LOGICVC_RGB_NORM;
+		b = ((c1 * LOGICVC_RGB_NORM) - (LOGICVC_COEFF_B_V * c3) -
+		     LOGICVC_COEFF_B) / LOGICVC_RGB_NORM;
+
+		*pixel = (0xFF << 24) | (r << 16) | (g << 8) | b;
+	}
+}
+
+static int xylonfb_layer_color_rgb(struct xylonfb_layer_data *ld,
+				   struct xylonfb_layer_color *layer_color,
+				   unsigned int reg_offset, bool set)
+{
+	struct xylonfb_data *data = ld->data;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+	void __iomem *base;
+	u32 r = 0, g = 0, b = 0;
+	u32 raw_rgb, y, u, v;
+	int bpp, transparency;
+
+	if (reg_offset = LOGICVC_LAYER_TRANSP_COLOR_ROFF) {
+		base = ld->base;
+		bpp = fd->bpp;
+		transparency = fd->transparency;
+	} else /* if (reg_offset = LOGICVC_BACKGROUND_COLOR_ROFF) */ {
+		base = data->dev_base;
+		bpp = data->bg_layer_bpp;
+		transparency = -1;
+	}
+
+	if (set) {
+		if (layer_color->use_raw) {
+			raw_rgb = layer_color->raw_rgb;
+		} else if (data->flags & XYLONFB_FLAGS_BACKGROUND_LAYER_YUV) {
+			r = layer_color->r;
+			g = layer_color->g;
+			b = layer_color->b;
+			xylonfb_rgb_yuv(r, g, b, &raw_rgb, ld, true);
+		} else {
+			r = layer_color->r;
+			g = layer_color->g;
+			b = layer_color->b;
+check_bpp_set:
+			switch (bpp) {
+			case 8:
+				switch (transparency) {
+				case LOGICVC_ALPHA_CLUT_16BPP:
+					bpp = 16;
+					goto check_bpp_set;
+				case LOGICVC_ALPHA_CLUT_32BPP:
+					bpp = 32;
+					goto check_bpp_set;
+				default:
+					raw_rgb = (r & 0xE0) |
+						   ((g & 0xE0) >> 3) |
+						   ((b & 0xC0) >> 6);
+					break;
+				}
+				break;
+			case 16:
+				raw_rgb = ((r & 0xF8) << 8) |
+					   ((g & 0xFC) << 3) |
+					   ((b & 0xF8) >> 3);
+				break;
+			case 32:
+				raw_rgb = (r << 16) | (g << 8) | b;
+				break;
+			default:
+				raw_rgb = 0;
+			}
+		}
+		data->reg_access.set_reg_val(raw_rgb, base, reg_offset, ld);
+	} else {
+		raw_rgb = data->reg_access.get_reg_val(base, reg_offset, ld);
+check_bpp_get:
+		if (data->flags & XYLONFB_FLAGS_BACKGROUND_LAYER_YUV) {
+			y = (raw_rgb >> 16) & 0xFF;
+			u = (raw_rgb >> 8) & 0xFF;
+			v = raw_rgb & 0xFF;
+			xylonfb_rgb_yuv(y, u, v, &raw_rgb, ld, false);
+		} else {
+			switch (bpp) {
+			case 8:
+				switch (transparency) {
+				case LOGICVC_ALPHA_CLUT_16BPP:
+					bpp = 16;
+					goto check_bpp_get;
+				case LOGICVC_ALPHA_CLUT_32BPP:
+					bpp = 32;
+					goto check_bpp_get;
+				default:
+					r = raw_rgb >> 5;
+					r = (((r << 3) | r) << 2) | (r >> 1);
+					g = (raw_rgb >> 2) & 0x07;
+					g = (((g << 3) | g) << 2) | (g >> 1);
+					b = raw_rgb & 0x03;
+					b = (b << 6) | (b << 4) | (b << 2) | b;
+					break;
+				}
+				break;
+			case 16:
+				r = raw_rgb >> 11;
+				r = (r << 3) | (r >> 2);
+				g = (raw_rgb >> 5) & 0x3F;
+				g = (g << 2) | (g >> 4);
+				b = raw_rgb & 0x1F;
+				b = (b << 3) | (b >> 2);
+				break;
+			case 32:
+				r = raw_rgb >> 16;
+				g = (raw_rgb >> 8) & 0xFF;
+				b = raw_rgb & 0xFF;
+				break;
+			default:
+				raw_rgb = r = g = b = 0;
+			}
+		}
+		layer_color->raw_rgb = raw_rgb;
+		layer_color->r = (u8)r;
+		layer_color->g = (u8)g;
+		layer_color->b = (u8)b;
+	}
+
+	return 0;
+}
+
+static int xylonfb_layer_geometry(struct fb_info *fbi,
+				  struct xylonfb_layer_geometry *layer_geometry,
+				  bool set)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+	u32 x, y, width, height, xoff, yoff, xres, yres;
+
+	xres = fbi->var.xres;
+	yres = fbi->var.yres;
+
+	if (set) {
+		x = layer_geometry->x;
+		y = layer_geometry->y;
+		width = layer_geometry->width;
+		height = layer_geometry->height;
+
+		if ((x > xres) || (y > yres))
+			return -EINVAL;
+
+		if ((width = 0) || (height = 0))
+			return -EINVAL;
+
+		if ((x + width) > xres) {
+			width = xres - x;
+			layer_geometry->width = width;
+		}
+		if ((y + height) > yres) {
+			height = yres - y;
+			layer_geometry->height = height;
+		}
+		/* YUV 4:2:2 layer type can only have even layer width */
+		if ((width > 2) && (fd->type = LOGICVC_LAYER_YUV) &&
+		    (fd->bpp = 16))
+			width &= ~((unsigned long) + 1);
+
+		/*
+		 * logiCVC 3.x registers write sequence:
+		 * offset, size, position with implicit last write to
+		 * LOGICVC_LAYER_VPOS_ROFF
+		 * logiCVC 4.x registers write sequence:
+		 * size, position with implicit last write to
+		 * LOGICVC_LAYER_ADDR_ROFF
+		 */
+		if (!(data->flags & XYLONFB_FLAGS_DYNAMIC_LAYER_ADDRESS)) {
+			data->reg_access.set_reg_val(layer_geometry->x_offset,
+						     ld->base,
+						     LOGICVC_LAYER_HOFF_ROFF,
+						     ld);
+			data->reg_access.set_reg_val(layer_geometry->y_offset,
+						     ld->base,
+						     LOGICVC_LAYER_VOFF_ROFF,
+						     ld);
+		}
+		data->reg_access.set_reg_val((width - 1), ld->base,
+					     LOGICVC_LAYER_HSIZE_ROFF,
+					     ld);
+		data->reg_access.set_reg_val((height - 1), ld->base,
+					     LOGICVC_LAYER_VSIZE_ROFF,
+					     ld);
+		data->reg_access.set_reg_val((xres - (x + 1)), ld->base,
+					     LOGICVC_LAYER_HPOS_ROFF,
+					     ld);
+		data->reg_access.set_reg_val((yres - (y + 1)), ld->base,
+					     LOGICVC_LAYER_VPOS_ROFF,
+					     ld);
+		if (data->flags & XYLONFB_FLAGS_DYNAMIC_LAYER_ADDRESS) {
+			xoff = layer_geometry->x_offset * (ld->fd->bpp / 8);
+			yoff = layer_geometry->y_offset * ld->fd->width *
+			       (ld->fd->bpp / 8);
+
+			ld->fb_pbase_active = ld->fb_pbase + xoff + yoff;
+
+			data->reg_access.set_reg_val(ld->fb_pbase_active,
+						     ld->base,
+						     LOGICVC_LAYER_ADDR_ROFF,
+						     ld);
+		}
+	} else {
+		x = data->reg_access.get_reg_val(ld->base,
+						 LOGICVC_LAYER_HPOS_ROFF,
+						 ld);
+		layer_geometry->x = xres - (x + 1);
+		y = data->reg_access.get_reg_val(ld->base,
+						 LOGICVC_LAYER_VPOS_ROFF,
+						 ld);
+		layer_geometry->y = yres - (y + 1);
+		layer_geometry->width +			data->reg_access.get_reg_val(ld->base,
+						     LOGICVC_LAYER_HSIZE_ROFF,
+						     ld);
+		layer_geometry->width += 1;
+		layer_geometry->height +			data->reg_access.get_reg_val(ld->base,
+						     LOGICVC_LAYER_VSIZE_ROFF,
+						     ld);
+		layer_geometry->height += 1;
+	}
+
+	return 0;
+}
+
+static int xylonfb_layer_reg_access(struct xylonfb_layer_data *ld,
+				    struct xylonfb_hw_access *hw_access,
+				    bool set)
+{
+	struct xylonfb_data *data = ld->data;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+	u32 offset;
+	u32 rel_offset;
+
+	if ((hw_access->offset < LOGICVC_LAYER_BASE_OFFSET) ||
+	    (hw_access->offset > LOGICVC_LAYER_BASE_END))
+		return -EPERM;
+
+	if (data->flags & XYLONFB_FLAGS_READABLE_REGS) {
+		offset = hw_access->offset;
+		if (set)
+			data->reg_access.set_reg_val(hw_access->value,
+						     data->dev_base,
+						     offset,
+						     ld);
+		else
+			hw_access->value +				data->reg_access.get_reg_val(data->dev_base,
+							     offset,
+							     ld);
+		return 0;
+	}
+
+	rel_offset = hw_access->offset - (fd->id * 0x80) -
+		     LOGICVC_LAYER_BASE_OFFSET;
+
+	if (rel_offset > LOGICVC_LAYER_BASE_END)
+		return -EINVAL;
+
+	if (set)
+		data->reg_access.set_reg_val(hw_access->value, ld->base,
+					     rel_offset, ld);
+	else
+		hw_access->value = data->reg_access.get_reg_val(ld->base,
+								rel_offset, ld);
+
+	return 0;
+}
+
+int xylonfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	union {
+		struct fb_vblank vblank;
+		struct xylonfb_hw_access hw_access;
+		struct xylonfb_layer_buffer layer_buff;
+		struct xylonfb_layer_color layer_color;
+		struct xylonfb_layer_geometry layer_geometry;
+		struct xylonfb_layer_transparency layer_transp;
+	} ioctl;
+	void __user *argp = (void __user *)arg;
+	unsigned long val;
+	u32 var32;
+	int ret = 0;
+	bool flag;
+
+	switch (cmd) {
+	case FBIOGET_VBLANK:
+		if (copy_from_user(&ioctl.vblank, argp, sizeof(ioctl.vblank)))
+			return -EFAULT;
+
+		ret = xylonfb_get_vblank(&ioctl.vblank, fbi);
+		if (!ret &&
+		    copy_to_user(argp, &ioctl.vblank, sizeof(ioctl.vblank)))
+			ret = -EFAULT;
+		break;
+
+	case FBIO_WAITFORVSYNC:
+		if (get_user(var32, (u32 __user *)arg))
+			return -EFAULT;
+
+		ret = xylonfb_vsync_wait(var32, fbi);
+		break;
+
+	case XYLONFB_VSYNC_CTRL:
+		if (get_user(flag, (u8 __user *)arg))
+			return -EFAULT;
+
+		xylonfb_vsync_ctrl(fbi, flag);
+		break;
+
+	case XYLONFB_LAYER_IDX:
+		var32 = ld->fd->id;
+		put_user(var32, (u32 __user *)arg);
+		break;
+
+	case XYLONFB_LAYER_ALPHA:
+		if (copy_from_user(&ioctl.layer_transp, argp,
+				   sizeof(ioctl.layer_transp)))
+			return -EFAULT;
+
+		mutex_lock(&ld->mutex);
+		ret = xylonfb_layer_alpha(ld, &ioctl.layer_transp.alpha,
+					  ioctl.layer_transp.set);
+		if (!ret && !ioctl.layer_transp.set)
+			if (copy_to_user(argp, &ioctl.layer_transp,
+					 sizeof(ioctl.layer_transp)))
+				ret = -EFAULT;
+		mutex_unlock(&ld->mutex);
+		break;
+
+	case XYLONFB_LAYER_COLOR_TRANSP_CTRL:
+		if (get_user(flag, (u8 __user *)arg))
+			return -EFAULT;
+
+		mutex_lock(&ld->mutex);
+		var32 = data->reg_access.get_reg_val(ld->base,
+						     LOGICVC_LAYER_CTRL_ROFF,
+						     ld);
+		if (flag)
+			var32 |= LOGICVC_LAYER_CTRL_COLOR_TRANSPARENCY_DISABLE;
+		else
+			var32 &= ~LOGICVC_LAYER_CTRL_COLOR_TRANSPARENCY_DISABLE;
+		data->reg_access.set_reg_val(var32, ld->base,
+					     LOGICVC_LAYER_CTRL_ROFF,
+					     ld);
+		mutex_unlock(&ld->mutex);
+		break;
+
+	case XYLONFB_LAYER_COLOR_TRANSP:
+		if (copy_from_user(&ioctl.layer_color, argp,
+				   sizeof(ioctl.layer_color)))
+			return -EFAULT;
+
+		mutex_lock(&ld->mutex);
+		ret = xylonfb_layer_color_rgb(ld, &ioctl.layer_color,
+					      LOGICVC_LAYER_TRANSP_COLOR_ROFF,
+					      ioctl.layer_color.set);
+		if (!ret && !ioctl.layer_color.set)
+			if (copy_to_user(argp, &ioctl.layer_color,
+					 sizeof(ioctl.layer_color)))
+				ret = -EFAULT;
+		mutex_unlock(&ld->mutex);
+		break;
+
+	case XYLONFB_LAYER_GEOMETRY:
+		if (!(data->flags & XYLONFB_FLAGS_SIZE_POSITION))
+			return -EINVAL;
+
+		if (copy_from_user(&ioctl.layer_geometry, argp,
+				   sizeof(ioctl.layer_geometry)))
+			return -EFAULT;
+
+		mutex_lock(&ld->mutex);
+		ret = xylonfb_layer_geometry(fbi, &ioctl.layer_geometry,
+					     ioctl.layer_geometry.set);
+		if (!ret && !ioctl.layer_geometry.set)
+			if (copy_to_user(argp, &ioctl.layer_geometry,
+					 sizeof(ioctl.layer_geometry)))
+				ret = -EFAULT;
+		mutex_unlock(&ld->mutex);
+		break;
+
+	case XYLONFB_LAYER_BUFFER:
+		if (data->major >= 4)
+			return -EPERM;
+
+		if (copy_from_user(&ioctl.layer_buff, argp,
+				   sizeof(ioctl.layer_buff)))
+			return -EFAULT;
+
+		mutex_lock(&ld->mutex);
+		ret = xylonfb_layer_buff(fbi, &ioctl.layer_buff,
+					 ioctl.layer_buff.set);
+		if (!ret && !ioctl.layer_buff.set)
+			if (copy_to_user(argp, &ioctl.layer_buff,
+					 sizeof(ioctl.layer_buff)))
+				ret = -EFAULT;
+		mutex_unlock(&ld->mutex);
+		break;
+
+	case XYLONFB_LAYER_BUFFER_OFFSET:
+		if (data->major < 4) {
+			var32 = readl(ld->data->dev_base +
+				      LOGICVC_VBUFF_SELECT_ROFF);
+			var32 >>= (ld->fd->id << 1);
+			var32 &= 0x03;
+			val = ld->fd->buffer_offset;
+			val *= var32;
+		} else {
+			val = ld->fd->buffer_offset;
+		}
+		put_user(val, (unsigned long __user *)arg);
+		break;
+
+	case XYLONFB_BACKGROUND_COLOR:
+		if (data->bg_layer_bpp = 0)
+			return -EPERM;
+
+		if (copy_from_user(&ioctl.layer_color, argp,
+				   sizeof(ioctl.layer_color)))
+			return -EFAULT;
+
+		mutex_lock(&ld->mutex);
+		ret = xylonfb_layer_color_rgb(ld, &ioctl.layer_color,
+					      LOGICVC_BACKGROUND_COLOR_ROFF,
+					      ioctl.layer_color.set);
+		if (!ret && !ioctl.layer_color.set)
+			if (copy_to_user(argp, &ioctl.layer_color,
+					 sizeof(ioctl.layer_color)))
+				ret = -EFAULT;
+		mutex_unlock(&ld->mutex);
+		break;
+
+	case XYLONFB_LAYER_EXT_BUFF_SWITCH:
+		if (get_user(flag, (u8 __user *)arg))
+			return -EFAULT;
+
+		mutex_lock(&ld->mutex);
+		var32 = data->reg_access.get_reg_val(ld->base,
+						     LOGICVC_LAYER_CTRL_ROFF,
+						     ld);
+		if (flag)
+			var32 |= LOGICVC_LAYER_CTRL_EXTERNAL_BUFFER_SWITCH;
+		else
+			var32 &= ~LOGICVC_LAYER_CTRL_EXTERNAL_BUFFER_SWITCH;
+		data->reg_access.set_reg_val(var32, ld->base,
+					     LOGICVC_LAYER_CTRL_ROFF,
+					     ld);
+		mutex_unlock(&ld->mutex);
+		break;
+
+	case XYLONFB_HW_ACCESS:
+		if (copy_from_user(&ioctl.hw_access, argp,
+				   sizeof(ioctl.hw_access)))
+			return -EFAULT;
+
+		ret = xylonfb_layer_reg_access(ld, &ioctl.hw_access,
+					       ioctl.hw_access.set);
+		if (!ret && !ioctl.hw_access.set)
+			if (copy_to_user(argp, &ioctl.hw_access,
+					 sizeof(ioctl.hw_access)))
+				ret = -EFAULT;
+		break;
+
+	case XYLONFB_IP_CORE_VERSION:
+		var32 = (data->major << 16) | (data->minor << 8) | data->patch;
+		if (copy_to_user(argp, &var32, sizeof(u32)))
+			ret = -EFAULT;
+		break;
+
+	default:
+		dev_err(&data->pdev->dev, "unknown ioctl");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
-- 
1.9.1


^ permalink raw reply related

* [PATCH 02/10] fbdev: xylon: Framebuffer driver core
From: Davor Joja @ 2015-03-11 15:27 UTC (permalink / raw)
  To: linux-kernel, linux-fbdev, tomi.valkeinen, geert; +Cc: Davor Joja
In-Reply-To: <1426087631-9952-1-git-send-email-davorjoja@logicbricks.com>

Driver core functionality.

Signed-off-by: Davor Joja <davorjoja@logicbricks.com>
---
 drivers/video/fbdev/xylon/xylonfb_core.c | 1691 ++++++++++++++++++++++++++++++
 drivers/video/fbdev/xylon/xylonfb_core.h |  252 +++++
 2 files changed, 1943 insertions(+)
 create mode 100644 drivers/video/fbdev/xylon/xylonfb_core.c
 create mode 100644 drivers/video/fbdev/xylon/xylonfb_core.h

diff --git a/drivers/video/fbdev/xylon/xylonfb_core.c b/drivers/video/fbdev/xylon/xylonfb_core.c
new file mode 100644
index 0000000..9970215
--- /dev/null
+++ b/drivers/video/fbdev/xylon/xylonfb_core.c
@@ -0,0 +1,1691 @@
+/*
+ * Xylon logiCVC frame buffer driver core functions
+ *
+ * Copyright (C) 2015 Xylon d.o.o.
+ * Author: Davor Joja <davor.joja@logicbricks.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/videodev2.h>
+
+#include "xylonfb_core.h"
+#include "logicvc.h"
+
+#define LOGICVC_PIX_FMT_AYUV	v4l2_fourcc('A', 'Y', 'U', 'V')
+#define LOGICVC_PIX_FMT_AVUY	v4l2_fourcc('A', 'V', 'U', 'Y')
+#define LOGICVC_PIX_FMT_ALPHA	v4l2_fourcc('A', '8', ' ', ' ')
+
+#define XYLONFB_PSEUDO_PALETTE_SIZE	256
+#define XYLONFB_VRES_DEFAULT		1080
+
+#define LOGICVC_COLOR_RGB_BLACK		0
+#define LOGICVC_COLOR_RGB_WHITE		0xFFFFFF
+#define LOGICVC_COLOR_YUV888_BLACK	0x8080
+#define LOGICVC_COLOR_YUV888_WHITE	0xFF8080
+
+char *xylonfb_mode_option;
+
+static const struct xylonfb_vmode xylonfb_vm = {
+	.vmode = {
+		.refresh = 60,
+		.xres = 1024,
+		.yres = 768,
+		.pixclock = KHZ2PICOS(65000),
+		.left_margin = 160,
+		.right_margin = 24,
+		.upper_margin = 29,
+		.lower_margin = 3,
+		.hsync_len = 136,
+		.vsync_len = 6,
+		.vmode = FB_VMODE_NONINTERLACED
+	},
+	.name = "1024x768"
+};
+
+static int xylonfb_set_timings(struct fb_info *fbi, int bpp);
+static void xylonfb_logicvc_disp_ctrl(struct fb_info *fbi, bool enable);
+static void xylonfb_enable_logicvc_output(struct fb_info *fbi);
+static void xylonfb_disable_logicvc_output(struct fb_info *fbi);
+static void xylonfb_logicvc_layer_enable(struct fb_info *fbi, bool enable);
+static void xylonfb_fbi_update(struct fb_info *fbi);
+
+static u32 xylonfb_get_reg(void __iomem *base, unsigned int offset,
+			   struct xylonfb_layer_data *ld)
+{
+	return readl(base + offset);
+}
+
+static void xylonfb_set_reg(u32 value, void __iomem *base, unsigned int offset,
+			    struct xylonfb_layer_data *ld)
+{
+	writel(value, (base + offset));
+}
+
+static unsigned long xylonfb_get_reg_mem_addr(void __iomem *base,
+					      unsigned int offset,
+					      struct xylonfb_layer_data *ld)
+{
+	unsigned int ordinal = offset / LOGICVC_REG_STRIDE;
+
+	if ((unsigned long)base - (unsigned long)ld->data->dev_base) {
+		return (unsigned long)(&ld->regs) + (ordinal * sizeof(u32));
+	} else {
+		ordinal -= (LOGICVC_CTRL_ROFF / LOGICVC_REG_STRIDE);
+		return (unsigned long)(&ld->data->regs) +
+				       (ordinal * sizeof(u32));
+	}
+}
+
+static u32 xylonfb_get_reg_mem(void __iomem *base, unsigned int offset,
+			       struct xylonfb_layer_data *ld)
+{
+	return *((unsigned long *)xylonfb_get_reg_mem_addr(base, offset, ld));
+}
+
+static void xylonfb_set_reg_mem(u32 value, void __iomem *base,
+				unsigned int offset,
+				struct xylonfb_layer_data *ld)
+{
+	unsigned long *reg_mem_addr +		(unsigned long *)xylonfb_get_reg_mem_addr(base, offset, ld);
+	*reg_mem_addr = value;
+	writel((*reg_mem_addr), (base + offset));
+}
+
+static irqreturn_t xylonfb_isr(int irq, void *dev_id)
+{
+	struct fb_info **afbi = dev_get_drvdata(dev_id);
+	struct fb_info *fbi = afbi[0];
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	void __iomem *dev_base = data->dev_base;
+	u32 isr;
+
+	XYLONFB_DBG(CORE, "%s", __func__);
+
+	isr = readl(dev_base + LOGICVC_INT_STAT_ROFF);
+	if (isr & LOGICVC_INT_V_SYNC) {
+		writel(LOGICVC_INT_V_SYNC, dev_base + LOGICVC_INT_STAT_ROFF);
+
+		data->vsync.count++;
+
+		if (waitqueue_active(&data->vsync.wait))
+			wake_up_interruptible(&data->vsync.wait);
+
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int xylonfb_open(struct fb_info *fbi, int user)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	int ret;
+	bool enable = false;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (atomic_read(&ld->refcount) = 0) {
+		if (ld->flags & XYLONFB_FLAGS_ACTIVATE_NEXT_OPEN) {
+			ld->flags &= ~XYLONFB_FLAGS_ACTIVATE_NEXT_OPEN;
+			enable = true;
+		} else {
+			if (fbi->var.activate = FB_ACTIVATE_NOW) {
+				enable = true;
+			} else if (fbi->var.activate = FB_ACTIVATE_NXTOPEN) {
+				ld->flags |= XYLONFB_FLAGS_ACTIVATE_NEXT_OPEN;
+				return 0;
+			} else if (fbi->var.activate = FB_ACTIVATE_VBL) {
+				ret = xylonfb_vsync_wait(0, fbi);
+				if (ret > 0)
+					enable = true;
+				else
+					return ret;
+			}
+		}
+
+		if (enable) {
+			xylonfb_logicvc_layer_enable(fbi, true);
+			atomic_inc(&data->refcount);
+		}
+	}
+
+	atomic_inc(&ld->refcount);
+
+	return 0;
+}
+
+static int xylonfb_release(struct fb_info *fbi, int user)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (atomic_read(&ld->refcount) > 0) {
+		atomic_dec(&ld->refcount);
+
+		if (atomic_read(&ld->refcount) = 0) {
+			xylonfb_logicvc_layer_enable(fbi, false);
+			atomic_dec(&data->refcount);
+		}
+	}
+
+	return 0;
+}
+
+static int xylonfb_check_var(struct fb_var_screeninfo *var,
+			     struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (var->xres < LOGICVC_MIN_XRES)
+		var->xres = LOGICVC_MIN_XRES;
+	if (var->xres > LOGICVC_MAX_XRES)
+		var->xres = LOGICVC_MAX_XRES;
+	if (var->yres < LOGICVC_MIN_VRES)
+		var->yres = LOGICVC_MIN_VRES;
+	if (var->yres > LOGICVC_MAX_VRES)
+		var->yres = LOGICVC_MAX_VRES;
+
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+	if (var->xres_virtual > fd->width)
+		var->xres_virtual = fd->width;
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+	if (var->yres_virtual > fd->height)
+		var->yres_virtual = fd->height;
+
+	/* YUV 4:2:2 layer type can only have even layer xoffset */
+	if (fd->format = XYLONFB_FORMAT_YUYV)
+		var->xoffset &= ~((unsigned long) + 1);
+
+	if ((var->xoffset + var->xres) >= var->xres_virtual)
+		var->xoffset = var->xres_virtual - var->xres - 1;
+	if ((var->yoffset + var->yres) >= var->yres_virtual)
+		var->yoffset = var->yres_virtual - var->yres - 1;
+
+	if (var->bits_per_pixel != fbi->var.bits_per_pixel) {
+		if (var->bits_per_pixel = 24)
+			var->bits_per_pixel = 32;
+		else
+			var->bits_per_pixel = fbi->var.bits_per_pixel;
+	}
+
+	var->grayscale = fbi->var.grayscale;
+
+	var->transp.offset = fbi->var.transp.offset;
+	var->transp.length = fbi->var.transp.length;
+	var->transp.msb_right = fbi->var.transp.msb_right;
+	var->red.offset = fbi->var.red.offset;
+	var->red.length = fbi->var.red.length;
+	var->red.msb_right = fbi->var.red.msb_right;
+	var->green.offset = fbi->var.green.offset;
+	var->green.length = fbi->var.green.length;
+	var->green.msb_right = fbi->var.green.msb_right;
+	var->blue.offset = fbi->var.blue.offset;
+	var->blue.length = fbi->var.blue.length;
+	var->blue.msb_right = fbi->var.blue.msb_right;
+	var->height = fbi->var.height;
+	var->width = fbi->var.width;
+	var->sync = fbi->var.sync;
+	var->rotate = fbi->var.rotate;
+
+	return 0;
+}
+
+static int xylonfb_set_par(struct fb_info *fbi)
+{
+	struct device *dev = fbi->dev;
+	struct fb_info **afbi = NULL;
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	unsigned long f;
+	int i, bpp;
+	int ret = 0;
+	char vmode_opt[VMODE_NAME_SIZE];
+	bool resolution_change, layer_on[LOGICVC_MAX_LAYERS];
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (data->flags & XYLONFB_FLAGS_VMODE_SET)
+		return 0;
+
+	if ((fbi->var.xres = data->vm_active.vmode.xres) ||
+	    (fbi->var.yres = data->vm_active.vmode.yres))
+		resolution_change = false;
+	else
+		resolution_change = true;
+
+	if (resolution_change || (data->flags & XYLONFB_FLAGS_VMODE_INIT)) {
+		if (!(data->flags & XYLONFB_FLAGS_VMODE_INIT)) {
+			struct xylonfb_layer_data *ld;
+
+			afbi = dev_get_drvdata(fbi->device);
+			for (i = 0; i < data->layers; i++) {
+				ld = afbi[i]->par;
+				if (ld->flags & XYLONFB_FLAGS_LAYER_ENABLED)
+					layer_on[i] = true;
+				else
+					layer_on[i] = false;
+			}
+		}
+
+		xylonfb_disable_logicvc_output(fbi);
+		xylonfb_logicvc_disp_ctrl(fbi, false);
+
+		if (!(data->flags & XYLONFB_FLAGS_VMODE_INIT)) {
+			data->vm_active.vmode.refresh = 60;
+			sprintf(vmode_opt, "%dx%d%s-%d@%d%s",
+				fbi->var.xres, fbi->var.yres,
+				data->vm_active.opts_cvt,
+				fbi->var.bits_per_pixel,
+				data->vm_active.vmode.refresh,
+				data->vm_active.opts_ext);
+			if (!strcmp(data->vm.name, vmode_opt)) {
+				data->vm_active = data->vm;
+			} else {
+				bpp = fbi->var.bits_per_pixel;
+				xylonfb_mode_option = vmode_opt;
+				ret = xylonfb_set_timings(fbi, bpp);
+				xylonfb_mode_option = NULL;
+			}
+		}
+		if (!ret) {
+			f = PICOS2KHZ(data->vm_active.vmode.pixclock);
+			if (data->flags & XYLONFB_FLAGS_PIXCLK_VALID)
+				if (xylonfb_hw_pixclk_set(&data->pdev->dev,
+							  data->pixel_clock, f))
+					dev_err(dev,
+						"failed set pixel clock\n");
+
+			xylonfb_fbi_update(fbi);
+			XYLONFB_DBG(INFO, "video mode: %dx%d%s-%d@%d%s\n",
+				    fbi->var.xres, fbi->var.yres,
+				    data->vm_active.opts_cvt,
+				    fbi->var.bits_per_pixel,
+				    data->vm_active.vmode.refresh,
+				    data->vm_active.opts_ext);
+		}
+
+		xylonfb_enable_logicvc_output(fbi);
+		xylonfb_logicvc_disp_ctrl(fbi, true);
+
+		if (data->flags & XYLONFB_FLAGS_VMODE_INIT)
+			data->flags |= XYLONFB_FLAGS_VMODE_SET;
+
+		if (!(data->flags & XYLONFB_FLAGS_VMODE_SET)) {
+			if (!afbi) {
+				xylonfb_logicvc_layer_enable(fbi, true);
+				return ret;
+			}
+
+			for (i = 0; i < data->layers; i++) {
+				if (layer_on[i])
+					xylonfb_logicvc_layer_enable(afbi[i],
+								     true);
+			}
+		}
+	}
+
+	return ret;
+}
+
+static void xylonfb_set_color_hw_rgb2yuv(u16 t, u16 r, u16 g, u16 b, u32 *yuv,
+					 struct xylonfb_layer_data *ld)
+{
+	struct xylonfb_data *data = ld->data;
+	u32 y, u, v;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	y = ((data->coeff.cyr * (r & 0xFF)) + (data->coeff.cyg * (g & 0xFF)) +
+	     (data->coeff.cyb * (b & 0xFF)) + data->coeff.cy) /
+	     LOGICVC_YUV_NORM;
+	u = ((-data->coeff.cur * (r & 0xFF)) - (data->coeff.cug * (g & 0xFF)) +
+	     (data->coeff.cub * (b & 0xFF)) + LOGICVC_COEFF_U) /
+	     LOGICVC_YUV_NORM;
+	v = ((data->coeff.cvr * (r & 0xFF)) - (data->coeff.cvg * (g & 0xFF)) -
+	     (data->coeff.cvb * (b & 0xFF)) + LOGICVC_COEFF_V) /
+	     LOGICVC_YUV_NORM;
+
+	*yuv = ((t & 0xFF) << 24) | (y << 16) | (u << 8) | v;
+}
+
+static int xylonfb_set_color_hw(u16 *t, u16 *r, u16 *g, u16 *b,
+				int len, int id, struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+	u32 pixel, pixel_clut;
+	u16 a = 0xFF;
+	int bpp, to, ro, go, bo;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	bpp = fd->bpp;
+
+	to = fbi->var.transp.offset;
+	ro = fbi->var.red.offset;
+	go = fbi->var.green.offset;
+	bo = fbi->var.blue.offset;
+
+	switch (fbi->fix.visual) {
+	case FB_VISUAL_PSEUDOCOLOR:
+		if ((id > (LOGICVC_CLUT_SIZE - 1)) || (len > LOGICVC_CLUT_SIZE))
+			return -EINVAL;
+
+		switch (fd->format_clut) {
+		case XYLONFB_FORMAT_CLUT_ARGB6565:
+			while (len > 0) {
+				if (t)
+					a = t[id];
+				pixel_clut = ((((a & 0xFC) >> 2) << to) |
+					      (((r[id] & 0xF8) >> 3) << ro) |
+					      (((g[id] & 0xFC) >> 2) << go) |
+					      (((b[id] & 0xF8) >> 3) << bo));
+				writel(pixel_clut, ld->clut_base +
+				       (id*LOGICVC_CLUT_REGISTER_SIZE));
+				len--;
+				id++;
+			}
+			break;
+		case XYLONFB_FORMAT_CLUT_ARGB8888:
+			while (len > 0) {
+				if (t)
+					a = t[id];
+				pixel_clut = (((a & 0xFF) << to) |
+					      ((r[id] & 0xFF) << ro) |
+					      ((g[id] & 0xFF) << go) |
+					      ((b[id] & 0xFF) << bo));
+				writel(pixel_clut, ld->clut_base +
+				       (id*LOGICVC_CLUT_REGISTER_SIZE));
+				len--;
+				id++;
+			}
+			break;
+		case XYLONFB_FORMAT_CLUT_AYUV8888:
+			while (len > 0) {
+				if (t)
+					a = t[id];
+				xylonfb_set_color_hw_rgb2yuv(a, r[id],
+							     g[id], b[id],
+					 		     &pixel_clut,
+					 		     ld);
+				writel(pixel_clut, ld->clut_base +
+				       (id*LOGICVC_CLUT_REGISTER_SIZE));
+				len--;
+				id++;
+			}
+			break;
+		}
+		break;
+	case FB_VISUAL_TRUECOLOR:
+		switch (fd->format) {
+		case XYLONFB_FORMAT_RGB332:
+			while (len > 0) {
+				pixel = ((((r[id] & 0xE0) >> 5) << ro) |
+					(((g[id] & 0xE0) >> 5) << go) |
+					(((b[id] & 0xC0) >> 6) << bo));
+				((u32 *)(fbi->pseudo_palette))[id] +					(pixel << 24) | (pixel << 16) |
+					(pixel << 8) | pixel;
+				len--;
+				id++;
+			}
+			break;
+		case XYLONFB_FORMAT_RGB565:
+			while (len > 0) {
+				pixel = ((((r[id] & 0xF8) >> 3) << ro) |
+					(((g[id] & 0xFC) >> 2) << go) |
+					(((b[id] & 0xF8) >> 3) << bo));
+				((u32 *)(fbi->pseudo_palette))[id] +					(pixel << 16) | pixel;
+				len--;
+				id++;
+			}
+			break;
+		case XYLONFB_FORMAT_XRGB8888:
+			while (len > 0) {
+				((u32 *)(fbi->pseudo_palette))[id] +					(((r[id] & 0xFF) << ro) |
+					((g[id] & 0xFF) << go) |
+					((b[id] & 0xFF) << bo));
+				len--;
+				id++;
+			}
+			break;
+		case XYLONFB_FORMAT_ARGB8888:
+			while (len > 0) {
+				if (t)
+					a = t[id];
+				((u32 *)(fbi->pseudo_palette))[id] +					(((a & 0xFF) << to) |
+					((r[id] & 0xFF) << ro) |
+					((g[id] & 0xFF) << go) |
+					((b[id] & 0xFF) << bo));
+				len--;
+				id++;
+			}
+			break;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int xylonfb_set_color(unsigned regno,
+			     unsigned red, unsigned green, unsigned blue,
+			     unsigned transp, struct fb_info *fbi)
+{
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	return xylonfb_set_color_hw((u16 *)&transp,
+				    (u16 *)&red, (u16 *)&green, (u16 *)&blue,
+				    1, regno, fbi);
+}
+
+static int xylonfb_set_cmap(struct fb_cmap *cmap, struct fb_info *fbi)
+{
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	return xylonfb_set_color_hw(cmap->transp,
+				    cmap->red, cmap->green, cmap->blue,
+				    cmap->len, cmap->start, fbi);
+}
+
+static void xylonfb_set_pixels(struct fb_info *fbi,
+			       struct xylonfb_layer_data *ld,
+			       int bpp, unsigned int pix)
+{
+	u32 *vmem;
+	u8 *vmem8;
+	u16 *vmem16;
+	u32 *vmem32;
+	int x, y, pixoffset;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	vmem = ld->fb_base + (fbi->var.xoffset * (fbi->var.bits_per_pixel/4)) +
+	       (fbi->var.yoffset * fbi->var.xres_virtual *
+	       (fbi->var.bits_per_pixel/4));
+
+	switch (bpp) {
+	case 8:
+		vmem8 = (u8 *)vmem;
+		for (y = fbi->var.yoffset; y < fbi->var.yres; y++) {
+			pixoffset = (y * fbi->var.xres_virtual);
+			for (x = fbi->var.xoffset; x < fbi->var.xres; x++)
+				vmem8[pixoffset + x] = pix;
+		}
+		break;
+	case 16:
+		vmem16 = (u16 *)vmem;
+		for (y = fbi->var.yoffset; y < fbi->var.yres; y++) {
+			pixoffset = (y * fbi->var.xres_virtual);
+			for (x = fbi->var.xoffset; x < fbi->var.xres; x++)
+				vmem16[pixoffset + x] = pix;
+		}
+		break;
+	case 32:
+		vmem32 = (u32 *)vmem;
+		for (y = fbi->var.yoffset; y < fbi->var.yres; y++) {
+			pixoffset = (y * fbi->var.xres_virtual);
+			for (x = fbi->var.xoffset; x < fbi->var.xres; x++)
+				vmem32[pixoffset + x] = pix;
+		}
+		break;
+	}
+}
+
+static int xylonfb_blank(int blank_mode, struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+	void __iomem *dev_base = data->dev_base;
+	u32 ctrl = data->reg_access.get_reg_val(dev_base,
+						LOGICVC_CTRL_ROFF,
+						ld);
+	u32 power = readl(dev_base + LOGICVC_POWER_CTRL_ROFF);
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK:
+		XYLONFB_DBG(INFO, "FB_BLANK_UNBLANK");
+		ctrl |= (LOGICVC_CTRL_HSYNC | LOGICVC_CTRL_VSYNC |
+			LOGICVC_CTRL_DATA_ENABLE);
+		data->reg_access.set_reg_val(ctrl, dev_base,
+					     LOGICVC_CTRL_ROFF, ld);
+
+		power |= LOGICVC_V_EN_MSK;
+		writel(power, dev_base + LOGICVC_POWER_CTRL_ROFF);
+
+		mdelay(50);
+		break;
+
+	case FB_BLANK_NORMAL:
+		XYLONFB_DBG(INFO, "FB_BLANK_NORMAL");
+		switch (fd->format) {
+		case XYLONFB_FORMAT_C8:
+			xylonfb_set_color(0, 0, 0, 0, 0xFF, fbi);
+			xylonfb_set_pixels(fbi, ld, 8, 0);
+			break;
+		case XYLONFB_FORMAT_RGB332:
+			xylonfb_set_pixels(fbi, ld, 8, 0x00);
+			break;
+		case XYLONFB_FORMAT_RGB565:
+			xylonfb_set_pixels(fbi, ld, 16, 0x0000);
+			break;
+		case XYLONFB_FORMAT_XRGB8888:
+		case XYLONFB_FORMAT_ARGB8888:
+			xylonfb_set_pixels(fbi, ld, 32, 0xFF000000);
+			break;
+		}
+		break;
+
+	case FB_BLANK_POWERDOWN:
+		XYLONFB_DBG(INFO, "FB_BLANK_POWERDOWN");
+		ctrl &= ~(LOGICVC_CTRL_HSYNC | LOGICVC_CTRL_VSYNC |
+			LOGICVC_CTRL_DATA_ENABLE);
+		data->reg_access.set_reg_val(ctrl, dev_base,
+					     LOGICVC_CTRL_ROFF, ld);
+
+		power &= ~LOGICVC_V_EN_MSK;
+		writel(power, dev_base + LOGICVC_POWER_CTRL_ROFF);
+
+		mdelay(50);
+		break;
+
+	case FB_BLANK_VSYNC_SUSPEND:
+		XYLONFB_DBG(INFO, "FB_BLANK_VSYNC_SUSPEND");
+		ctrl &= ~LOGICVC_CTRL_VSYNC;
+		data->reg_access.set_reg_val(ctrl, dev_base,
+					     LOGICVC_CTRL_ROFF, ld);
+		break;
+
+	case FB_BLANK_HSYNC_SUSPEND:
+		XYLONFB_DBG(INFO, "FB_BLANK_HSYNC_SUSPEND");
+		ctrl &= ~LOGICVC_CTRL_HSYNC;
+		data->reg_access.set_reg_val(ctrl, dev_base,
+					     LOGICVC_CTRL_ROFF, ld);
+		break;
+	}
+
+	return 0;
+}
+
+static int xylonfb_pan_display(struct fb_var_screeninfo *var,
+			       struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (!(data->flags & XYLONFB_FLAGS_SIZE_POSITION))
+		return -EINVAL;
+
+	if ((fbi->var.xoffset = var->xoffset) &&
+	    (fbi->var.yoffset = var->yoffset))
+		return 0;
+
+	if (fbi->var.vmode & FB_VMODE_YWRAP)
+		return -EINVAL;
+
+	if (((var->xoffset + fbi->var.xres) > fbi->var.xres_virtual) ||
+	    ((var->yoffset + fbi->var.yres) > fbi->var.yres_virtual))
+		return -EINVAL;
+
+	if (fd->format = XYLONFB_FORMAT_YUYV)
+		var->xoffset &= ~((unsigned long) + 1);
+
+	fbi->var.xoffset = var->xoffset;
+	fbi->var.yoffset = var->yoffset;
+
+	if (!(data->flags & XYLONFB_FLAGS_DYNAMIC_LAYER_ADDRESS)) {
+		data->reg_access.set_reg_val(var->xoffset, ld->base,
+					     LOGICVC_LAYER_HOFF_ROFF, ld);
+		data->reg_access.set_reg_val(var->yoffset, ld->base,
+					     LOGICVC_LAYER_VOFF_ROFF, ld);
+	}
+	data->reg_access.set_reg_val((fbi->var.xres - 1), ld->base,
+				     LOGICVC_LAYER_HPOS_ROFF, ld);
+	data->reg_access.set_reg_val((fbi->var.yres - 1), ld->base,
+				     LOGICVC_LAYER_VPOS_ROFF, ld);
+	if (data->flags & XYLONFB_FLAGS_DYNAMIC_LAYER_ADDRESS) {
+		ld->fb_pbase_active = ld->fb_pbase +
+				      ((var->xoffset * (fd->bpp / 8)) +
+				      (var->yoffset * fd->width *
+				      (fd->bpp / 8)));
+		data->reg_access.set_reg_val(ld->fb_pbase_active, ld->base,
+					     LOGICVC_LAYER_ADDR_ROFF, ld);
+	}
+
+	return 0;
+}
+
+static struct fb_ops xylonfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_open = xylonfb_open,
+	.fb_release = xylonfb_release,
+	.fb_check_var = xylonfb_check_var,
+	.fb_set_par = xylonfb_set_par,
+	.fb_setcolreg = xylonfb_set_color,
+	.fb_setcmap = xylonfb_set_cmap,
+	.fb_blank = xylonfb_blank,
+	.fb_pan_display = xylonfb_pan_display,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_ioctl = xylonfb_ioctl,
+};
+
+static int xylonfb_find_next_layer(struct xylonfb_data *data, int layers,
+				   int id)
+{
+	dma_addr_t address = data->fd[id]->address;
+	dma_addr_t temp_address = ((unsigned long) - 1);
+	dma_addr_t loop_address;
+	int next = -1;
+	int i;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	for (i = 0; i < layers; i++) {
+		loop_address = data->fd[i]->address;
+		if ((address < loop_address) && (loop_address < temp_address)) {
+			next = i;
+			temp_address = loop_address;
+		}
+	}
+
+	return next;
+}
+
+static void xylonfb_get_vmem_height(struct xylonfb_data *data, int layers,
+				    int id)
+{
+	struct xylonfb_layer_fix_data *fd = data->fd[id];
+	dma_addr_t vmem_start = fd->address;
+	dma_addr_t vmem_end;
+	int next;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (fd->address_range && (id < (layers - 1))) {
+		fd->height = fd->address_range / (fd->width * (fd->bpp / 8));
+		return;
+	}
+
+	vmem_start = fd->address;
+
+	next = xylonfb_find_next_layer(data, layers, id);
+	if (next = -1) {
+		if (fd->address_range) {
+			fd->height = fd->address_range /
+				     (fd->width * (fd->bpp / 8));
+		} else {
+			if (fd->buffer_offset)
+				fd->height = fd->buffer_offset *
+					     LOGICVC_MAX_LAYER_BUFFERS;
+			else
+				fd->height = XYLONFB_VRES_DEFAULT;
+		}
+	} else {
+		vmem_end = data->fd[next]->address;
+		fd->height = (vmem_end - vmem_start) /
+			     (fd->width * (fd->bpp / 8));
+	}
+
+	if (fd->height > (LOGICVC_MAX_VRES * LOGICVC_MAX_LAYER_BUFFERS))
+		fd->height = LOGICVC_MAX_VRES * LOGICVC_MAX_LAYER_BUFFERS;
+}
+
+static void xylonfb_set_fbi_var_screeninfo(struct fb_var_screeninfo *var,
+					   struct xylonfb_data *data)
+{
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	var->xres = data->vm_active.vmode.xres;
+	var->yres = data->vm_active.vmode.yres;
+	var->pixclock = data->vm_active.vmode.pixclock;
+	var->left_margin = data->vm_active.vmode.left_margin;
+	var->right_margin = data->vm_active.vmode.right_margin;
+	var->upper_margin = data->vm_active.vmode.upper_margin;
+	var->lower_margin = data->vm_active.vmode.lower_margin;
+	var->hsync_len = data->vm_active.vmode.hsync_len;
+	var->vsync_len = data->vm_active.vmode.vsync_len;
+	var->sync = data->vm_active.vmode.sync;
+	var->vmode = data->vm_active.vmode.vmode;
+}
+
+static void xylonfb_fbi_update(struct fb_info *fbi)
+{
+	struct fb_info **afbi = dev_get_drvdata(fbi->device);
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	int i, layers, id;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (!afbi)
+		return;
+
+	layers = data->layers;
+	id = ld->fd->id;
+
+	for (i = 0; i < layers; i++) {
+		if (i = id)
+			continue;
+
+		xylonfb_set_fbi_var_screeninfo(&afbi[i]->var, data);
+		afbi[i]->monspecs = afbi[id]->monspecs;
+	}
+}
+
+static void xylonfb_set_hw_specifics(struct fb_info *fbi,
+				     struct xylonfb_layer_data *ld,
+				     struct xylonfb_layer_fix_data *fd)
+{
+	struct xylonfb_data *data = ld->data;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	fbi->fix.smem_start = ld->fb_pbase;
+	fbi->fix.smem_len = ld->fb_size;
+	if (fd->type = LOGICVC_LAYER_RGB) {
+		fbi->fix.type = FB_TYPE_PACKED_PIXELS;
+	} else if (fd->type = LOGICVC_LAYER_YUV) {
+		if (fd->format = XYLONFB_FORMAT_C8)
+			fbi->fix.type = FB_TYPE_PACKED_PIXELS;
+		else
+			fbi->fix.type = FB_TYPE_FOURCC;
+	}
+	if ((fd->type = LOGICVC_LAYER_YUV) ||
+	    (fd->type = LOGICVC_LAYER_ALPHA)) {
+		if (fd->format = XYLONFB_FORMAT_C8)
+			fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		else
+			fbi->fix.visual = FB_VISUAL_FOURCC;
+	} else if (fd->format = XYLONFB_FORMAT_C8) {
+		fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+	} else {
+		/*
+		 * Other logiCVC layer pixel formats:
+		 * - 8 bpp: LAYER or PIXEL alpha
+		 *   It is not true color, RGB triplet is stored in 8 bits.
+		 * - 16 bpp:
+		 *   LAYER alpha: RGB triplet is stored in 16 bits
+		 * - 32 bpp: LAYER or PIXEL alpha
+		 *   True color, RGB triplet or ARGB quadriplet
+		 *   is stored in 32 bits.
+		 */
+		fbi->fix.visual = FB_VISUAL_TRUECOLOR;
+	}
+
+	fbi->fix.xpanstep = 1;
+	fbi->fix.ypanstep = 1;
+	fbi->fix.ywrapstep = 0;
+	fbi->fix.line_length = fd->width * (fd->bpp / 8);
+	fbi->fix.mmio_start = ld->pbase;
+	fbi->fix.mmio_len = LOGICVC_LAYER_REGISTERS_RANGE;
+	fbi->fix.accel = FB_ACCEL_NONE;
+
+	fbi->var.xres_virtual = fd->width;
+	fbi->var.yres_virtual = fd->height;
+
+	fbi->var.bits_per_pixel = fd->bpp;
+
+	switch (fd->type) {
+	case LOGICVC_LAYER_ALPHA:
+		fbi->var.grayscale = LOGICVC_PIX_FMT_ALPHA;
+		break;
+	case LOGICVC_LAYER_RGB:
+		fbi->var.grayscale = 0;
+		break;
+	case LOGICVC_LAYER_YUV:
+		if (fd->format = XYLONFB_FORMAT_C8) {
+			fbi->var.grayscale = LOGICVC_PIX_FMT_AYUV;
+		} else if (fd->format = XYLONFB_FORMAT_YUYV) {
+			if (fd->component_swap)
+				fbi->var.grayscale = V4L2_PIX_FMT_VYUY;
+			else
+				fbi->var.grayscale = V4L2_PIX_FMT_YVYU;
+		} else if (fd->format = XYLONFB_FORMAT_AYUV) {
+			if (fd->component_swap)
+				fbi->var.grayscale = LOGICVC_PIX_FMT_AVUY;
+			else
+				fbi->var.grayscale = LOGICVC_PIX_FMT_AYUV;
+		}
+		break;
+	}
+
+	/*
+	 * Set values according to logiCVC layer data width configuration:
+	 * layer data width can be 1, 2, 4 bytes
+	 */
+	if (fd->transparency = LOGICVC_ALPHA_LAYER) {
+		fbi->var.transp.offset = 0;
+		fbi->var.transp.length = 0;
+	}
+
+	switch (fd->format) {
+	case XYLONFB_FORMAT_A8:
+		fbi->var.transp.offset = 0;
+		fbi->var.transp.length = 8;
+		break;
+	case XYLONFB_FORMAT_C8:
+		switch (fd->format_clut) {
+		case XYLONFB_FORMAT_CLUT_ARGB6565:
+			fbi->var.transp.offset = 24;
+			fbi->var.transp.length = 6;
+			fbi->var.red.offset = 19;
+			fbi->var.red.length = 5;
+			fbi->var.green.offset = 10;
+			fbi->var.green.length = 6;
+			fbi->var.blue.offset = 3;
+			fbi->var.blue.length = 5;
+			break;
+		case XYLONFB_FORMAT_CLUT_ARGB8888:
+			fbi->var.transp.offset = 24;
+			fbi->var.transp.length = 8;
+			fbi->var.red.offset = 16;
+			fbi->var.red.length = 8;
+			fbi->var.green.offset = 8;
+			fbi->var.green.length = 8;
+			fbi->var.blue.offset = 0;
+			fbi->var.blue.length = 8;
+			break;
+		case XYLONFB_FORMAT_CLUT_AYUV8888:
+			fbi->var.transp.offset = 24;
+			fbi->var.transp.length = 8;
+			fbi->var.red.offset = 16;
+			fbi->var.red.length = 8;
+			fbi->var.green.offset = 8;
+			fbi->var.green.length = 8;
+			fbi->var.blue.offset = 0;
+			fbi->var.blue.length = 8;
+			break;
+		}
+		break;
+	case XYLONFB_FORMAT_RGB332:
+		fbi->var.red.offset = 5;
+		fbi->var.red.length = 3;
+		fbi->var.green.offset = 2;
+		fbi->var.green.length = 3;
+		fbi->var.blue.offset = 0;
+		fbi->var.blue.length = 2;
+		break;
+	case XYLONFB_FORMAT_RGB565:
+		fbi->var.red.offset = 11;
+		fbi->var.red.length = 5;
+		fbi->var.green.offset = 5;
+		fbi->var.green.length = 6;
+		fbi->var.blue.offset = 0;
+		fbi->var.blue.length = 5;
+		break;
+	case XYLONFB_FORMAT_ARGB8888:
+	case XYLONFB_FORMAT_AYUV:
+		fbi->var.transp.offset = 24;
+		fbi->var.transp.length = 8;
+	case XYLONFB_FORMAT_XRGB8888:
+		fbi->var.red.offset = 16;
+		fbi->var.red.length = 8;
+		fbi->var.green.offset = 8;
+		fbi->var.green.length = 8;
+		fbi->var.blue.offset = 0;
+		fbi->var.blue.length = 8;
+		break;
+	}
+	fbi->var.transp.msb_right = 0;
+	fbi->var.red.msb_right = 0;
+	fbi->var.green.msb_right = 0;
+	fbi->var.blue.msb_right = 0;
+	fbi->var.activate = FB_ACTIVATE_NOW;
+	fbi->var.height = 0;
+	fbi->var.width = 0;
+	fbi->var.sync = 0;
+	if (!(data->vm_active.ctrl & LOGICVC_CTRL_HSYNC_INVERT))
+		fbi->var.sync |= FB_SYNC_HOR_HIGH_ACT;
+	if (!(data->vm_active.ctrl & LOGICVC_CTRL_VSYNC_INVERT))
+		fbi->var.sync |= FB_SYNC_VERT_HIGH_ACT;
+	fbi->var.rotate = 0;
+}
+
+static int xylonfb_set_timings(struct fb_info *fbi, int bpp)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	struct fb_var_screeninfo fb_var;
+	struct fb_videomode *vm;
+	int rc;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if ((data->flags & XYLONFB_FLAGS_VMODE_INIT) &&
+	    (data->flags & XYLONFB_FLAGS_VMODE_CUSTOM) &&
+	    memchr(data->vm.name, 'x', 10)) {
+		data->vm_active = data->vm;
+		vm = &data->vm.vmode;
+		data->vm_active.vmode.refresh +			DIV_ROUND_CLOSEST((PICOS2KHZ(vm->pixclock) * 1000),
+					  ((vm->xres + vm->left_margin +
+					  vm->right_margin + vm->hsync_len) *
+					  (vm->yres + vm->upper_margin +
+					  vm->lower_margin + vm->vsync_len)));
+		return 0;
+	}
+
+	rc = fb_find_mode(&fb_var, fbi, xylonfb_mode_option, NULL, 0,
+			  &xylonfb_vm.vmode, bpp);
+
+	switch (rc) {
+	case 0:
+		dev_err(fbi->dev, "failed find video mode\n"
+			"using driver default mode %dx%dM-%d@%d\n",
+			xylonfb_vm.vmode.xres,
+			xylonfb_vm.vmode.yres,
+			bpp,
+			xylonfb_vm.vmode.refresh);
+		break;
+	case 1:
+		dev_dbg(fbi->dev, "video mode %s", xylonfb_mode_option);
+		break;
+	case 2:
+		dev_warn(fbi->dev, "video mode %s with ignored refresh rate\n",
+			 xylonfb_mode_option);
+		break;
+	case 3:
+		dev_warn(fbi->dev, "default video mode %dx%dM-%d@%d\n",
+			 xylonfb_vm.vmode.xres,
+			 xylonfb_vm.vmode.yres,
+			 bpp,
+			 xylonfb_vm.vmode.refresh);
+		break;
+	case 4:
+		dev_warn(fbi->dev, "video mode fallback\n");
+		break;
+	default:
+		break;
+	}
+
+	data->vm_active.ctrl = data->vm.ctrl;
+	data->vm_active.vmode.xres = fb_var.xres;
+	data->vm_active.vmode.yres = fb_var.yres;
+	data->vm_active.vmode.pixclock = fb_var.pixclock;
+	data->vm_active.vmode.left_margin = fb_var.left_margin;
+	data->vm_active.vmode.right_margin = fb_var.right_margin;
+	data->vm_active.vmode.upper_margin = fb_var.upper_margin;
+	data->vm_active.vmode.lower_margin = fb_var.lower_margin;
+	data->vm_active.vmode.hsync_len = fb_var.hsync_len;
+	data->vm_active.vmode.vsync_len = fb_var.vsync_len;
+	data->vm_active.vmode.sync = fb_var.sync;
+	data->vm_active.vmode.vmode = fb_var.vmode;
+	data->vm_active.vmode.refresh +		DIV_ROUND_CLOSEST((PICOS2KHZ(fb_var.pixclock) * 1000),
+				  ((fb_var.xres + fb_var.left_margin +
+				  fb_var.right_margin + fb_var.hsync_len) *
+				  (fb_var.yres + fb_var.upper_margin +
+				  fb_var.lower_margin + fb_var.vsync_len)));
+	strcpy(data->vm_active.opts_cvt, data->vm.opts_cvt);
+	strcpy(data->vm_active.opts_ext, data->vm.opts_ext);
+	sprintf(data->vm_active.name, "%dx%d%s-%d@%d%s",
+		fb_var.xres, fb_var.yres,
+		data->vm_active.opts_cvt,
+		fb_var.bits_per_pixel,
+		data->vm_active.vmode.refresh,
+		data->vm_active.opts_ext);
+
+	if (!memchr(data->vm.name, 'x', 10))
+		data->vm = data->vm_active;
+
+	return 0;
+}
+
+static int xylonfb_register_fb(struct fb_info *fbi,
+			       struct xylonfb_layer_data *ld, int id,
+			       int *regfb)
+{
+	struct device *dev = fbi->dev;
+	struct xylonfb_data *data = ld->data;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+	int transp;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	fbi->flags = FBINFO_DEFAULT;
+	fbi->screen_base = (char __iomem *)ld->fb_base;
+	fbi->screen_size = ld->fb_size;
+	fbi->pseudo_palette = kzalloc(sizeof(u32) * XYLONFB_PSEUDO_PALETTE_SIZE,
+				      GFP_KERNEL);
+	fbi->fbops = &xylonfb_ops;
+
+	sprintf(fbi->fix.id, "Xylon FB%d", id);
+	xylonfb_set_hw_specifics(fbi, ld, fd);
+
+	if (!(data->flags & XYLONFB_FLAGS_VMODE_DEFAULT)) {
+		if (!xylonfb_set_timings(fbi, fbi->var.bits_per_pixel))
+			data->flags |= XYLONFB_FLAGS_VMODE_DEFAULT;
+		else
+			dev_err(dev, "videomode not set\n");
+	}
+	xylonfb_set_fbi_var_screeninfo(&fbi->var, data);
+	fbi->mode = &data->vm_active.vmode;
+	fbi->mode->name = data->vm_active.name;
+
+	if (fd->transparency = LOGICVC_ALPHA_LAYER)
+		transp = 0;
+	else
+		transp = 1;
+	if (fb_alloc_cmap(&fbi->cmap, XYLONFB_PSEUDO_PALETTE_SIZE, transp))
+		return -ENOMEM;
+
+	/*
+	 * After fb driver registration, values in struct fb_info
+	 * must not be changed anywhere else in driver except in
+	 * xylonfb_set_par() function
+	 */
+	*regfb = register_framebuffer(fbi);
+	if (*regfb) {
+		dev_err(dev, "failed register fb %d\n", id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void xylonfb_layer_initialize(struct xylonfb_layer_data *ld)
+{
+	struct xylonfb_data *data = ld->data;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+	u32 reg = ld->data->reg_access.get_reg_val(ld->base,
+						   LOGICVC_LAYER_CTRL_ROFF,
+						   ld);
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	reg |= LOGICVC_LAYER_CTRL_COLOR_TRANSPARENCY_DISABLE;
+	if (fd->component_swap)
+		reg |= LOGICVC_LAYER_CTRL_PIXEL_FORMAT_ABGR;
+	ld->data->reg_access.set_reg_val(reg, ld->base,
+					 LOGICVC_LAYER_CTRL_ROFF,
+					 ld);
+
+	if (data->flags & XYLONFB_FLAGS_DYNAMIC_LAYER_ADDRESS)
+		data->reg_access.set_reg_val(ld->fb_pbase, ld->base,
+					     LOGICVC_LAYER_ADDR_ROFF,
+					     ld);
+}
+
+static int xylonfb_vmem_init(struct xylonfb_layer_data *ld, int id, bool *mmap)
+{
+	struct xylonfb_data *data = ld->data;
+	struct xylonfb_layer_fix_data *fd = ld->fd;
+	struct device *dev = &data->pdev->dev;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (fd->address) {
+		ld->fb_pbase = fd->address;
+
+		xylonfb_get_vmem_height(data, data->layers, id);
+		ld->fb_size = fd->width * (fd->bpp / 8) * fd->height;
+
+		if (*mmap) {
+			ld->fb_base = (__force void *)ioremap_wc(ld->fb_pbase,
+								 ld->fb_size);
+			if (!ld->fb_base) {
+				dev_err(dev, "failed map video memory\n");
+				return -EINVAL;
+			}
+		}
+	} else {
+		if (fd->buffer_offset)
+			fd->height = fd->buffer_offset *
+				     LOGICVC_MAX_LAYER_BUFFERS;
+		else
+			fd->height = XYLONFB_VRES_DEFAULT *
+				     LOGICVC_MAX_LAYER_BUFFERS;
+		ld->fb_size = fd->width * (fd->bpp / 8) * fd->height;
+
+		ld->fb_base = dma_alloc_coherent(&data->pdev->dev,
+						 PAGE_ALIGN(ld->fb_size),
+						 &ld->fb_pbase, GFP_KERNEL);
+		if (!ld->fb_base) {
+			dev_err(dev, "failed allocate video buffer ID%d\n", id);
+			return -ENOMEM;
+		}
+
+		data->flags |= XYLONFB_FLAGS_DMA_BUFFER;
+	}
+
+	ld->fb_pbase_active = ld->fb_pbase;
+
+	*mmap = false;
+
+	return 0;
+}
+
+static void xylonfb_logicvc_disp_ctrl(struct fb_info *fbi, bool enable)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	void __iomem *dev_base = data->dev_base;
+	u32 val;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (enable) {
+		val = LOGICVC_EN_VDD_MSK;
+		writel(val, dev_base + LOGICVC_POWER_CTRL_ROFF);
+		mdelay(data->pwr_delay);
+		val |= LOGICVC_V_EN_MSK;
+		writel(val, dev_base + LOGICVC_POWER_CTRL_ROFF);
+		mdelay(data->sig_delay);
+		val |= LOGICVC_EN_BLIGHT_MSK;
+		writel(val, dev_base + LOGICVC_POWER_CTRL_ROFF);
+	} else {
+		writel(0, dev_base + LOGICVC_POWER_CTRL_ROFF);
+	}
+}
+
+static void xylonfb_logicvc_layer_enable(struct fb_info *fbi, bool enable)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	u32 reg;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	reg = ld->data->reg_access.get_reg_val(ld->base,
+					       LOGICVC_LAYER_CTRL_ROFF,
+					       ld);
+
+	if (enable) {
+		reg |= LOGICVC_LAYER_CTRL_ENABLE;
+		ld->flags |= XYLONFB_FLAGS_LAYER_ENABLED;
+	} else {
+		reg &= ~LOGICVC_LAYER_CTRL_ENABLE;
+		ld->flags &= ~XYLONFB_FLAGS_LAYER_ENABLED;
+	}
+
+	ld->data->reg_access.set_reg_val(reg, ld->base,
+					 LOGICVC_LAYER_CTRL_ROFF,
+					 ld);
+}
+
+static void xylonfb_enable_logicvc_output(struct fb_info *fbi)
+{
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	void __iomem *dev_base = data->dev_base;
+	struct fb_videomode *vm = &data->vm_active.vmode;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	writel(vm->right_margin - 1, dev_base + LOGICVC_HSYNC_FRONT_PORCH_ROFF);
+	writel(vm->hsync_len - 1, dev_base + LOGICVC_HSYNC_ROFF);
+	writel(vm->left_margin - 1, dev_base + LOGICVC_HSYNC_BACK_PORCH_ROFF);
+	writel(vm->xres - 1, dev_base + LOGICVC_HRES_ROFF);
+	writel(vm->lower_margin - 1, dev_base + LOGICVC_VSYNC_FRONT_PORCH_ROFF);
+	writel(vm->vsync_len - 1, dev_base + LOGICVC_VSYNC_ROFF);
+	writel(vm->upper_margin - 1, dev_base + LOGICVC_VSYNC_BACK_PORCH_ROFF);
+	writel(vm->yres - 1, dev_base + LOGICVC_VRES_ROFF);
+	data->reg_access.set_reg_val(data->vm_active.ctrl, dev_base,
+				     LOGICVC_CTRL_ROFF, ld);
+
+	if (data->flags & XYLONFB_FLAGS_BACKGROUND_LAYER_YUV)
+		data->reg_access.set_reg_val(LOGICVC_COLOR_YUV888_BLACK,
+					     dev_base,
+					     LOGICVC_BACKGROUND_COLOR_ROFF,
+					     ld);
+	else
+		data->reg_access.set_reg_val(LOGICVC_COLOR_RGB_BLACK,
+					     dev_base,
+					     LOGICVC_BACKGROUND_COLOR_ROFF,
+					     ld);
+
+	writel(LOGICVC_DTYPE_REG_INIT, dev_base + LOGICVC_DTYPE_ROFF);
+
+	XYLONFB_DBG(INFO, "logiCVC HW parameters:\n" \
+		"    Horizontal Front Porch: %d pixclks\n" \
+		"    Horizontal Sync:        %d pixclks\n" \
+		"    Horizontal Back Porch:  %d pixclks\n" \
+		"    Vertical Front Porch:   %d pixclks\n" \
+		"    Vertical Sync:          %d pixclks\n" \
+		"    Vertical Back Porch:    %d pixclks\n" \
+		"    Pixel Clock:            %d ps\n" \
+		"    Horizontal Resolution:  %d pixels\n" \
+		"    Vertical Resolution:    %d lines\n", \
+		vm->right_margin, vm->hsync_len, vm->left_margin,
+		vm->lower_margin, vm->vsync_len, vm->upper_margin,
+		vm->pixclock, vm->xres, vm->yres);
+}
+
+static void xylonfb_disable_logicvc_output(struct fb_info *fbi)
+{
+	struct fb_info **afbi = dev_get_drvdata(fbi->device);
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	int i;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (afbi)
+		for (i = 0; i < data->layers; i++)
+			xylonfb_logicvc_layer_enable(afbi[i], false);
+}
+
+static void xylonfb_start(struct fb_info **afbi, int layers)
+{
+	struct fb_info *fbi = afbi[0];
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	int i;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	for (i = 0; i < layers; i++) {
+		ld = afbi[i]->par;
+		if (ld->flags & XYLONFB_FLAGS_LAYER_ENABLED)
+			continue;
+
+		xylonfb_logicvc_layer_enable(afbi[i], false);
+	}
+
+	if (data->flags & XYLONFB_FLAGS_VSYNC_IRQ) {
+		writel(LOGICVC_INT_V_SYNC,
+		       data->dev_base + LOGICVC_INT_STAT_ROFF);
+		data->reg_access.set_reg_val(~LOGICVC_INT_V_SYNC,
+					     data->dev_base,
+					     LOGICVC_INT_MASK_ROFF, ld);
+	}
+
+	for (i = 0; i < layers; i++) {
+		ld = afbi[i]->par;
+		XYLONFB_DBG(INFO, "logiCVC layer %d\n" \
+			"    Registers Base Address:     0x%lX\n" \
+			"    Layer Video Memory Address: 0x%lX\n" \
+			"    X resolution:               %d\n" \
+			"    Y resolution:               %d\n" \
+			"    X resolution (virtual):     %d\n" \
+			"    Y resolution (virtual):     %d\n" \
+			"    Line length (bytes):        %d\n" \
+			"    Bits per Pixel:             %d\n" \
+			"\n", \
+			i,
+			(unsigned long)ld->pbase,
+			(unsigned long)ld->fb_pbase,
+			afbi[i]->var.xres,
+			afbi[i]->var.yres,
+			afbi[i]->var.xres_virtual,
+			afbi[i]->var.yres_virtual,
+			afbi[i]->fix.line_length,
+			afbi[i]->var.bits_per_pixel);
+	}
+}
+
+static void xylonfb_get_vmode_opts(struct xylonfb_data *data)
+{
+	char *s, *opt, *ext, *c;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	s = data->vm.name;
+	opt = data->vm.opts_cvt;
+	ext = data->vm.opts_ext;
+
+	data->vm.vmode.vmode = 0;
+
+	c = strchr(s, 'M');
+	if (c)
+		*opt++ = *c;
+	c = strchr(s, 'R');
+	if (c)
+		*opt = *c;
+	c = strchr(s, 'i');
+	if (c) {
+		*ext++ = *c;
+		data->vm.vmode.vmode |= FB_VMODE_INTERLACED;
+	}
+	c = strchr(s, 'm');
+	if (c)
+		*ext = *c;
+}
+
+static bool xylonfb_allow_console(struct xylonfb_layer_fix_data *fd)
+{
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	switch (fd->format) {
+	case XYLONFB_FORMAT_C8:
+	case XYLONFB_FORMAT_RGB332:
+	case XYLONFB_FORMAT_RGB565:
+	case XYLONFB_FORMAT_XRGB8888:
+	case XYLONFB_FORMAT_ARGB8888:
+		return true;
+	default:
+		return false;
+	}
+}
+
+int xylonfb_init_core(struct xylonfb_data *data)
+{
+	struct device *dev = &data->pdev->dev;
+	struct fb_info **afbi, *fbi;
+	struct xylonfb_layer_data *ld;
+	void __iomem *dev_base;
+	u32 ip_ver;
+	int i, ret, layers, console_layer;
+	int regfb[LOGICVC_MAX_LAYERS];
+	size_t size;
+	unsigned short layer_base_off[] = {
+		(LOGICVC_LAYER_BASE_OFFSET + LOGICVC_LAYER_0_OFFSET),
+		(LOGICVC_LAYER_BASE_OFFSET + LOGICVC_LAYER_1_OFFSET),
+		(LOGICVC_LAYER_BASE_OFFSET + LOGICVC_LAYER_2_OFFSET),
+		(LOGICVC_LAYER_BASE_OFFSET + LOGICVC_LAYER_3_OFFSET),
+		(LOGICVC_LAYER_BASE_OFFSET + LOGICVC_LAYER_4_OFFSET)
+	};
+	unsigned short clut_base_off[] = {
+		(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L0_CLUT_0_OFFSET),
+		(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L1_CLUT_0_OFFSET),
+		(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L2_CLUT_0_OFFSET),
+		(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L3_CLUT_0_OFFSET),
+		(LOGICVC_CLUT_BASE_OFFSET + LOGICVC_CLUT_L4_CLUT_0_OFFSET),
+	};
+	bool memmap;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	dev_base = devm_ioremap_resource(dev, &data->resource_mem);
+	if (IS_ERR(dev_base)) {
+		dev_err(dev, "failed ioremap mem resource\n");
+		return PTR_ERR(dev_base);
+	}
+	data->dev_base = dev_base;
+
+	data->irq = data->resource_irq.start;
+	ret = devm_request_irq(dev, data->irq, xylonfb_isr, IRQF_TRIGGER_HIGH,
+			       XYLONFB_DEVICE_NAME, dev);
+	if (ret)
+		return ret;
+
+	ip_ver = readl(dev_base + LOGICVC_IP_VERSION_ROFF);
+	data->major = (ip_ver >> LOGICVC_MAJOR_REVISION_SHIFT) &
+		      LOGICVC_MAJOR_REVISION_MASK;
+	data->minor = (ip_ver >> LOGICVC_MINOR_REVISION_SHIFT) &
+		      LOGICVC_MINOR_REVISION_MASK;
+	data->patch = ip_ver & LOGICVC_PATCH_LEVEL_MASK;
+	dev_info(dev, "logiCVC IP core %d.%02d.%c\n",
+		 data->major, data->minor, ('a' + data->patch));
+
+	if (data->major >= 4)
+		data->flags |= XYLONFB_FLAGS_DYNAMIC_LAYER_ADDRESS;
+
+	layers = data->layers;
+	if (layers = 0) {
+		dev_err(dev, "no available layers\n");
+		return -ENODEV;
+	}
+	console_layer = data->console_layer;
+	if (console_layer >= layers) {
+		dev_err(dev, "invalid console layer ID\n");
+		console_layer = 0;
+	}
+
+	if (data->flags & XYLONFB_FLAGS_CHECK_CONSOLE_LAYER) {
+		if (!xylonfb_allow_console(data->fd[console_layer])) {
+			dev_err(dev, "invalid console layer format\n");
+			return -EINVAL;
+		}
+		data->flags &= ~XYLONFB_FLAGS_CHECK_CONSOLE_LAYER;
+	}
+
+	size = sizeof(struct fb_info *);
+	afbi = devm_kzalloc(dev, (size * layers), GFP_KERNEL);
+	if (!afbi) {
+		dev_err(dev, "failed allocate internal data\n");
+		return -ENOMEM;
+	}
+
+	if (data->flags & XYLONFB_FLAGS_READABLE_REGS) {
+		data->reg_access.get_reg_val = xylonfb_get_reg;
+		data->reg_access.set_reg_val = xylonfb_set_reg;
+	} else {
+		size = sizeof(struct xylonfb_registers);
+		data->reg_access.get_reg_val = xylonfb_get_reg_mem;
+		data->reg_access.set_reg_val = xylonfb_set_reg_mem;
+	}
+
+	data->coeff.cyr = LOGICVC_COEFF_Y_R;
+	data->coeff.cyg = LOGICVC_COEFF_Y_G;
+	data->coeff.cyb = LOGICVC_COEFF_Y_B;
+	if (data->flags & XYLONFB_FLAGS_DISPLAY_INTERFACE_ITU656) {
+		data->coeff.cy = LOGICVC_COEFF_ITU656_Y;
+		data->coeff.cur = LOGICVC_COEFF_ITU656_U_R;
+		data->coeff.cug = LOGICVC_COEFF_ITU656_U_G;
+		data->coeff.cub = LOGICVC_COEFF_ITU656_U_B;
+		data->coeff.cvr = LOGICVC_COEFF_ITU656_V_R;
+		data->coeff.cvg = LOGICVC_COEFF_ITU656_V_G;
+		data->coeff.cvb = LOGICVC_COEFF_ITU656_V_B;
+	} else {
+		data->coeff.cy = LOGICVC_COEFF_Y;
+		data->coeff.cur = LOGICVC_COEFF_U_R;
+		data->coeff.cug = LOGICVC_COEFF_U_G;
+		data->coeff.cub = LOGICVC_COEFF_U_B;
+		data->coeff.cvr = LOGICVC_COEFF_V_R;
+		data->coeff.cvg = LOGICVC_COEFF_V_G;
+		data->coeff.cvb = LOGICVC_COEFF_V_B;
+	}
+
+	atomic_set(&data->refcount, 0);
+
+	data->flags |= XYLONFB_FLAGS_VMODE_INIT;
+
+	sprintf(data->vm.name, "%s-%d@%d",
+		data->vm.name, data->fd[console_layer]->bpp,
+		data->vm.vmode.refresh);
+	if (!(data->flags & XYLONFB_FLAGS_VMODE_CUSTOM))
+		xylonfb_mode_option = data->vm.name;
+	xylonfb_get_vmode_opts(data);
+
+	if (data->pixel_clock) {
+		if (xylonfb_hw_pixclk_supported(dev, data->pixel_clock)) {
+			data->flags |= XYLONFB_FLAGS_PIXCLK_VALID;
+		} else {
+			dev_warn(dev, "pixel clock not supported\n");
+			ret = -EPROBE_DEFER;
+			goto err_probe;
+		}
+	} else {
+		dev_info(dev, "external pixel clock\n");
+	}
+
+	ld = NULL;
+
+	for (i = 0; i < layers; i++)
+		regfb[i] = -1;
+	memmap = true;
+
+	/*
+	 * /dev/fb0 will be default console layer,
+	 * no matter how logiCVC layers are sorted in memory
+	 */
+	for (i = console_layer; i < layers; i++) {
+		if (regfb[i] != -1)
+			continue;
+
+		size = sizeof(struct xylonfb_layer_data);
+		fbi = framebuffer_alloc(size, dev);
+		if (!fbi) {
+			dev_err(dev, "failed allocate fb info\n");
+			ret = -ENOMEM;
+			goto err_probe;
+		}
+		fbi->dev = dev;
+		afbi[i] = fbi;
+
+		ld = fbi->par;
+		ld->data = data;
+		ld->fd = data->fd[i];
+
+		atomic_set(&ld->refcount, 0);
+
+		ld->pbase = data->resource_mem.start + layer_base_off[i];
+		ld->base = dev_base + layer_base_off[i];
+		ld->clut_base = dev_base + clut_base_off[i];
+
+		ret = xylonfb_vmem_init(ld, i, &memmap);
+		if (ret)
+			goto err_probe;
+
+		xylonfb_layer_initialize(ld);
+
+		ret = xylonfb_register_fb(fbi, ld, i, &regfb[i]);
+		if (ret)
+			goto err_probe;
+
+		if (console_layer >= 0)
+			fbi->monspecs = afbi[console_layer]->monspecs;
+
+		mutex_init(&ld->mutex);
+
+		XYLONFB_DBG(INFO, "Layer parameters\n" \
+			    "    ID %d\n" \
+			    "    Width %d pixels\n" \
+			    "    Height %d lines\n" \
+			    "    Bits per pixel %d\n" \
+			    "    Buffer size %d bytes\n", \
+			    ld->fd->id,
+			    ld->fd->width,
+			    ld->fd->height,
+			    ld->fd->bpp,
+			    ld->fb_size);
+
+		if (console_layer > 0) {
+			i = -1;
+			console_layer = -1;
+		}
+	}
+
+	if (ld) {
+		if (!(data->flags & XYLONFB_FLAGS_READABLE_REGS))
+			data->reg_access.set_reg_val(0xFFFF, dev_base,
+						     LOGICVC_INT_MASK_ROFF,
+						     ld);
+	} else {
+		dev_warn(dev, "initialization not completed\n");
+	}
+
+	if (data->flags & XYLONFB_FLAGS_BACKGROUND_LAYER)
+		dev_info(dev, "BG layer: %s@%dbpp",
+			 data->flags & XYLONFB_FLAGS_BACKGROUND_LAYER_RGB ? \
+			 "RGB" : "YUV", data->bg_layer_bpp);
+
+	mutex_init(&data->irq_mutex);
+	init_waitqueue_head(&data->vsync.wait);
+	atomic_set(&data->refcount, 0);
+
+	dev_set_drvdata(dev, (void *)afbi);
+
+	data->flags &= ~(XYLONFB_FLAGS_VMODE_INIT |
+			 XYLONFB_FLAGS_VMODE_DEFAULT | XYLONFB_FLAGS_VMODE_SET);
+	xylonfb_mode_option = NULL;
+
+	xylonfb_start(afbi, layers);
+
+	return 0;
+
+err_probe:
+	for (i = layers - 1; i >= 0; i--) {
+		fbi = afbi[i];
+		if (!fbi)
+			continue;
+		ld = fbi->par;
+		if (regfb[i] = 0)
+			unregister_framebuffer(fbi);
+		else
+			regfb[i] = 0;
+		if (fbi->cmap.red)
+			fb_dealloc_cmap(&fbi->cmap);
+		if (ld) {
+			if (data->flags & XYLONFB_FLAGS_DMA_BUFFER) {
+				if (ld->fb_base)
+					dma_free_coherent(dev,
+						PAGE_ALIGN(ld->fb_size),
+						ld->fb_base, ld->fb_pbase);
+			} else {
+				if (ld->fb_base)
+					iounmap((void __iomem *)ld->fb_base);
+			}
+			kfree(fbi->pseudo_palette);
+			framebuffer_release(fbi);
+		}
+	}
+
+	return ret;
+}
+
+int xylonfb_deinit_core(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct fb_info **afbi = dev_get_drvdata(dev);
+	struct fb_info *fbi = afbi[0];
+	struct xylonfb_layer_data *ld = fbi->par;
+	struct xylonfb_data *data = ld->data;
+	int i;
+
+	XYLONFB_DBG(INFO, "%s", __func__);
+
+	if (atomic_read(&data->refcount) != 0) {
+		dev_err(dev, "driver in use\n");
+		return -EINVAL;
+	}
+
+	xylonfb_disable_logicvc_output(fbi);
+
+	xylonfb_hw_pixclk_unload(data->pixel_clock);
+
+	for (i = data->layers - 1; i >= 0; i--) {
+		fbi = afbi[i];
+		ld = fbi->par;
+
+		unregister_framebuffer(fbi);
+		fb_dealloc_cmap(&fbi->cmap);
+		if (data->flags & XYLONFB_FLAGS_DMA_BUFFER) {
+			dma_free_coherent(dev,
+					  PAGE_ALIGN(ld->fb_size),
+					  ld->fb_base, ld->fb_pbase);
+		}
+		kfree(fbi->pseudo_palette);
+		framebuffer_release(fbi);
+	}
+
+	return 0;
+}
diff --git a/drivers/video/fbdev/xylon/xylonfb_core.h b/drivers/video/fbdev/xylon/xylonfb_core.h
new file mode 100644
index 0000000..1a3dee8
--- /dev/null
+++ b/drivers/video/fbdev/xylon/xylonfb_core.h
@@ -0,0 +1,252 @@
+/*
+ * Xylon logiCVC frame buffer driver internal data structures
+ *
+ * Copyright (C) 2015 Xylon d.o.o.
+ * Author: Davor Joja <davor.joja@logicbricks.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __XYLONFB_CORE_H__
+#define __XYLONFB_CORE_H__
+
+#include <linux/fb.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+
+#define XYLONFB_DRIVER_NAME "xylonfb"
+#define XYLONFB_DEVICE_NAME "logicvc"
+#define XYLONFB_DRIVER_DESCRIPTION "Xylon logiCVC frame buffer driver"
+#define XYLONFB_DRIVER_VERSION "3.0"
+
+#define INFO		1
+#define CORE		2
+#define DEBUG_LEVEL	CORE
+
+#ifdef DEBUG
+#define XYLONFB_DBG(level, format, ...)				\
+	do {							\
+		if (level >= DEBUG_LEVEL)			\
+			pr_info(format "\n", ## __VA_ARGS__);	\
+	} while (0)
+#else
+#define XYLONFB_DBG(format, ...) do { } while (0)
+#endif
+
+#define LOGICVC_MAX_LAYERS	5
+
+/* Xylon FB driver flags */
+#define XYLONFB_FLAGS_READABLE_REGS		(1 << 0)
+#define XYLONFB_FLAGS_SIZE_POSITION		(1 << 1)
+#define XYLONFB_FLAGS_BACKGROUND_LAYER		(1 << 2)
+#define XYLONFB_FLAGS_BACKGROUND_LAYER_RGB	(1 << 3)
+#define XYLONFB_FLAGS_BACKGROUND_LAYER_YUV	(1 << 4)
+#define XYLONFB_FLAGS_DISPLAY_INTERFACE_ITU656	(1 << 5)
+#define XYLONFB_FLAGS_DYNAMIC_LAYER_ADDRESS	(1 << 6)
+#define XYLONFB_FLAGS_CHECK_CONSOLE_LAYER	(1 << 7)
+#define XYLONFB_FLAGS_PIXCLK_VALID		(1 << 8)
+#define XYLONFB_FLAGS_DMA_BUFFER		(1 << 9)
+#define XYLONFB_FLAGS_VSYNC_IRQ			(1 << 10)
+#define XYLONFB_FLAGS_VMODE_CUSTOM		(1 << 11)
+#define XYLONFB_FLAGS_VMODE_INIT		(1 << 12)
+#define XYLONFB_FLAGS_VMODE_DEFAULT		(1 << 13)
+#define XYLONFB_FLAGS_VMODE_SET			(1 << 14)
+#define XYLONFB_FLAGS_LAYER_ENABLED		(1 << 15)
+#define XYLONFB_FLAGS_ACTIVATE_NEXT_OPEN	(1 << 16)
+
+/* Xylon FB driver color formats */
+enum xylonfb_color_format {
+	XYLONFB_FORMAT_A8,
+	XYLONFB_FORMAT_C8,
+	XYLONFB_FORMAT_RGB332,
+	XYLONFB_FORMAT_RGB565,
+	XYLONFB_FORMAT_XRGB8888,
+	XYLONFB_FORMAT_ARGB8888,
+	XYLONFB_FORMAT_YUYV,
+	XYLONFB_FORMAT_AYUV,
+	XYLONFB_FORMAT_CLUT_ARGB6565,
+	XYLONFB_FORMAT_CLUT_ARGB8888,
+	XYLONFB_FORMAT_CLUT_AYUV8888
+};
+
+struct xylonfb_layer_data;
+struct xylonfb_data;
+
+#define VMODE_NAME_SIZE	21
+#define VMODE_OPTS_SIZE	3
+
+struct xylonfb_vmode {
+	u32 ctrl;
+	struct fb_videomode vmode;
+	char name[VMODE_NAME_SIZE];
+	char opts_cvt[VMODE_OPTS_SIZE];
+	char opts_ext[VMODE_OPTS_SIZE];
+};
+
+struct xylonfb_registers {
+	u32 ctrl;
+	u32 dtype;
+	u32 bg;
+	u32 unused[3];
+	u32 int_mask;
+};
+
+union xylonfb_layer_reg_0 {
+	u32 addr;
+	u32 hoff;
+};
+
+union xylonfb_layer_reg_1 {
+	u32 unused;
+	u32 voff;
+};
+
+struct xylonfb_layer_registers {
+	union xylonfb_layer_reg_0 reg_0;
+	union xylonfb_layer_reg_1 reg_1;
+	u32 hpos;
+	u32 vpos;
+	u32 hsize;
+	u32 vsize;
+	u32 alpha;
+	u32 ctrl;
+	u32 transp;
+};
+
+struct xylonfb_register_access {
+	u32 (*get_reg_val)(void __iomem *dev_base, unsigned int offset,
+			   struct xylonfb_layer_data *layer_data);
+	void (*set_reg_val)(u32 value, void __iomem *dev_base,
+			    unsigned int offset,
+			    struct xylonfb_layer_data *layer_data);
+};
+
+struct xylonfb_layer_fix_data {
+	unsigned int id;
+	u32 address;
+	u32 address_range;
+	u32 buffer_offset;
+	u32 bpp;
+	u32 width;
+	u32 height;
+	u32 format;
+	u32 format_clut;
+	u32 transparency;
+	u32 type;
+	bool component_swap;
+};
+
+struct xylonfb_layer_data {
+	struct mutex mutex;
+
+	atomic_t refcount;
+
+	struct xylonfb_data *data;
+	struct xylonfb_layer_fix_data *fd;
+	struct xylonfb_layer_registers regs;
+
+	dma_addr_t pbase;
+	void __iomem *base;
+	void __iomem *clut_base;
+
+	dma_addr_t fb_pbase;
+	void *fb_base;
+	u32 fb_size;
+
+	dma_addr_t fb_pbase_active;
+
+	u32 flags;
+};
+
+struct xylonfb_rgb2yuv_coeff {
+	s32 cy;
+	s32 cyr;
+	s32 cyg;
+	s32 cyb;
+	s32 cur;
+	s32 cug;
+	s32 cub;
+	s32 cvr;
+	s32 cvg;
+	s32 cvb;
+};
+
+struct xylonfb_sync {
+	wait_queue_head_t wait;
+	unsigned int count;
+};
+
+struct xylonfb_data {
+	struct platform_device *pdev;
+
+	struct device_node *device;
+	struct device_node *pixel_clock;
+
+	struct resource resource_mem;
+	struct resource resource_irq;
+
+	void __iomem *dev_base;
+
+	struct mutex irq_mutex;
+
+	struct xylonfb_register_access reg_access;
+	struct xylonfb_sync vsync;
+	struct xylonfb_vmode vm;
+	struct xylonfb_vmode vm_active;
+	struct xylonfb_rgb2yuv_coeff coeff;
+
+	struct xylonfb_layer_fix_data *fd[LOGICVC_MAX_LAYERS];
+	struct xylonfb_registers regs;
+
+	u32 bg_layer_bpp;
+	u32 console_layer;
+	u32 pixel_stride;
+
+	atomic_t refcount;
+
+	u32 flags;
+	int irq;
+	u8 layers;
+	/*
+	 * Delay after applying display power and
+	 * before applying display signals
+	 */
+	u32 pwr_delay;
+	/*
+	 * Delay after applying display signal and
+	 * before applying display backlight power supply
+	 */
+	u32 sig_delay;
+	/* IP version */
+	u8 major;
+	u8 minor;
+	u8 patch;
+};
+
+/* Xylon FB video mode options */
+extern char *xylonfb_mode_option;
+
+/* Xylon FB core pixel clock interface functions */
+extern bool xylonfb_hw_pixclk_supported(struct device *dev,
+					struct device_node *dn);
+extern void xylonfb_hw_pixclk_unload(struct device_node *dn);
+extern int xylonfb_hw_pixclk_set(struct device *dev, struct device_node *dn,
+				 unsigned long pixclk_khz);
+
+/* Xylon FB core V sync wait function */
+extern int xylonfb_vsync_wait(u32 crt, struct fb_info *fbi);
+
+/* Xylon FB core interface functions */
+extern int xylonfb_init_core(struct xylonfb_data *data);
+extern int xylonfb_deinit_core(struct platform_device *pdev);
+extern int xylonfb_ioctl(struct fb_info *fbi, unsigned int cmd,
+			 unsigned long arg);
+
+#endif /* __XYLONFB_CORE_H__ */
-- 
1.9.1


^ permalink raw reply related


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