// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH * Copyright (c) 2015 Google, Inc * Copyright 2014 Rockchip Inc. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "rk_vop.h" DECLARE_GLOBAL_DATA_PTR; static void rk3288_set_pin_polarity(struct udevice *dev, enum vop_modes mode, u32 polarity) { struct rk_vop_priv *priv = dev_get_priv(dev); struct rk3288_vop *regs = priv->regs; /* The RK3328 VOP (v3.1) has its polarity configuration in ctrl0 */ clrsetbits_le32(®s->dsp_ctrl0, M_DSP_DCLK_POL | M_DSP_DEN_POL | M_DSP_VSYNC_POL | M_DSP_HSYNC_POL, V_DSP_PIN_POL(polarity)); } static void rk3288_set_io_vsel(struct udevice *dev) { struct rk3288_grf *grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); /* lcdc(vop) iodomain select 1.8V */ rk_setreg(&grf->io_vsel, 1 << 0); } /* * Try some common regulators. We should really get these from the * device tree somehow. */ static const char * const rk3288_regulator_names[] = { "vcc18_lcd", "VCC18_LCD", "vdd10_lcd_pwren_h", "vdd10_lcd", "VDD10_LCD", "vcc33_lcd" }; static int rk3288_vop_probe(struct udevice *dev) { /* Before relocation we don't need to do anything */ if (!(gd->flags & GD_FLG_RELOC)) return 0; /* Set the LCDC(vop) iodomain to 1.8V */ rk3288_set_io_vsel(dev); /* Probe regulators required for the RK3288 VOP */ rk_vop_probe_regulators(dev, rk3288_regulator_names, ARRAY_SIZE(rk3288_regulator_names)); return rk_vop_probe(dev); } static int rk_vop_remove(struct udevice *dev) { struct rk_vop_priv *priv = dev_get_priv(dev); struct rk3288_vop *regs = priv->regs; setbits_le32(®s->sys_ctrl, V_STANDBY_EN(1)); /* wait frame complete (60Hz) to enter standby */ mdelay(17); return 0; } struct rkvop_driverdata rk3288_driverdata = { .features = VOP_FEATURE_OUTPUT_10BIT, .set_pin_polarity = rk3288_set_pin_polarity, }; static const struct udevice_id rk3288_vop_ids[] = { { .compatible = "rockchip,rk3288-vop", .data = (ulong)&rk3288_driverdata }, { } }; static const struct video_ops rk3288_vop_ops = { }; U_BOOT_DRIVER(rockchip_rk3288_vop) = { .name = "rockchip_rk3288_vop", .id = UCLASS_VIDEO, .of_match = rk3288_vop_ids, .ops = &rk3288_vop_ops, .bind = rk_vop_bind, .probe = rk3288_vop_probe, .remove = rk_vop_remove, .priv_auto = sizeof(struct rk_vop_priv), };