uboot/drivers/video/rockchip/rk3288_vop.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
   4 * Copyright (c) 2015 Google, Inc
   5 * Copyright 2014 Rockchip Inc.
   6 */
   7
   8#include <common.h>
   9#include <display.h>
  10#include <dm.h>
  11#include <regmap.h>
  12#include <syscon.h>
  13#include <video.h>
  14#include <asm/global_data.h>
  15#include <asm/io.h>
  16#include <asm/arch-rockchip/clock.h>
  17#include <asm/arch-rockchip/grf_rk3288.h>
  18#include <asm/arch-rockchip/hardware.h>
  19#include <linux/delay.h>
  20#include "rk_vop.h"
  21
  22DECLARE_GLOBAL_DATA_PTR;
  23
  24static void rk3288_set_pin_polarity(struct udevice *dev,
  25                                    enum vop_modes mode, u32 polarity)
  26{
  27        struct rk_vop_priv *priv = dev_get_priv(dev);
  28        struct rk3288_vop *regs = priv->regs;
  29
  30        /* The RK3328 VOP (v3.1) has its polarity configuration in ctrl0 */
  31        clrsetbits_le32(&regs->dsp_ctrl0,
  32                        M_DSP_DCLK_POL | M_DSP_DEN_POL |
  33                        M_DSP_VSYNC_POL | M_DSP_HSYNC_POL,
  34                        V_DSP_PIN_POL(polarity));
  35}
  36
  37static void rk3288_set_io_vsel(struct udevice *dev)
  38{
  39        struct rk3288_grf *grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
  40
  41        /* lcdc(vop) iodomain select 1.8V */
  42        rk_setreg(&grf->io_vsel, 1 << 0);
  43}
  44
  45/*
  46 * Try some common regulators. We should really get these from the
  47 * device tree somehow.
  48 */
  49static const char * const rk3288_regulator_names[] = {
  50        "vcc18_lcd",
  51        "VCC18_LCD",
  52        "vdd10_lcd_pwren_h",
  53        "vdd10_lcd",
  54        "VDD10_LCD",
  55        "vcc33_lcd"
  56};
  57
  58static int rk3288_vop_probe(struct udevice *dev)
  59{
  60        /* Before relocation we don't need to do anything */
  61        if (!(gd->flags & GD_FLG_RELOC))
  62                return 0;
  63
  64        /* Set the LCDC(vop) iodomain to 1.8V */
  65        rk3288_set_io_vsel(dev);
  66
  67        /* Probe regulators required for the RK3288 VOP */
  68        rk_vop_probe_regulators(dev, rk3288_regulator_names,
  69                                ARRAY_SIZE(rk3288_regulator_names));
  70
  71        return rk_vop_probe(dev);
  72}
  73
  74static int rk_vop_remove(struct udevice *dev)
  75{
  76        struct rk_vop_priv *priv = dev_get_priv(dev);
  77        struct rk3288_vop *regs = priv->regs;
  78
  79        setbits_le32(&regs->sys_ctrl, V_STANDBY_EN(1));
  80
  81        /* wait frame complete (60Hz) to enter standby */
  82        mdelay(17);
  83
  84        return 0;
  85}
  86
  87struct rkvop_driverdata rk3288_driverdata = {
  88        .features = VOP_FEATURE_OUTPUT_10BIT,
  89        .set_pin_polarity = rk3288_set_pin_polarity,
  90};
  91
  92static const struct udevice_id rk3288_vop_ids[] = {
  93        { .compatible = "rockchip,rk3288-vop",
  94          .data = (ulong)&rk3288_driverdata },
  95        { }
  96};
  97
  98static const struct video_ops rk3288_vop_ops = {
  99};
 100
 101U_BOOT_DRIVER(rockchip_rk3288_vop) = {
 102        .name   = "rockchip_rk3288_vop",
 103        .id     = UCLASS_VIDEO,
 104        .of_match = rk3288_vop_ids,
 105        .ops    = &rk3288_vop_ops,
 106        .bind   = rk_vop_bind,
 107        .probe  = rk3288_vop_probe,
 108        .remove = rk_vop_remove,
 109        .priv_auto      = sizeof(struct rk_vop_priv),
 110};
 111