u-boot-brain/drivers/video/rockchip/rk3288_vop.c
Philipp Tomsich d46d40474a rockchip: video: refactor rk_vop and split RK3288-specific code off
To prepare for adding the RK3399 VOP driver (which shares most of its
registers and config logic with the RK3228 VOP), this change refactors
the driver and splits the RK3288-specific driver off.

The changes in detail are:
- introduces a data-structure for chip-specific drivers to register
  features/callbacks with the common driver: at this time, this is
  limited to a callback for setting the pin polarities (between the
  VOP and the encoder modules) and a flag to signal 10bit RGB
  capability
- refactors the probing of regulators into a helper function that
  can take a list of regulator names to probe and autoset
- moves the priv data-structure into a (common) header file to be
  used by the chip-specific drivers to provide base addresses to
  the common driver
- uses a callback into the chip-specific driver to set pin polarities
  (replacing the direct register accesses previously used)
- splits enabling the output (towards an encoder) into a separate
  help function withint the common driver

Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2017-06-07 21:30:49 -06:00

96 lines
2.2 KiB
C

/*
* Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
* Copyright (c) 2015 Google, Inc
* Copyright 2014 Rockchip Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <display.h>
#include <dm.h>
#include <regmap.h>
#include <syscon.h>
#include <video.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/grf_rk3288.h>
#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(&regs->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);
}
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(rk_vop) = {
.name = "rk3288_vop",
.id = UCLASS_VIDEO,
.of_match = rk3288_vop_ids,
.ops = &rk3288_vop_ops,
.bind = rk_vop_bind,
.probe = rk3288_vop_probe,
.priv_auto_alloc_size = sizeof(struct rk_vop_priv),
};