1*cf8ddacfSJason Jin /*
2*cf8ddacfSJason Jin * Copyright 2014 Freescale Semiconductor, Inc.
3*cf8ddacfSJason Jin * Author: Priyanka Jain <Priyanka.Jain@freescale.com>
4*cf8ddacfSJason Jin *
5*cf8ddacfSJason Jin * SPDX-License-Identifier: GPL-2.0+
6*cf8ddacfSJason Jin */
7*cf8ddacfSJason Jin
8*cf8ddacfSJason Jin #include <asm/io.h>
9*cf8ddacfSJason Jin #include <common.h>
10*cf8ddacfSJason Jin #include <command.h>
11*cf8ddacfSJason Jin #include <fsl_diu_fb.h>
12*cf8ddacfSJason Jin #include <linux/ctype.h>
13*cf8ddacfSJason Jin #include <video_fb.h>
14*cf8ddacfSJason Jin
15*cf8ddacfSJason Jin #include "../common/diu_ch7301.h"
16*cf8ddacfSJason Jin
17*cf8ddacfSJason Jin #include "cpld.h"
18*cf8ddacfSJason Jin #include "t104xrdb.h"
19*cf8ddacfSJason Jin
20*cf8ddacfSJason Jin /*
21*cf8ddacfSJason Jin * DIU Area Descriptor
22*cf8ddacfSJason Jin *
23*cf8ddacfSJason Jin * Note that we need to byte-swap the value before it's written to the AD
24*cf8ddacfSJason Jin * register. So even though the registers don't look like they're in the same
25*cf8ddacfSJason Jin * bit positions as they are on the MPC8610, the same value is written to the
26*cf8ddacfSJason Jin * AD register on the MPC8610 and on the P1022.
27*cf8ddacfSJason Jin */
28*cf8ddacfSJason Jin #define AD_BYTE_F 0x10000000
29*cf8ddacfSJason Jin #define AD_ALPHA_C_SHIFT 25
30*cf8ddacfSJason Jin #define AD_BLUE_C_SHIFT 23
31*cf8ddacfSJason Jin #define AD_GREEN_C_SHIFT 21
32*cf8ddacfSJason Jin #define AD_RED_C_SHIFT 19
33*cf8ddacfSJason Jin #define AD_PIXEL_S_SHIFT 16
34*cf8ddacfSJason Jin #define AD_COMP_3_SHIFT 12
35*cf8ddacfSJason Jin #define AD_COMP_2_SHIFT 8
36*cf8ddacfSJason Jin #define AD_COMP_1_SHIFT 4
37*cf8ddacfSJason Jin #define AD_COMP_0_SHIFT 0
38*cf8ddacfSJason Jin
diu_set_pixel_clock(unsigned int pixclock)39*cf8ddacfSJason Jin void diu_set_pixel_clock(unsigned int pixclock)
40*cf8ddacfSJason Jin {
41*cf8ddacfSJason Jin unsigned long speed_ccb, temp;
42*cf8ddacfSJason Jin u32 pixval;
43*cf8ddacfSJason Jin int ret;
44*cf8ddacfSJason Jin
45*cf8ddacfSJason Jin speed_ccb = get_bus_freq(0);
46*cf8ddacfSJason Jin temp = 1000000000 / pixclock;
47*cf8ddacfSJason Jin temp *= 1000;
48*cf8ddacfSJason Jin pixval = speed_ccb / temp;
49*cf8ddacfSJason Jin
50*cf8ddacfSJason Jin /* Program HDMI encoder */
51*cf8ddacfSJason Jin ret = diu_set_dvi_encoder(temp);
52*cf8ddacfSJason Jin if (ret) {
53*cf8ddacfSJason Jin puts("Failed to set DVI encoder\n");
54*cf8ddacfSJason Jin return;
55*cf8ddacfSJason Jin }
56*cf8ddacfSJason Jin
57*cf8ddacfSJason Jin /* Program pixel clock */
58*cf8ddacfSJason Jin out_be32((unsigned *)CONFIG_SYS_FSL_SCFG_PIXCLK_ADDR,
59*cf8ddacfSJason Jin ((pixval << PXCK_BITS_START) & PXCK_MASK));
60*cf8ddacfSJason Jin
61*cf8ddacfSJason Jin /* enable clock*/
62*cf8ddacfSJason Jin out_be32((unsigned *)CONFIG_SYS_FSL_SCFG_PIXCLK_ADDR, PXCKEN_MASK |
63*cf8ddacfSJason Jin ((pixval << PXCK_BITS_START) & PXCK_MASK));
64*cf8ddacfSJason Jin }
65*cf8ddacfSJason Jin
platform_diu_init(unsigned int xres,unsigned int yres,const char * port)66*cf8ddacfSJason Jin int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
67*cf8ddacfSJason Jin {
68*cf8ddacfSJason Jin u32 pixel_format;
69*cf8ddacfSJason Jin u8 sw;
70*cf8ddacfSJason Jin
71*cf8ddacfSJason Jin /*Configure Display ouput port as HDMI*/
72*cf8ddacfSJason Jin sw = CPLD_READ(sfp_ctl_status);
73*cf8ddacfSJason Jin CPLD_WRITE(sfp_ctl_status , sw & ~(CPLD_DIU_SEL_DFP));
74*cf8ddacfSJason Jin
75*cf8ddacfSJason Jin pixel_format = cpu_to_le32(AD_BYTE_F | (3 << AD_ALPHA_C_SHIFT) |
76*cf8ddacfSJason Jin (0 << AD_BLUE_C_SHIFT) | (1 << AD_GREEN_C_SHIFT) |
77*cf8ddacfSJason Jin (2 << AD_RED_C_SHIFT) | (8 << AD_COMP_3_SHIFT) |
78*cf8ddacfSJason Jin (8 << AD_COMP_2_SHIFT) | (8 << AD_COMP_1_SHIFT) |
79*cf8ddacfSJason Jin (8 << AD_COMP_0_SHIFT) | (3 << AD_PIXEL_S_SHIFT));
80*cf8ddacfSJason Jin
81*cf8ddacfSJason Jin printf("DIU: Switching to monitor DVI @ %ux%u\n", xres, yres);
82*cf8ddacfSJason Jin
83*cf8ddacfSJason Jin return fsl_diu_init(xres, yres, pixel_format, 0);
84*cf8ddacfSJason Jin }
85