android13/u-boot/drivers/video/drm/display-serdes/serdes-panel-split.c

180 lines
4.8 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* serdes-panel.c -- display panel for different serdes chips
*
* Copyright (c) 2023 Rockchip Electronics Co. Ltd.
*
* Author: luowei <lw@rock-chips.com>
*/
#include "core.h"
static void serdes_panel_split_init(struct serdes *serdes)
{
if (serdes->vpower_supply)
regulator_set_enable(serdes->vpower_supply, true);
if (dm_gpio_is_valid(&serdes->enable_gpio))
dm_gpio_set_value(&serdes->enable_gpio, 1);
mdelay(5);
if (serdes->chip_data->panel_ops->init)
serdes->chip_data->panel_ops->init(serdes);
if (serdes->chip_data->serdes_type == TYPE_DES)
serdes_i2c_set_sequence(serdes);
SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
serdes->chip_data->name);
}
static void serdes_panel_split_prepare(struct rockchip_panel *panel)
{
struct udevice *dev = panel->dev;
struct serdes *serdes = dev_get_priv(dev->parent);
if (serdes->chip_data->panel_ops->prepare)
serdes->chip_data->panel_ops->prepare(serdes);
SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
serdes->chip_data->name);
}
static void serdes_panel_split_unprepare(struct rockchip_panel *panel)
{
struct udevice *dev = panel->dev;
struct serdes *serdes = dev_get_priv(dev->parent);
if (serdes->chip_data->panel_ops->unprepare)
serdes->chip_data->panel_ops->unprepare(serdes);
SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
serdes->chip_data->name);
}
static void serdes_panel_split_enable(struct rockchip_panel *panel)
{
struct udevice *dev = panel->dev;
struct serdes *serdes = dev_get_priv(dev->parent);
if (serdes->chip_data->panel_ops->enable)
serdes->chip_data->panel_ops->enable(serdes);
serdes_panel_split_init(serdes);
if (serdes->serdes_panel_split->backlight)
backlight_enable(serdes->serdes_panel_split->backlight);
if (serdes->chip_data->panel_ops->backlight_enable)
serdes->chip_data->panel_ops->backlight_enable(serdes);
SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
serdes->chip_data->name);
}
static void serdes_panel_split_disable(struct rockchip_panel *panel)
{
struct udevice *dev = panel->dev;
struct serdes *serdes = dev_get_priv(dev->parent);
if (serdes->chip_data->panel_ops->backlight_disable)
serdes->chip_data->panel_ops->backlight_disable(serdes);
if (serdes->serdes_panel_split->backlight)
backlight_disable(serdes->serdes_panel_split->backlight);
if (serdes->chip_data->panel_ops->disable)
serdes->chip_data->panel_ops->disable(serdes);
SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
serdes->chip_data->name);
}
static struct rockchip_panel_funcs serdes_panel_split_ops = {
.prepare = serdes_panel_split_prepare,
.unprepare = serdes_panel_split_unprepare,
.enable = serdes_panel_split_enable,
.disable = serdes_panel_split_disable,
};
static int serdes_panel_split_probe(struct udevice *dev)
{
struct serdes *serdes = dev_get_priv(dev->parent);
struct serdes_panel_split *serdes_panel_split = NULL;
struct rockchip_panel *panel;
int ret;
SERDES_DBG_MFD("%s: %s %s start\n", __func__, serdes->dev->name,
serdes->chip_data->name);
if (!serdes->chip_data->panel_ops) {
printf("%s %s no panel ops\n",
__func__, serdes->chip_data->name);
return -1;
}
if (serdes->chip_data->serdes_type != TYPE_DES)
printf("%s warning: this chip is not des type\n", __func__);
serdes_panel_split = calloc(1, sizeof(*serdes_panel_split));
if (!serdes_panel_split)
return -ENOMEM;
serdes->serdes_panel_split = serdes_panel_split;
ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
"backlight",
&serdes->serdes_panel_split->backlight);
if (ret && ret != -ENOENT)
printf("%s: Cannot get backlight: %d\n", __func__, ret);
panel = calloc(1, sizeof(*panel));
if (!panel)
return -ENOMEM;
ret = serdes_get_init_seq(serdes);
if (ret)
goto free_panel;
dev->driver_data = (ulong)panel;
panel->dev = dev;
panel->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
panel->funcs = &serdes_panel_split_ops;
serdes->serdes_panel_split->panel = panel;
printf("%s %s successful, version %s\n",
__func__,
serdes->dev->name,
SERDES_UBOOT_DISPLAY_VERSION);
return 0;
free_panel:
free(panel);
return ret;
}
static const struct udevice_id serdes_of_match[] = {
#if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96752)
{ .compatible = "maxim,max96752-panel-split",},
#endif
#if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96772)
{ .compatible = "maxim,max96772-panel-split",},
#endif
#if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX121)
{ .compatible = "rockchip,rkx121-panel-split",},
#endif
{ }
};
U_BOOT_DRIVER(serdes_panel_split) = {
.name = "serdes-panel-split",
.id = UCLASS_PANEL,
.of_match = serdes_of_match,
.probe = serdes_panel_split_probe,
.priv_auto_alloc_size = sizeof(struct serdes_panel_split),
};