108a7aa1eSSimon Glass /* 208a7aa1eSSimon Glass * Copyright (C) 2012 Samsung Electronics 308a7aa1eSSimon Glass * 408a7aa1eSSimon Glass * Author: InKi Dae <inki.dae@samsung.com> 508a7aa1eSSimon Glass * Author: Donghwa Lee <dh09.lee@samsung.com> 608a7aa1eSSimon Glass * 708a7aa1eSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 808a7aa1eSSimon Glass */ 908a7aa1eSSimon Glass 1008a7aa1eSSimon Glass #include <config.h> 1108a7aa1eSSimon Glass #include <common.h> 12bb5930d5SSimon Glass #include <display.h> 130c84358cSSimon Glass #include <div64.h> 14bb5930d5SSimon Glass #include <dm.h> 1508a7aa1eSSimon Glass #include <fdtdec.h> 1608a7aa1eSSimon Glass #include <libfdt.h> 17bb5930d5SSimon Glass #include <panel.h> 18bb5930d5SSimon Glass #include <video.h> 19bb5930d5SSimon Glass #include <video_bridge.h> 2008a7aa1eSSimon Glass #include <asm/io.h> 2108a7aa1eSSimon Glass #include <asm/arch/cpu.h> 2208a7aa1eSSimon Glass #include <asm/arch/clock.h> 2308a7aa1eSSimon Glass #include <asm/arch/clk.h> 2408a7aa1eSSimon Glass #include <asm/arch/mipi_dsim.h> 2508a7aa1eSSimon Glass #include <asm/arch/dp_info.h> 26bb5930d5SSimon Glass #include <asm/arch/fb.h> 27bb5930d5SSimon Glass #include <asm/arch/pinmux.h> 2808a7aa1eSSimon Glass #include <asm/arch/system.h> 2908a7aa1eSSimon Glass #include <asm/gpio.h> 305d97dff0SMasahiro Yamada #include <linux/errno.h> 3108a7aa1eSSimon Glass 3208a7aa1eSSimon Glass DECLARE_GLOBAL_DATA_PTR; 3308a7aa1eSSimon Glass 34bb5930d5SSimon Glass enum { 35bb5930d5SSimon Glass FIMD_RGB_INTERFACE = 1, 36bb5930d5SSimon Glass FIMD_CPU_INTERFACE = 2, 3708a7aa1eSSimon Glass }; 3808a7aa1eSSimon Glass 39bb5930d5SSimon Glass enum exynos_fb_rgb_mode_t { 40bb5930d5SSimon Glass MODE_RGB_P = 0, 41bb5930d5SSimon Glass MODE_BGR_P = 1, 42bb5930d5SSimon Glass MODE_RGB_S = 2, 43bb5930d5SSimon Glass MODE_BGR_S = 3, 44bb5930d5SSimon Glass }; 45bb5930d5SSimon Glass 46bb5930d5SSimon Glass struct exynos_fb_priv { 47bb5930d5SSimon Glass ushort vl_col; /* Number of columns (i.e. 640) */ 48bb5930d5SSimon Glass ushort vl_row; /* Number of rows (i.e. 480) */ 49bb5930d5SSimon Glass ushort vl_rot; /* Rotation of Display (0, 1, 2, 3) */ 50bb5930d5SSimon Glass ushort vl_width; /* Width of display area in millimeters */ 51bb5930d5SSimon Glass ushort vl_height; /* Height of display area in millimeters */ 52bb5930d5SSimon Glass 53bb5930d5SSimon Glass /* LCD configuration register */ 54bb5930d5SSimon Glass u_char vl_freq; /* Frequency */ 55bb5930d5SSimon Glass u_char vl_clkp; /* Clock polarity */ 56bb5930d5SSimon Glass u_char vl_oep; /* Output Enable polarity */ 57bb5930d5SSimon Glass u_char vl_hsp; /* Horizontal Sync polarity */ 58bb5930d5SSimon Glass u_char vl_vsp; /* Vertical Sync polarity */ 59bb5930d5SSimon Glass u_char vl_dp; /* Data polarity */ 60bb5930d5SSimon Glass u_char vl_bpix; /* Bits per pixel */ 61bb5930d5SSimon Glass 62bb5930d5SSimon Glass /* Horizontal control register. Timing from data sheet */ 63bb5930d5SSimon Glass u_char vl_hspw; /* Horz sync pulse width */ 64bb5930d5SSimon Glass u_char vl_hfpd; /* Wait before of line */ 65bb5930d5SSimon Glass u_char vl_hbpd; /* Wait end of line */ 66bb5930d5SSimon Glass 67bb5930d5SSimon Glass /* Vertical control register. */ 68bb5930d5SSimon Glass u_char vl_vspw; /* Vertical sync pulse width */ 69bb5930d5SSimon Glass u_char vl_vfpd; /* Wait before of frame */ 70bb5930d5SSimon Glass u_char vl_vbpd; /* Wait end of frame */ 71bb5930d5SSimon Glass u_char vl_cmd_allow_len; /* Wait end of frame */ 72bb5930d5SSimon Glass 73bb5930d5SSimon Glass unsigned int win_id; 74bb5930d5SSimon Glass unsigned int init_delay; 75bb5930d5SSimon Glass unsigned int power_on_delay; 76bb5930d5SSimon Glass unsigned int reset_delay; 77bb5930d5SSimon Glass unsigned int interface_mode; 78bb5930d5SSimon Glass unsigned int mipi_enabled; 79bb5930d5SSimon Glass unsigned int dp_enabled; 80bb5930d5SSimon Glass unsigned int cs_setup; 81bb5930d5SSimon Glass unsigned int wr_setup; 82bb5930d5SSimon Glass unsigned int wr_act; 83bb5930d5SSimon Glass unsigned int wr_hold; 84bb5930d5SSimon Glass unsigned int logo_on; 85bb5930d5SSimon Glass unsigned int logo_width; 86bb5930d5SSimon Glass unsigned int logo_height; 87bb5930d5SSimon Glass int logo_x_offset; 88bb5930d5SSimon Glass int logo_y_offset; 89bb5930d5SSimon Glass unsigned long logo_addr; 90bb5930d5SSimon Glass unsigned int rgb_mode; 91bb5930d5SSimon Glass unsigned int resolution; 92bb5930d5SSimon Glass 93bb5930d5SSimon Glass /* parent clock name(MPLL, EPLL or VPLL) */ 94bb5930d5SSimon Glass unsigned int pclk_name; 95bb5930d5SSimon Glass /* ratio value for source clock from parent clock. */ 96bb5930d5SSimon Glass unsigned int sclk_div; 97bb5930d5SSimon Glass 98bb5930d5SSimon Glass unsigned int dual_lcd_enabled; 99bb5930d5SSimon Glass struct exynos_fb *reg; 100bb5930d5SSimon Glass struct exynos_platform_mipi_dsim *dsim_platform_data_dt; 101bb5930d5SSimon Glass }; 102bb5930d5SSimon Glass 103bb5930d5SSimon Glass static void exynos_fimd_set_dualrgb(struct exynos_fb_priv *priv, bool enabled) 1040c84358cSSimon Glass { 1058b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 1060c84358cSSimon Glass unsigned int cfg = 0; 1070c84358cSSimon Glass 1080c84358cSSimon Glass if (enabled) { 1090c84358cSSimon Glass cfg = EXYNOS_DUALRGB_BYPASS_DUAL | EXYNOS_DUALRGB_LINESPLIT | 1100c84358cSSimon Glass EXYNOS_DUALRGB_VDEN_EN_ENABLE; 1110c84358cSSimon Glass 1120c84358cSSimon Glass /* in case of Line Split mode, MAIN_CNT doesn't neet to set. */ 1138b449a66SSimon Glass cfg |= EXYNOS_DUALRGB_SUB_CNT(priv->vl_col / 2) | 1140c84358cSSimon Glass EXYNOS_DUALRGB_MAIN_CNT(0); 1150c84358cSSimon Glass } 1160c84358cSSimon Glass 1178b449a66SSimon Glass writel(cfg, ®->dualrgb); 1180c84358cSSimon Glass } 1190c84358cSSimon Glass 120bb5930d5SSimon Glass static void exynos_fimd_set_dp_clkcon(struct exynos_fb_priv *priv, 1210c84358cSSimon Glass unsigned int enabled) 1220c84358cSSimon Glass { 1238b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 1240c84358cSSimon Glass unsigned int cfg = 0; 1250c84358cSSimon Glass 1260c84358cSSimon Glass if (enabled) 1270c84358cSSimon Glass cfg = EXYNOS_DP_CLK_ENABLE; 1280c84358cSSimon Glass 1298b449a66SSimon Glass writel(cfg, ®->dp_mie_clkcon); 1300c84358cSSimon Glass } 1310c84358cSSimon Glass 132bb5930d5SSimon Glass static void exynos_fimd_set_par(struct exynos_fb_priv *priv, 133bb5930d5SSimon Glass unsigned int win_id) 1340c84358cSSimon Glass { 1358b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 1360c84358cSSimon Glass unsigned int cfg = 0; 1370c84358cSSimon Glass 1380c84358cSSimon Glass /* set window control */ 1398b449a66SSimon Glass cfg = readl((unsigned int)®->wincon0 + 1400c84358cSSimon Glass EXYNOS_WINCON(win_id)); 1410c84358cSSimon Glass 1420c84358cSSimon Glass cfg &= ~(EXYNOS_WINCON_BITSWP_ENABLE | EXYNOS_WINCON_BYTESWP_ENABLE | 1430c84358cSSimon Glass EXYNOS_WINCON_HAWSWP_ENABLE | EXYNOS_WINCON_WSWP_ENABLE | 1440c84358cSSimon Glass EXYNOS_WINCON_BURSTLEN_MASK | EXYNOS_WINCON_BPPMODE_MASK | 1450c84358cSSimon Glass EXYNOS_WINCON_INRGB_MASK | EXYNOS_WINCON_DATAPATH_MASK); 1460c84358cSSimon Glass 1470c84358cSSimon Glass /* DATAPATH is DMA */ 1480c84358cSSimon Glass cfg |= EXYNOS_WINCON_DATAPATH_DMA; 1490c84358cSSimon Glass 1500c84358cSSimon Glass cfg |= EXYNOS_WINCON_HAWSWP_ENABLE; 1510c84358cSSimon Glass 1520c84358cSSimon Glass /* dma burst is 16 */ 1530c84358cSSimon Glass cfg |= EXYNOS_WINCON_BURSTLEN_16WORD; 1540c84358cSSimon Glass 1558b449a66SSimon Glass switch (priv->vl_bpix) { 1560c84358cSSimon Glass case 4: 1570c84358cSSimon Glass cfg |= EXYNOS_WINCON_BPPMODE_16BPP_565; 1580c84358cSSimon Glass break; 1590c84358cSSimon Glass default: 1600c84358cSSimon Glass cfg |= EXYNOS_WINCON_BPPMODE_24BPP_888; 1610c84358cSSimon Glass break; 1620c84358cSSimon Glass } 1630c84358cSSimon Glass 1648b449a66SSimon Glass writel(cfg, (unsigned int)®->wincon0 + 1650c84358cSSimon Glass EXYNOS_WINCON(win_id)); 1660c84358cSSimon Glass 1670c84358cSSimon Glass /* set window position to x=0, y=0*/ 1680c84358cSSimon Glass cfg = EXYNOS_VIDOSD_LEFT_X(0) | EXYNOS_VIDOSD_TOP_Y(0); 1698b449a66SSimon Glass writel(cfg, (unsigned int)®->vidosd0a + 1700c84358cSSimon Glass EXYNOS_VIDOSD(win_id)); 1710c84358cSSimon Glass 1728b449a66SSimon Glass cfg = EXYNOS_VIDOSD_RIGHT_X(priv->vl_col - 1) | 1738b449a66SSimon Glass EXYNOS_VIDOSD_BOTTOM_Y(priv->vl_row - 1) | 1740c84358cSSimon Glass EXYNOS_VIDOSD_RIGHT_X_E(1) | 1750c84358cSSimon Glass EXYNOS_VIDOSD_BOTTOM_Y_E(0); 1760c84358cSSimon Glass 1778b449a66SSimon Glass writel(cfg, (unsigned int)®->vidosd0b + 1780c84358cSSimon Glass EXYNOS_VIDOSD(win_id)); 1790c84358cSSimon Glass 1800c84358cSSimon Glass /* set window size for window0*/ 1818b449a66SSimon Glass cfg = EXYNOS_VIDOSD_SIZE(priv->vl_col * priv->vl_row); 1828b449a66SSimon Glass writel(cfg, (unsigned int)®->vidosd0c + 1830c84358cSSimon Glass EXYNOS_VIDOSD(win_id)); 1840c84358cSSimon Glass } 1850c84358cSSimon Glass 186bb5930d5SSimon Glass static void exynos_fimd_set_buffer_address(struct exynos_fb_priv *priv, 1870c84358cSSimon Glass unsigned int win_id, 1880c84358cSSimon Glass ulong lcd_base_addr) 1890c84358cSSimon Glass { 1908b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 1910c84358cSSimon Glass unsigned long start_addr, end_addr; 1920c84358cSSimon Glass 1930c84358cSSimon Glass start_addr = lcd_base_addr; 194bb5930d5SSimon Glass end_addr = start_addr + ((priv->vl_col * (VNBITS(priv->vl_bpix) / 8)) * 1958b449a66SSimon Glass priv->vl_row); 1960c84358cSSimon Glass 1978b449a66SSimon Glass writel(start_addr, (unsigned int)®->vidw00add0b0 + 1980c84358cSSimon Glass EXYNOS_BUFFER_OFFSET(win_id)); 1998b449a66SSimon Glass writel(end_addr, (unsigned int)®->vidw00add1b0 + 2000c84358cSSimon Glass EXYNOS_BUFFER_OFFSET(win_id)); 2010c84358cSSimon Glass } 2020c84358cSSimon Glass 203bb5930d5SSimon Glass static void exynos_fimd_set_clock(struct exynos_fb_priv *priv) 2040c84358cSSimon Glass { 2058b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 2060c84358cSSimon Glass unsigned int cfg = 0, div = 0, remainder, remainder_div; 2070c84358cSSimon Glass unsigned long pixel_clock; 2080c84358cSSimon Glass unsigned long long src_clock; 2090c84358cSSimon Glass 2108b449a66SSimon Glass if (priv->dual_lcd_enabled) { 2118b449a66SSimon Glass pixel_clock = priv->vl_freq * 2128b449a66SSimon Glass (priv->vl_hspw + priv->vl_hfpd + 2138b449a66SSimon Glass priv->vl_hbpd + priv->vl_col / 2) * 2148b449a66SSimon Glass (priv->vl_vspw + priv->vl_vfpd + 2158b449a66SSimon Glass priv->vl_vbpd + priv->vl_row); 2168b449a66SSimon Glass } else if (priv->interface_mode == FIMD_CPU_INTERFACE) { 2178b449a66SSimon Glass pixel_clock = priv->vl_freq * 2188b449a66SSimon Glass priv->vl_width * priv->vl_height * 2198b449a66SSimon Glass (priv->cs_setup + priv->wr_setup + 2208b449a66SSimon Glass priv->wr_act + priv->wr_hold + 1); 2210c84358cSSimon Glass } else { 2228b449a66SSimon Glass pixel_clock = priv->vl_freq * 2238b449a66SSimon Glass (priv->vl_hspw + priv->vl_hfpd + 2248b449a66SSimon Glass priv->vl_hbpd + priv->vl_col) * 2258b449a66SSimon Glass (priv->vl_vspw + priv->vl_vfpd + 2268b449a66SSimon Glass priv->vl_vbpd + priv->vl_row); 2270c84358cSSimon Glass } 2280c84358cSSimon Glass 2298b449a66SSimon Glass cfg = readl(®->vidcon0); 2300c84358cSSimon Glass cfg &= ~(EXYNOS_VIDCON0_CLKSEL_MASK | EXYNOS_VIDCON0_CLKVALUP_MASK | 2310c84358cSSimon Glass EXYNOS_VIDCON0_CLKVAL_F(0xFF) | EXYNOS_VIDCON0_VCLKEN_MASK | 2320c84358cSSimon Glass EXYNOS_VIDCON0_CLKDIR_MASK); 2330c84358cSSimon Glass cfg |= (EXYNOS_VIDCON0_CLKSEL_SCLK | EXYNOS_VIDCON0_CLKVALUP_ALWAYS | 2340c84358cSSimon Glass EXYNOS_VIDCON0_VCLKEN_NORMAL | EXYNOS_VIDCON0_CLKDIR_DIVIDED); 2350c84358cSSimon Glass 2360c84358cSSimon Glass src_clock = (unsigned long long) get_lcd_clk(); 2370c84358cSSimon Glass 2380c84358cSSimon Glass /* get quotient and remainder. */ 2390c84358cSSimon Glass remainder = do_div(src_clock, pixel_clock); 2400c84358cSSimon Glass div = src_clock; 2410c84358cSSimon Glass 2420c84358cSSimon Glass remainder *= 10; 2430c84358cSSimon Glass remainder_div = remainder / pixel_clock; 2440c84358cSSimon Glass 2450c84358cSSimon Glass /* round about one places of decimals. */ 2460c84358cSSimon Glass if (remainder_div >= 5) 2470c84358cSSimon Glass div++; 2480c84358cSSimon Glass 2490c84358cSSimon Glass /* in case of dual lcd mode. */ 2508b449a66SSimon Glass if (priv->dual_lcd_enabled) 2510c84358cSSimon Glass div--; 2520c84358cSSimon Glass 2530c84358cSSimon Glass cfg |= EXYNOS_VIDCON0_CLKVAL_F(div - 1); 2548b449a66SSimon Glass writel(cfg, ®->vidcon0); 2550c84358cSSimon Glass } 2560c84358cSSimon Glass 257bb5930d5SSimon Glass void exynos_set_trigger(struct exynos_fb_priv *priv) 2580c84358cSSimon Glass { 2598b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 2600c84358cSSimon Glass unsigned int cfg = 0; 2610c84358cSSimon Glass 2628b449a66SSimon Glass cfg = readl(®->trigcon); 2630c84358cSSimon Glass 2640c84358cSSimon Glass cfg |= (EXYNOS_I80SOFT_TRIG_EN | EXYNOS_I80START_TRIG); 2650c84358cSSimon Glass 2668b449a66SSimon Glass writel(cfg, ®->trigcon); 2670c84358cSSimon Glass } 2680c84358cSSimon Glass 269bb5930d5SSimon Glass int exynos_is_i80_frame_done(struct exynos_fb_priv *priv) 2700c84358cSSimon Glass { 2718b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 2720c84358cSSimon Glass unsigned int cfg = 0; 2730c84358cSSimon Glass int status; 2740c84358cSSimon Glass 2758b449a66SSimon Glass cfg = readl(®->trigcon); 2760c84358cSSimon Glass 2770c84358cSSimon Glass /* frame done func is valid only when TRIMODE[0] is set to 1. */ 2780c84358cSSimon Glass status = (cfg & EXYNOS_I80STATUS_TRIG_DONE) == 2790c84358cSSimon Glass EXYNOS_I80STATUS_TRIG_DONE; 2800c84358cSSimon Glass 2810c84358cSSimon Glass return status; 2820c84358cSSimon Glass } 2830c84358cSSimon Glass 284bb5930d5SSimon Glass static void exynos_fimd_lcd_on(struct exynos_fb_priv *priv) 2850c84358cSSimon Glass { 2868b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 2870c84358cSSimon Glass unsigned int cfg = 0; 2880c84358cSSimon Glass 2890c84358cSSimon Glass /* display on */ 2908b449a66SSimon Glass cfg = readl(®->vidcon0); 2910c84358cSSimon Glass cfg |= (EXYNOS_VIDCON0_ENVID_ENABLE | EXYNOS_VIDCON0_ENVID_F_ENABLE); 2928b449a66SSimon Glass writel(cfg, ®->vidcon0); 2930c84358cSSimon Glass } 2940c84358cSSimon Glass 295bb5930d5SSimon Glass static void exynos_fimd_window_on(struct exynos_fb_priv *priv, 296bb5930d5SSimon Glass unsigned int win_id) 2970c84358cSSimon Glass { 2988b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 2990c84358cSSimon Glass unsigned int cfg = 0; 3000c84358cSSimon Glass 3010c84358cSSimon Glass /* enable window */ 3028b449a66SSimon Glass cfg = readl((unsigned int)®->wincon0 + 3030c84358cSSimon Glass EXYNOS_WINCON(win_id)); 3040c84358cSSimon Glass cfg |= EXYNOS_WINCON_ENWIN_ENABLE; 3058b449a66SSimon Glass writel(cfg, (unsigned int)®->wincon0 + 3060c84358cSSimon Glass EXYNOS_WINCON(win_id)); 3070c84358cSSimon Glass 3088b449a66SSimon Glass cfg = readl(®->winshmap); 3090c84358cSSimon Glass cfg |= EXYNOS_WINSHMAP_CH_ENABLE(win_id); 3108b449a66SSimon Glass writel(cfg, ®->winshmap); 3110c84358cSSimon Glass } 3120c84358cSSimon Glass 313bb5930d5SSimon Glass void exynos_fimd_lcd_off(struct exynos_fb_priv *priv) 3140c84358cSSimon Glass { 3158b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 3160c84358cSSimon Glass unsigned int cfg = 0; 3170c84358cSSimon Glass 3188b449a66SSimon Glass cfg = readl(®->vidcon0); 3190c84358cSSimon Glass cfg &= (EXYNOS_VIDCON0_ENVID_DISABLE | EXYNOS_VIDCON0_ENVID_F_DISABLE); 3208b449a66SSimon Glass writel(cfg, ®->vidcon0); 3210c84358cSSimon Glass } 3220c84358cSSimon Glass 323bb5930d5SSimon Glass void exynos_fimd_window_off(struct exynos_fb_priv *priv, unsigned int win_id) 3240c84358cSSimon Glass { 3258b449a66SSimon Glass struct exynos_fb *reg = priv->reg; 3260c84358cSSimon Glass unsigned int cfg = 0; 3270c84358cSSimon Glass 3288b449a66SSimon Glass cfg = readl((unsigned int)®->wincon0 + 3290c84358cSSimon Glass EXYNOS_WINCON(win_id)); 3300c84358cSSimon Glass cfg &= EXYNOS_WINCON_ENWIN_DISABLE; 3318b449a66SSimon Glass writel(cfg, (unsigned int)®->wincon0 + 3320c84358cSSimon Glass EXYNOS_WINCON(win_id)); 3330c84358cSSimon Glass 3348b449a66SSimon Glass cfg = readl(®->winshmap); 3350c84358cSSimon Glass cfg &= ~EXYNOS_WINSHMAP_CH_DISABLE(win_id); 3368b449a66SSimon Glass writel(cfg, ®->winshmap); 3370c84358cSSimon Glass } 3380c84358cSSimon Glass 3390c84358cSSimon Glass /* 3400c84358cSSimon Glass * The reset value for FIMD SYSMMU register MMU_CTRL is 3 3410c84358cSSimon Glass * on Exynos5420 and newer versions. 3420c84358cSSimon Glass * This means FIMD SYSMMU is on by default on Exynos5420 3430c84358cSSimon Glass * and newer versions. 3440c84358cSSimon Glass * Since in u-boot we don't use SYSMMU, we should disable 3450c84358cSSimon Glass * those FIMD SYSMMU. 3460c84358cSSimon Glass * Note that there are 2 SYSMMU for FIMD: m0 and m1. 3470c84358cSSimon Glass * m0 handles windows 0 and 4, and m1 handles windows 1, 2 and 3. 3480c84358cSSimon Glass * We disable both of them here. 3490c84358cSSimon Glass */ 3500c84358cSSimon Glass void exynos_fimd_disable_sysmmu(void) 3510c84358cSSimon Glass { 3520c84358cSSimon Glass u32 *sysmmufimd; 3530c84358cSSimon Glass unsigned int node; 3540c84358cSSimon Glass int node_list[2]; 3550c84358cSSimon Glass int count; 3560c84358cSSimon Glass int i; 3570c84358cSSimon Glass 3580c84358cSSimon Glass count = fdtdec_find_aliases_for_id(gd->fdt_blob, "fimd", 3590c84358cSSimon Glass COMPAT_SAMSUNG_EXYNOS_SYSMMU, node_list, 2); 3600c84358cSSimon Glass for (i = 0; i < count; i++) { 3610c84358cSSimon Glass node = node_list[i]; 3620c84358cSSimon Glass if (node <= 0) { 3630c84358cSSimon Glass debug("Can't get device node for fimd sysmmu\n"); 3640c84358cSSimon Glass return; 3650c84358cSSimon Glass } 3660c84358cSSimon Glass 3670c84358cSSimon Glass sysmmufimd = (u32 *)fdtdec_get_addr(gd->fdt_blob, node, "reg"); 3680c84358cSSimon Glass if (!sysmmufimd) { 3690c84358cSSimon Glass debug("Can't get base address for sysmmu fimdm0"); 3700c84358cSSimon Glass return; 3710c84358cSSimon Glass } 3720c84358cSSimon Glass 3730c84358cSSimon Glass writel(0x0, sysmmufimd); 3740c84358cSSimon Glass } 3750c84358cSSimon Glass } 3760c84358cSSimon Glass 377bb5930d5SSimon Glass void exynos_fimd_lcd_init(struct udevice *dev) 3780c84358cSSimon Glass { 379bb5930d5SSimon Glass struct exynos_fb_priv *priv = dev_get_priv(dev); 380bb5930d5SSimon Glass struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 381bb5930d5SSimon Glass struct exynos_fb *reg = priv->reg; 3820c84358cSSimon Glass unsigned int cfg = 0, rgb_mode; 3830c84358cSSimon Glass unsigned int offset; 3840c84358cSSimon Glass unsigned int node; 3850c84358cSSimon Glass 386e160f7d4SSimon Glass node = dev_of_offset(dev); 3870c84358cSSimon Glass if (fdtdec_get_bool(gd->fdt_blob, node, "samsung,disable-sysmmu")) 3880c84358cSSimon Glass exynos_fimd_disable_sysmmu(); 3890c84358cSSimon Glass 3900c84358cSSimon Glass offset = exynos_fimd_get_base_offset(); 3910c84358cSSimon Glass 3928b449a66SSimon Glass rgb_mode = priv->rgb_mode; 3930c84358cSSimon Glass 3948b449a66SSimon Glass if (priv->interface_mode == FIMD_RGB_INTERFACE) { 3950c84358cSSimon Glass cfg |= EXYNOS_VIDCON0_VIDOUT_RGB; 3968b449a66SSimon Glass writel(cfg, ®->vidcon0); 3970c84358cSSimon Glass 3988b449a66SSimon Glass cfg = readl(®->vidcon2); 3990c84358cSSimon Glass cfg &= ~(EXYNOS_VIDCON2_WB_MASK | 4000c84358cSSimon Glass EXYNOS_VIDCON2_TVFORMATSEL_MASK | 4010c84358cSSimon Glass EXYNOS_VIDCON2_TVFORMATSEL_YUV_MASK); 4020c84358cSSimon Glass cfg |= EXYNOS_VIDCON2_WB_DISABLE; 4038b449a66SSimon Glass writel(cfg, ®->vidcon2); 4040c84358cSSimon Glass 4050c84358cSSimon Glass /* set polarity */ 4060c84358cSSimon Glass cfg = 0; 4078b449a66SSimon Glass if (!priv->vl_clkp) 4080c84358cSSimon Glass cfg |= EXYNOS_VIDCON1_IVCLK_RISING_EDGE; 4098b449a66SSimon Glass if (!priv->vl_hsp) 4100c84358cSSimon Glass cfg |= EXYNOS_VIDCON1_IHSYNC_INVERT; 4118b449a66SSimon Glass if (!priv->vl_vsp) 4120c84358cSSimon Glass cfg |= EXYNOS_VIDCON1_IVSYNC_INVERT; 4138b449a66SSimon Glass if (!priv->vl_dp) 4140c84358cSSimon Glass cfg |= EXYNOS_VIDCON1_IVDEN_INVERT; 4150c84358cSSimon Glass 4168b449a66SSimon Glass writel(cfg, (unsigned int)®->vidcon1 + offset); 4170c84358cSSimon Glass 4180c84358cSSimon Glass /* set timing */ 4198b449a66SSimon Glass cfg = EXYNOS_VIDTCON0_VFPD(priv->vl_vfpd - 1); 4208b449a66SSimon Glass cfg |= EXYNOS_VIDTCON0_VBPD(priv->vl_vbpd - 1); 4218b449a66SSimon Glass cfg |= EXYNOS_VIDTCON0_VSPW(priv->vl_vspw - 1); 4228b449a66SSimon Glass writel(cfg, (unsigned int)®->vidtcon0 + offset); 4230c84358cSSimon Glass 4248b449a66SSimon Glass cfg = EXYNOS_VIDTCON1_HFPD(priv->vl_hfpd - 1); 4258b449a66SSimon Glass cfg |= EXYNOS_VIDTCON1_HBPD(priv->vl_hbpd - 1); 4268b449a66SSimon Glass cfg |= EXYNOS_VIDTCON1_HSPW(priv->vl_hspw - 1); 4270c84358cSSimon Glass 4288b449a66SSimon Glass writel(cfg, (unsigned int)®->vidtcon1 + offset); 4290c84358cSSimon Glass 4300c84358cSSimon Glass /* set lcd size */ 4318b449a66SSimon Glass cfg = EXYNOS_VIDTCON2_HOZVAL(priv->vl_col - 1) | 4328b449a66SSimon Glass EXYNOS_VIDTCON2_LINEVAL(priv->vl_row - 1) | 4338b449a66SSimon Glass EXYNOS_VIDTCON2_HOZVAL_E(priv->vl_col - 1) | 4348b449a66SSimon Glass EXYNOS_VIDTCON2_LINEVAL_E(priv->vl_row - 1); 4350c84358cSSimon Glass 4368b449a66SSimon Glass writel(cfg, (unsigned int)®->vidtcon2 + offset); 4370c84358cSSimon Glass } 4380c84358cSSimon Glass 4390c84358cSSimon Glass /* set display mode */ 4408b449a66SSimon Glass cfg = readl(®->vidcon0); 4410c84358cSSimon Glass cfg &= ~EXYNOS_VIDCON0_PNRMODE_MASK; 4420c84358cSSimon Glass cfg |= (rgb_mode << EXYNOS_VIDCON0_PNRMODE_SHIFT); 4438b449a66SSimon Glass writel(cfg, ®->vidcon0); 4440c84358cSSimon Glass 4450c84358cSSimon Glass /* set par */ 4468b449a66SSimon Glass exynos_fimd_set_par(priv, priv->win_id); 4470c84358cSSimon Glass 4480c84358cSSimon Glass /* set memory address */ 449bb5930d5SSimon Glass exynos_fimd_set_buffer_address(priv, priv->win_id, plat->base); 4500c84358cSSimon Glass 4510c84358cSSimon Glass /* set buffer size */ 4528b449a66SSimon Glass cfg = EXYNOS_VIDADDR_PAGEWIDTH(priv->vl_col * 453bb5930d5SSimon Glass VNBITS(priv->vl_bpix) / 8) | 4548b449a66SSimon Glass EXYNOS_VIDADDR_PAGEWIDTH_E(priv->vl_col * 455bb5930d5SSimon Glass VNBITS(priv->vl_bpix) / 8) | 4560c84358cSSimon Glass EXYNOS_VIDADDR_OFFSIZE(0) | 4570c84358cSSimon Glass EXYNOS_VIDADDR_OFFSIZE_E(0); 4580c84358cSSimon Glass 4598b449a66SSimon Glass writel(cfg, (unsigned int)®->vidw00add2 + 4608b449a66SSimon Glass EXYNOS_BUFFER_SIZE(priv->win_id)); 4610c84358cSSimon Glass 4620c84358cSSimon Glass /* set clock */ 4638b449a66SSimon Glass exynos_fimd_set_clock(priv); 4640c84358cSSimon Glass 4650c84358cSSimon Glass /* set rgb mode to dual lcd. */ 4668b449a66SSimon Glass exynos_fimd_set_dualrgb(priv, priv->dual_lcd_enabled); 4670c84358cSSimon Glass 4680c84358cSSimon Glass /* display on */ 4698b449a66SSimon Glass exynos_fimd_lcd_on(priv); 4700c84358cSSimon Glass 4710c84358cSSimon Glass /* window on */ 4728b449a66SSimon Glass exynos_fimd_window_on(priv, priv->win_id); 4730c84358cSSimon Glass 4748b449a66SSimon Glass exynos_fimd_set_dp_clkcon(priv, priv->dp_enabled); 4750c84358cSSimon Glass } 4760c84358cSSimon Glass 477bb5930d5SSimon Glass unsigned long exynos_fimd_calc_fbsize(struct exynos_fb_priv *priv) 4780c84358cSSimon Glass { 479bb5930d5SSimon Glass return priv->vl_col * priv->vl_row * (VNBITS(priv->vl_bpix) / 8); 48008a7aa1eSSimon Glass } 48108a7aa1eSSimon Glass 482bb5930d5SSimon Glass int exynos_fb_ofdata_to_platdata(struct udevice *dev) 48308a7aa1eSSimon Glass { 484bb5930d5SSimon Glass struct exynos_fb_priv *priv = dev_get_priv(dev); 485e160f7d4SSimon Glass unsigned int node = dev_of_offset(dev); 486bb5930d5SSimon Glass const void *blob = gd->fdt_blob; 487bb5930d5SSimon Glass fdt_addr_t addr; 48808a7aa1eSSimon Glass 489*a821c4afSSimon Glass addr = devfdt_get_addr(dev); 490bb5930d5SSimon Glass if (addr == FDT_ADDR_T_NONE) { 491bb5930d5SSimon Glass debug("Can't get the FIMD base address\n"); 492bb5930d5SSimon Glass return -EINVAL; 49308a7aa1eSSimon Glass } 494bb5930d5SSimon Glass priv->reg = (struct exynos_fb *)addr; 49508a7aa1eSSimon Glass 496bb5930d5SSimon Glass priv->vl_col = fdtdec_get_int(blob, node, "samsung,vl-col", 0); 497bb5930d5SSimon Glass if (priv->vl_col == 0) { 49808a7aa1eSSimon Glass debug("Can't get XRES\n"); 49908a7aa1eSSimon Glass return -ENXIO; 50008a7aa1eSSimon Glass } 50108a7aa1eSSimon Glass 502bb5930d5SSimon Glass priv->vl_row = fdtdec_get_int(blob, node, "samsung,vl-row", 0); 503bb5930d5SSimon Glass if (priv->vl_row == 0) { 50408a7aa1eSSimon Glass debug("Can't get YRES\n"); 50508a7aa1eSSimon Glass return -ENXIO; 50608a7aa1eSSimon Glass } 50708a7aa1eSSimon Glass 508bb5930d5SSimon Glass priv->vl_width = fdtdec_get_int(blob, node, 50908a7aa1eSSimon Glass "samsung,vl-width", 0); 51008a7aa1eSSimon Glass 511bb5930d5SSimon Glass priv->vl_height = fdtdec_get_int(blob, node, 51208a7aa1eSSimon Glass "samsung,vl-height", 0); 51308a7aa1eSSimon Glass 514bb5930d5SSimon Glass priv->vl_freq = fdtdec_get_int(blob, node, "samsung,vl-freq", 0); 515bb5930d5SSimon Glass if (priv->vl_freq == 0) { 51608a7aa1eSSimon Glass debug("Can't get refresh rate\n"); 51708a7aa1eSSimon Glass return -ENXIO; 51808a7aa1eSSimon Glass } 51908a7aa1eSSimon Glass 52008a7aa1eSSimon Glass if (fdtdec_get_bool(blob, node, "samsung,vl-clkp")) 521bb5930d5SSimon Glass priv->vl_clkp = VIDEO_ACTIVE_LOW; 52208a7aa1eSSimon Glass 52308a7aa1eSSimon Glass if (fdtdec_get_bool(blob, node, "samsung,vl-oep")) 524bb5930d5SSimon Glass priv->vl_oep = VIDEO_ACTIVE_LOW; 52508a7aa1eSSimon Glass 52608a7aa1eSSimon Glass if (fdtdec_get_bool(blob, node, "samsung,vl-hsp")) 527bb5930d5SSimon Glass priv->vl_hsp = VIDEO_ACTIVE_LOW; 52808a7aa1eSSimon Glass 52908a7aa1eSSimon Glass if (fdtdec_get_bool(blob, node, "samsung,vl-vsp")) 530bb5930d5SSimon Glass priv->vl_vsp = VIDEO_ACTIVE_LOW; 53108a7aa1eSSimon Glass 53208a7aa1eSSimon Glass if (fdtdec_get_bool(blob, node, "samsung,vl-dp")) 533bb5930d5SSimon Glass priv->vl_dp = VIDEO_ACTIVE_LOW; 53408a7aa1eSSimon Glass 535bb5930d5SSimon Glass priv->vl_bpix = fdtdec_get_int(blob, node, "samsung,vl-bpix", 0); 536bb5930d5SSimon Glass if (priv->vl_bpix == 0) { 53708a7aa1eSSimon Glass debug("Can't get bits per pixel\n"); 53808a7aa1eSSimon Glass return -ENXIO; 53908a7aa1eSSimon Glass } 54008a7aa1eSSimon Glass 541bb5930d5SSimon Glass priv->vl_hspw = fdtdec_get_int(blob, node, "samsung,vl-hspw", 0); 542bb5930d5SSimon Glass if (priv->vl_hspw == 0) { 54308a7aa1eSSimon Glass debug("Can't get hsync width\n"); 54408a7aa1eSSimon Glass return -ENXIO; 54508a7aa1eSSimon Glass } 54608a7aa1eSSimon Glass 547bb5930d5SSimon Glass priv->vl_hfpd = fdtdec_get_int(blob, node, "samsung,vl-hfpd", 0); 548bb5930d5SSimon Glass if (priv->vl_hfpd == 0) { 54908a7aa1eSSimon Glass debug("Can't get right margin\n"); 55008a7aa1eSSimon Glass return -ENXIO; 55108a7aa1eSSimon Glass } 55208a7aa1eSSimon Glass 553bb5930d5SSimon Glass priv->vl_hbpd = (u_char)fdtdec_get_int(blob, node, 55408a7aa1eSSimon Glass "samsung,vl-hbpd", 0); 555bb5930d5SSimon Glass if (priv->vl_hbpd == 0) { 55608a7aa1eSSimon Glass debug("Can't get left margin\n"); 55708a7aa1eSSimon Glass return -ENXIO; 55808a7aa1eSSimon Glass } 55908a7aa1eSSimon Glass 560bb5930d5SSimon Glass priv->vl_vspw = (u_char)fdtdec_get_int(blob, node, 56108a7aa1eSSimon Glass "samsung,vl-vspw", 0); 562bb5930d5SSimon Glass if (priv->vl_vspw == 0) { 56308a7aa1eSSimon Glass debug("Can't get vsync width\n"); 56408a7aa1eSSimon Glass return -ENXIO; 56508a7aa1eSSimon Glass } 56608a7aa1eSSimon Glass 567bb5930d5SSimon Glass priv->vl_vfpd = fdtdec_get_int(blob, node, 56808a7aa1eSSimon Glass "samsung,vl-vfpd", 0); 569bb5930d5SSimon Glass if (priv->vl_vfpd == 0) { 57008a7aa1eSSimon Glass debug("Can't get lower margin\n"); 57108a7aa1eSSimon Glass return -ENXIO; 57208a7aa1eSSimon Glass } 57308a7aa1eSSimon Glass 574bb5930d5SSimon Glass priv->vl_vbpd = fdtdec_get_int(blob, node, "samsung,vl-vbpd", 0); 575bb5930d5SSimon Glass if (priv->vl_vbpd == 0) { 57608a7aa1eSSimon Glass debug("Can't get upper margin\n"); 57708a7aa1eSSimon Glass return -ENXIO; 57808a7aa1eSSimon Glass } 57908a7aa1eSSimon Glass 580bb5930d5SSimon Glass priv->vl_cmd_allow_len = fdtdec_get_int(blob, node, 58108a7aa1eSSimon Glass "samsung,vl-cmd-allow-len", 0); 58208a7aa1eSSimon Glass 583bb5930d5SSimon Glass priv->win_id = fdtdec_get_int(blob, node, "samsung,winid", 0); 584bb5930d5SSimon Glass priv->init_delay = fdtdec_get_int(blob, node, 58508a7aa1eSSimon Glass "samsung,init-delay", 0); 586bb5930d5SSimon Glass priv->power_on_delay = fdtdec_get_int(blob, node, 58708a7aa1eSSimon Glass "samsung,power-on-delay", 0); 588bb5930d5SSimon Glass priv->reset_delay = fdtdec_get_int(blob, node, 58908a7aa1eSSimon Glass "samsung,reset-delay", 0); 590bb5930d5SSimon Glass priv->interface_mode = fdtdec_get_int(blob, node, 59108a7aa1eSSimon Glass "samsung,interface-mode", 0); 592bb5930d5SSimon Glass priv->mipi_enabled = fdtdec_get_int(blob, node, 59308a7aa1eSSimon Glass "samsung,mipi-enabled", 0); 594bb5930d5SSimon Glass priv->dp_enabled = fdtdec_get_int(blob, node, 59508a7aa1eSSimon Glass "samsung,dp-enabled", 0); 596bb5930d5SSimon Glass priv->cs_setup = fdtdec_get_int(blob, node, 59708a7aa1eSSimon Glass "samsung,cs-setup", 0); 598bb5930d5SSimon Glass priv->wr_setup = fdtdec_get_int(blob, node, 59908a7aa1eSSimon Glass "samsung,wr-setup", 0); 600bb5930d5SSimon Glass priv->wr_act = fdtdec_get_int(blob, node, "samsung,wr-act", 0); 601bb5930d5SSimon Glass priv->wr_hold = fdtdec_get_int(blob, node, "samsung,wr-hold", 0); 60208a7aa1eSSimon Glass 603bb5930d5SSimon Glass priv->logo_on = fdtdec_get_int(blob, node, "samsung,logo-on", 0); 604bb5930d5SSimon Glass if (priv->logo_on) { 605bb5930d5SSimon Glass priv->logo_width = fdtdec_get_int(blob, node, 60608a7aa1eSSimon Glass "samsung,logo-width", 0); 607bb5930d5SSimon Glass priv->logo_height = fdtdec_get_int(blob, node, 60808a7aa1eSSimon Glass "samsung,logo-height", 0); 609bb5930d5SSimon Glass priv->logo_addr = fdtdec_get_int(blob, node, 61008a7aa1eSSimon Glass "samsung,logo-addr", 0); 61108a7aa1eSSimon Glass } 61208a7aa1eSSimon Glass 613bb5930d5SSimon Glass priv->rgb_mode = fdtdec_get_int(blob, node, 61408a7aa1eSSimon Glass "samsung,rgb-mode", 0); 615bb5930d5SSimon Glass priv->pclk_name = fdtdec_get_int(blob, node, 61608a7aa1eSSimon Glass "samsung,pclk-name", 0); 617bb5930d5SSimon Glass priv->sclk_div = fdtdec_get_int(blob, node, 61808a7aa1eSSimon Glass "samsung,sclk-div", 0); 619bb5930d5SSimon Glass priv->dual_lcd_enabled = fdtdec_get_int(blob, node, 62008a7aa1eSSimon Glass "samsung,dual-lcd-enabled", 0); 62108a7aa1eSSimon Glass 62208a7aa1eSSimon Glass return 0; 62308a7aa1eSSimon Glass } 62408a7aa1eSSimon Glass 625bb5930d5SSimon Glass static int exynos_fb_probe(struct udevice *dev) 62608a7aa1eSSimon Glass { 627bb5930d5SSimon Glass struct video_priv *uc_priv = dev_get_uclass_priv(dev); 628bb5930d5SSimon Glass struct exynos_fb_priv *priv = dev_get_priv(dev); 629bb5930d5SSimon Glass struct udevice *panel, *bridge; 630bb5930d5SSimon Glass struct udevice *dp; 631bb5930d5SSimon Glass int ret; 632bb5930d5SSimon Glass 633bb5930d5SSimon Glass debug("%s: start\n", __func__); 63408a7aa1eSSimon Glass set_system_display_ctrl(); 63508a7aa1eSSimon Glass set_lcd_clk(); 63608a7aa1eSSimon Glass 63708a7aa1eSSimon Glass #ifdef CONFIG_EXYNOS_MIPI_DSIM 63808a7aa1eSSimon Glass exynos_init_dsim_platform_data(&panel_info); 63908a7aa1eSSimon Glass #endif 640bb5930d5SSimon Glass exynos_fimd_lcd_init(dev); 64108a7aa1eSSimon Glass 642bb5930d5SSimon Glass ret = uclass_first_device(UCLASS_PANEL, &panel); 643bb5930d5SSimon Glass if (ret) { 644bb5930d5SSimon Glass printf("LCD panel failed to probe\n"); 645bb5930d5SSimon Glass return ret; 646bb5930d5SSimon Glass } 647bb5930d5SSimon Glass if (!panel) { 648bb5930d5SSimon Glass printf("LCD panel not found\n"); 649bb5930d5SSimon Glass return -ENODEV; 65008a7aa1eSSimon Glass } 65108a7aa1eSSimon Glass 652bb5930d5SSimon Glass ret = uclass_first_device(UCLASS_DISPLAY, &dp); 653bb5930d5SSimon Glass if (ret) { 654bb5930d5SSimon Glass debug("%s: Display device error %d\n", __func__, ret); 655bb5930d5SSimon Glass return ret; 656bb5930d5SSimon Glass } 657bb5930d5SSimon Glass if (!dev) { 658bb5930d5SSimon Glass debug("%s: Display device missing\n", __func__); 659bb5930d5SSimon Glass return -ENODEV; 660bb5930d5SSimon Glass } 661bb5930d5SSimon Glass ret = display_enable(dp, 18, NULL); 662bb5930d5SSimon Glass if (ret) { 663bb5930d5SSimon Glass debug("%s: Display enable error %d\n", __func__, ret); 664bb5930d5SSimon Glass return ret; 665bb5930d5SSimon Glass } 666bb5930d5SSimon Glass 667bb5930d5SSimon Glass /* backlight / pwm */ 668bb5930d5SSimon Glass ret = panel_enable_backlight(panel); 669bb5930d5SSimon Glass if (ret) { 670bb5930d5SSimon Glass debug("%s: backlight error: %d\n", __func__, ret); 671bb5930d5SSimon Glass return ret; 672bb5930d5SSimon Glass } 673bb5930d5SSimon Glass 674bb5930d5SSimon Glass ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &bridge); 675bb5930d5SSimon Glass if (!ret) 676bb5930d5SSimon Glass ret = video_bridge_set_backlight(bridge, 80); 677bb5930d5SSimon Glass if (ret) { 678bb5930d5SSimon Glass debug("%s: No video bridge, or no backlight on bridge\n", 679bb5930d5SSimon Glass __func__); 680bb5930d5SSimon Glass exynos_pinmux_config(PERIPH_ID_PWM0, 0); 681bb5930d5SSimon Glass } 682bb5930d5SSimon Glass 683bb5930d5SSimon Glass uc_priv->xsize = priv->vl_col; 684bb5930d5SSimon Glass uc_priv->ysize = priv->vl_row; 685bb5930d5SSimon Glass uc_priv->bpix = priv->vl_bpix; 686bb5930d5SSimon Glass 687bb5930d5SSimon Glass /* Enable flushing after LCD writes if requested */ 688bb5930d5SSimon Glass video_set_flush_dcache(dev, true); 689bb5930d5SSimon Glass 690bb5930d5SSimon Glass return 0; 691bb5930d5SSimon Glass } 692bb5930d5SSimon Glass 693bb5930d5SSimon Glass static int exynos_fb_bind(struct udevice *dev) 69408a7aa1eSSimon Glass { 695bb5930d5SSimon Glass struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 696bb5930d5SSimon Glass 697bb5930d5SSimon Glass /* This is the maximum panel size we expect to see */ 698bb5930d5SSimon Glass plat->size = 1920 * 1080 * 2; 699bb5930d5SSimon Glass 700bb5930d5SSimon Glass return 0; 70108a7aa1eSSimon Glass } 70208a7aa1eSSimon Glass 703bb5930d5SSimon Glass static const struct video_ops exynos_fb_ops = { 704bb5930d5SSimon Glass }; 70508a7aa1eSSimon Glass 706bb5930d5SSimon Glass static const struct udevice_id exynos_fb_ids[] = { 707bb5930d5SSimon Glass { .compatible = "samsung,exynos-fimd" }, 708bb5930d5SSimon Glass { } 709bb5930d5SSimon Glass }; 710bb5930d5SSimon Glass 711bb5930d5SSimon Glass U_BOOT_DRIVER(exynos_fb) = { 712bb5930d5SSimon Glass .name = "exynos_fb", 713bb5930d5SSimon Glass .id = UCLASS_VIDEO, 714bb5930d5SSimon Glass .of_match = exynos_fb_ids, 715bb5930d5SSimon Glass .ops = &exynos_fb_ops, 716bb5930d5SSimon Glass .bind = exynos_fb_bind, 717bb5930d5SSimon Glass .probe = exynos_fb_probe, 718bb5930d5SSimon Glass .ofdata_to_platdata = exynos_fb_ofdata_to_platdata, 719bb5930d5SSimon Glass .priv_auto_alloc_size = sizeof(struct exynos_fb_priv), 720bb5930d5SSimon Glass }; 721