1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2014 Freescale Semiconductor, Inc. 4 * 5 * FSL DCU Framebuffer driver 6 */ 7 8 #include <asm/io.h> 9 #include <common.h> 10 #include <fsl_dcu_fb.h> 11 #include <i2c.h> 12 #include "div64.h" 13 #include "../common/diu_ch7301.h" 14 #include "ls1021aqds_qixis.h" 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 static int select_i2c_ch_pca9547(u8 ch) 19 { 20 int ret; 21 22 ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1); 23 if (ret) { 24 puts("PCA: failed to select proper channel\n"); 25 return ret; 26 } 27 28 return 0; 29 } 30 31 unsigned int dcu_set_pixel_clock(unsigned int pixclock) 32 { 33 unsigned long long div; 34 35 div = (unsigned long long)(gd->bus_clk / 1000); 36 div *= (unsigned long long)pixclock; 37 do_div(div, 1000000000); 38 39 return div; 40 } 41 42 int platform_dcu_init(unsigned int xres, unsigned int yres, 43 const char *port, 44 struct fb_videomode *dcu_fb_videomode) 45 { 46 const char *name; 47 unsigned int pixel_format; 48 int ret; 49 u8 ch; 50 51 /* Mux I2C3+I2C4 as HSYNC+VSYNC */ 52 ret = i2c_read(CONFIG_SYS_I2C_QIXIS_ADDR, QIXIS_DCU_BRDCFG5, 53 1, &ch, 1); 54 if (ret) { 55 printf("Error: failed to read I2C @%02x\n", 56 CONFIG_SYS_I2C_QIXIS_ADDR); 57 return ret; 58 } 59 ch &= 0x1F; 60 ch |= 0xA0; 61 ret = i2c_write(CONFIG_SYS_I2C_QIXIS_ADDR, QIXIS_DCU_BRDCFG5, 62 1, &ch, 1); 63 if (ret) { 64 printf("Error: failed to write I2C @%02x\n", 65 CONFIG_SYS_I2C_QIXIS_ADDR); 66 return ret; 67 } 68 69 if (strncmp(port, "hdmi", 4) == 0) { 70 unsigned long pixval; 71 72 name = "HDMI"; 73 74 pixval = 1000000000 / dcu_fb_videomode->pixclock; 75 pixval *= 1000; 76 77 i2c_set_bus_num(CONFIG_SYS_I2C_DVI_BUS_NUM); 78 select_i2c_ch_pca9547(I2C_MUX_CH_CH7301); 79 diu_set_dvi_encoder(pixval); 80 select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); 81 } else { 82 return 0; 83 } 84 85 printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres); 86 87 pixel_format = 32; 88 fsl_dcu_init(xres, yres, pixel_format); 89 90 return 0; 91 } 92