aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Jin <jason.jin@nxp.com>2016-11-25 01:40:55 -0500
committerScott Wood <oss@buserror.net>2017-01-25 03:30:10 -0500
commit1c06552a703c6a4256976a1615d262b5a0d754e5 (patch)
tree66ba56757acbfecd7e960775170ad09ce5de471e
parent7ce7d89f48834cefece7804d38fc5d85382edf77 (diff)
powerpc/85xx: Enable display support for t1042rdb
Add a diu_ops implementation for t1042rdb. Signed-off-by: Jason Jin <jason.jin@nxp.com> [Meng Yi: Made file t1042rdb-specific] Signed-off-by: Meng Yi <meng.yi@nxp.com> [scottwood: clean up commit message] Signed-off-by: Scott Wood <oss@buserror.net>
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/t1042rdb_diu.c152
2 files changed, 153 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 7bc86dae9517..fe19dad568e2 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_P1022_RDK) += p1022_rdk.o
22obj-$(CONFIG_P1023_RDB) += p1023_rdb.o 22obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
23obj-$(CONFIG_TWR_P102x) += twr_p102x.o 23obj-$(CONFIG_TWR_P102x) += twr_p102x.o
24obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o 24obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
25obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
25obj-$(CONFIG_STX_GP3) += stx_gp3.o 26obj-$(CONFIG_STX_GP3) += stx_gp3.o
26obj-$(CONFIG_TQM85xx) += tqm85xx.o 27obj-$(CONFIG_TQM85xx) += tqm85xx.o
27obj-$(CONFIG_SBC8548) += sbc8548.o 28obj-$(CONFIG_SBC8548) += sbc8548.o
diff --git a/arch/powerpc/platforms/85xx/t1042rdb_diu.c b/arch/powerpc/platforms/85xx/t1042rdb_diu.c
new file mode 100644
index 000000000000..58fa3d319f1c
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/t1042rdb_diu.c
@@ -0,0 +1,152 @@
1/*
2 * T1042 platform DIU operation
3 *
4 * Copyright 2014 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/io.h>
13#include <linux/kernel.h>
14#include <linux/of.h>
15#include <linux/of_address.h>
16
17#include <sysdev/fsl_soc.h>
18
19/*DIU Pixel ClockCR offset in scfg*/
20#define CCSR_SCFG_PIXCLKCR 0x28
21
22/* DIU Pixel Clock bits of the PIXCLKCR */
23#define PIXCLKCR_PXCKEN 0x80000000
24#define PIXCLKCR_PXCKINV 0x40000000
25#define PIXCLKCR_PXCKDLY 0x0000FF00
26#define PIXCLKCR_PXCLK_MASK 0x00FF0000
27
28/* Some CPLD register definitions */
29#define CPLD_DIUCSR 0x16
30#define CPLD_DIUCSR_DVIEN 0x80
31#define CPLD_DIUCSR_BACKLIGHT 0x0f
32
33struct device_node *cpld_node;
34
35/**
36 * t1042rdb_set_monitor_port: switch the output to a different monitor port
37 */
38static void t1042rdb_set_monitor_port(enum fsl_diu_monitor_port port)
39{
40 static void __iomem *cpld_base;
41
42 cpld_base = of_iomap(cpld_node, 0);
43 if (!cpld_base) {
44 pr_err("%s: Could not map cpld registers\n", __func__);
45 goto exit;
46 }
47
48 switch (port) {
49 case FSL_DIU_PORT_DVI:
50 /* Enable the DVI(HDMI) port, disable the DFP and
51 * the backlight
52 */
53 clrbits8(cpld_base + CPLD_DIUCSR, CPLD_DIUCSR_DVIEN);
54 break;
55 case FSL_DIU_PORT_LVDS:
56 /*
57 * LVDS also needs backlight enabled, otherwise the display
58 * will be blank.
59 */
60 /* Enable the DFP port, disable the DVI*/
61 setbits8(cpld_base + CPLD_DIUCSR, 0x01 << 8);
62 setbits8(cpld_base + CPLD_DIUCSR, 0x01 << 4);
63 setbits8(cpld_base + CPLD_DIUCSR, CPLD_DIUCSR_BACKLIGHT);
64 break;
65 default:
66 pr_err("%s: Unsupported monitor port %i\n", __func__, port);
67 }
68
69 iounmap(cpld_base);
70exit:
71 of_node_put(cpld_node);
72}
73
74/**
75 * t1042rdb_set_pixel_clock: program the DIU's clock
76 * @pixclock: pixel clock in ps (pico seconds)
77 */
78static void t1042rdb_set_pixel_clock(unsigned int pixclock)
79{
80 struct device_node *scfg_np;
81 void __iomem *scfg;
82 unsigned long freq;
83 u64 temp;
84 u32 pxclk;
85
86 scfg_np = of_find_compatible_node(NULL, NULL, "fsl,t1040-scfg");
87 if (!scfg_np) {
88 pr_err("%s: Missing scfg node. Can not display video.\n",
89 __func__);
90 return;
91 }
92
93 scfg = of_iomap(scfg_np, 0);
94 of_node_put(scfg_np);
95 if (!scfg) {
96 pr_err("%s: Could not map device. Can not display video.\n",
97 __func__);
98 return;
99 }
100
101 /* Convert pixclock into frequency */
102 temp = 1000000000000ULL;
103 do_div(temp, pixclock);
104 freq = temp;
105
106 /*
107 * 'pxclk' is the ratio of the platform clock to the pixel clock.
108 * This number is programmed into the PIXCLKCR register, and the valid
109 * range of values is 2-255.
110 */
111 pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq);
112 pxclk = clamp_t(u32, pxclk, 2, 255);
113
114 /* Disable the pixel clock, and set it to non-inverted and no delay */
115 clrbits32(scfg + CCSR_SCFG_PIXCLKCR,
116 PIXCLKCR_PXCKEN | PIXCLKCR_PXCKDLY | PIXCLKCR_PXCLK_MASK);
117
118 /* Enable the clock and set the pxclk */
119 setbits32(scfg + CCSR_SCFG_PIXCLKCR, PIXCLKCR_PXCKEN | (pxclk << 16));
120
121 iounmap(scfg);
122}
123
124/**
125 * t1042rdb_valid_monitor_port: set the monitor port for sysfs
126 */
127static enum fsl_diu_monitor_port
128t1042rdb_valid_monitor_port(enum fsl_diu_monitor_port port)
129{
130 switch (port) {
131 case FSL_DIU_PORT_DVI:
132 case FSL_DIU_PORT_LVDS:
133 return port;
134 default:
135 return FSL_DIU_PORT_DVI; /* Dual-link LVDS is not supported */
136 }
137}
138
139static int __init t1042rdb_diu_init(void)
140{
141 cpld_node = of_find_compatible_node(NULL, NULL, "fsl,t1042rdb-cpld");
142 if (!cpld_node)
143 return 0;
144
145 diu_ops.set_monitor_port = t1042rdb_set_monitor_port;
146 diu_ops.set_pixel_clock = t1042rdb_set_pixel_clock;
147 diu_ops.valid_monitor_port = t1042rdb_valid_monitor_port;
148
149 return 0;
150}
151
152early_initcall(t1042rdb_diu_init);