Merge remote-tracking branch 'origin/display/pc' into display/next
* origin/display/pc: gpu: imx: Add imx8 pixel combiner support gpu: Move ipu-v3 to imx folder drm/imx: Revert a patch which merges imx-drm-core and ipuv3-crtc in one module5.4-rM2-2.2.x-imx-squashed
commit
a557a5b86c
|
@ -49,6 +49,13 @@ config DRM_IMX_IPUV3
|
||||||
default y if DRM_IMX=y
|
default y if DRM_IMX=y
|
||||||
default m if DRM_IMX=m
|
default m if DRM_IMX=m
|
||||||
|
|
||||||
|
config DRM_IMX_IPUV3
|
||||||
|
tristate
|
||||||
|
depends on DRM_IMX
|
||||||
|
depends on IMX_IPUV3_CORE
|
||||||
|
default y if DRM_IMX=y
|
||||||
|
default m if DRM_IMX=m
|
||||||
|
|
||||||
config DRM_IMX_HDMI
|
config DRM_IMX_HDMI
|
||||||
tristate "Freescale i.MX DRM HDMI"
|
tristate "Freescale i.MX DRM HDMI"
|
||||||
select DRM_DW_HDMI
|
select DRM_DW_HDMI
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
config IMX8_PC
|
||||||
|
tristate
|
||||||
|
default y if IMX_DPU_CORE=y
|
||||||
|
default m if IMX_DPU_CORE=m
|
||||||
|
|
||||||
source "drivers/gpu/imx/ipu-v3/Kconfig"
|
source "drivers/gpu/imx/ipu-v3/Kconfig"
|
||||||
source "drivers/gpu/imx/dpu/Kconfig"
|
source "drivers/gpu/imx/dpu/Kconfig"
|
||||||
source "drivers/gpu/imx/dpu-blit/Kconfig"
|
source "drivers/gpu/imx/dpu-blit/Kconfig"
|
||||||
|
|
|
@ -2,3 +2,4 @@ obj-$(CONFIG_IMX_IPUV3_CORE) += ipu-v3/
|
||||||
obj-$(CONFIG_IMX_DPU_CORE) += dpu/
|
obj-$(CONFIG_IMX_DPU_CORE) += dpu/
|
||||||
obj-$(CONFIG_IMX_DPU_BLIT) += dpu-blit/
|
obj-$(CONFIG_IMX_DPU_BLIT) += dpu-blit/
|
||||||
obj-$(CONFIG_IMX_LCDIF_CORE) += lcdif/
|
obj-$(CONFIG_IMX_LCDIF_CORE) += lcdif/
|
||||||
|
obj-$(CONFIG_IMX8_PC) += imx8_pc.o
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018,2019 NXP
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <video/imx8-pc.h>
|
||||||
|
|
||||||
|
#define REG0 0x0
|
||||||
|
#define PIX_COMBINE_ENABLE BIT(0)
|
||||||
|
#define DISP_PIX_COMBINE_BYPASS(n) BIT(1 + 21 * (n))
|
||||||
|
#define DISP_HSYNC_POLARITY(n) BIT(2 + 11 * (n))
|
||||||
|
#define DISP_HSYNC_POLARITY_POS(n) DISP_HSYNC_POLARITY(n)
|
||||||
|
#define DISP_VSYNC_POLARITY(n) BIT(3 + 11 * (n))
|
||||||
|
#define DISP_VSYNC_POLARITY_POS(n) DISP_VSYNC_POLARITY(n)
|
||||||
|
#define DISP_DVALID_POLARITY(n) BIT(4 + 11 * (n))
|
||||||
|
#define DISP_DVALID_POLARITY_POS(n) DISP_DVALID_POLARITY(n)
|
||||||
|
#define VSYNC_MASK_ENABLE BIT(5)
|
||||||
|
#define SKIP_MODE BIT(6)
|
||||||
|
#define SKIP_NUMBER(n) (((n) & 0x3F) << 7)
|
||||||
|
#define DISP_PIX_DATA_FORMAT_MASK(n) (0x7 << (16 + (n) * 3))
|
||||||
|
#define DISP_PIX_DATA_FORMAT_SHIFT(n) (16 + (n) * 3)
|
||||||
|
enum {
|
||||||
|
RGB = 0,
|
||||||
|
YUV444,
|
||||||
|
YUV422,
|
||||||
|
SPLIT_RGB,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define REG1 0x10
|
||||||
|
#define BUF_ACTIVE_DEPTH(n) ((n) & 0x7FF)
|
||||||
|
|
||||||
|
#define REG2 0x20
|
||||||
|
#define PC_SW_RESET_N BIT(0)
|
||||||
|
#define DISP_SW_RESET_N(n) BIT(1 + (n))
|
||||||
|
#define PC_FULL_RESET_N (PC_SW_RESET_N | \
|
||||||
|
DISP_SW_RESET_N(0) | \
|
||||||
|
DISP_SW_RESET_N(1))
|
||||||
|
|
||||||
|
struct pc {
|
||||||
|
struct device *dev;
|
||||||
|
void __iomem *base;
|
||||||
|
struct list_head list;
|
||||||
|
};
|
||||||
|
|
||||||
|
static DEFINE_MUTEX(pc_list_mutex);
|
||||||
|
static LIST_HEAD(pc_list);
|
||||||
|
|
||||||
|
static inline u32 pc_read(struct pc *pc, unsigned int offset)
|
||||||
|
{
|
||||||
|
return readl(pc->base + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pc_write(struct pc *pc, unsigned int offset, u32 value)
|
||||||
|
{
|
||||||
|
writel(value, pc->base + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pc_reset(struct pc *pc)
|
||||||
|
{
|
||||||
|
pc_write(pc, REG2, 0);
|
||||||
|
usleep_range(1000, 2000);
|
||||||
|
pc_write(pc, REG2, PC_FULL_RESET_N);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pc_enable(struct pc *pc)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (WARN_ON(!pc))
|
||||||
|
return;
|
||||||
|
|
||||||
|
val = pc_read(pc, REG0);
|
||||||
|
val |= PIX_COMBINE_ENABLE;
|
||||||
|
pc_write(pc, REG0, val);
|
||||||
|
|
||||||
|
dev_dbg(pc->dev, "enable\n");
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pc_enable);
|
||||||
|
|
||||||
|
void pc_disable(struct pc *pc)
|
||||||
|
{
|
||||||
|
if (WARN_ON(!pc))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pc_reset(pc);
|
||||||
|
|
||||||
|
dev_dbg(pc->dev, "disable\n");
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pc_disable);
|
||||||
|
|
||||||
|
void pc_configure(struct pc *pc, unsigned int di, unsigned int frame_width,
|
||||||
|
u32 mode, u32 format)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (WARN_ON(!pc))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (WARN_ON(di != 0 && di != 1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
dev_dbg(pc->dev, "configure mode-0x%08x frame_width-%u\n",
|
||||||
|
mode, frame_width);
|
||||||
|
|
||||||
|
val = pc_read(pc, REG0);
|
||||||
|
if (mode == PC_BYPASS) {
|
||||||
|
val |= DISP_PIX_COMBINE_BYPASS(di);
|
||||||
|
} else if (mode == PC_COMBINE) {
|
||||||
|
val &= ~DISP_PIX_COMBINE_BYPASS(di);
|
||||||
|
frame_width /= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
pc_write(pc, REG0, val);
|
||||||
|
pc_write(pc, REG1, BUF_ACTIVE_DEPTH(frame_width));
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pc_configure);
|
||||||
|
|
||||||
|
struct pc *pc_lookup_by_phandle(struct device *dev, const char *name)
|
||||||
|
{
|
||||||
|
struct device_node *pc_node = of_parse_phandle(dev->of_node,
|
||||||
|
name, 0);
|
||||||
|
struct pc *pc;
|
||||||
|
|
||||||
|
mutex_lock(&pc_list_mutex);
|
||||||
|
list_for_each_entry(pc, &pc_list, list) {
|
||||||
|
if (pc_node == pc->dev->of_node) {
|
||||||
|
mutex_unlock(&pc_list_mutex);
|
||||||
|
device_link_add(dev, pc->dev,
|
||||||
|
DL_FLAG_AUTOREMOVE_CONSUMER);
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&pc_list_mutex);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pc_lookup_by_phandle);
|
||||||
|
|
||||||
|
static int pc_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct resource *res;
|
||||||
|
struct pc *pc;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
|
||||||
|
if (!pc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
pc->base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
if (IS_ERR(pc->base))
|
||||||
|
return PTR_ERR(pc->base);
|
||||||
|
|
||||||
|
pc->dev = dev;
|
||||||
|
platform_set_drvdata(pdev, pc);
|
||||||
|
mutex_lock(&pc_list_mutex);
|
||||||
|
list_add(&pc->list, &pc_list);
|
||||||
|
mutex_unlock(&pc_list_mutex);
|
||||||
|
|
||||||
|
pc_reset(pc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* assume data enable is active high and HSYNC/VSYNC are active low
|
||||||
|
* also, bypass combine at startup
|
||||||
|
*/
|
||||||
|
val = DISP_DVALID_POLARITY_POS(0) | DISP_DVALID_POLARITY_POS(1) |
|
||||||
|
DISP_PIX_COMBINE_BYPASS(0) | DISP_PIX_COMBINE_BYPASS(1) |
|
||||||
|
VSYNC_MASK_ENABLE;
|
||||||
|
|
||||||
|
pc_write(pc, REG0, val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pc_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct pc *pc = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
mutex_lock(&pc_list_mutex);
|
||||||
|
list_del(&pc->list);
|
||||||
|
mutex_unlock(&pc_list_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id pc_dt_ids[] = {
|
||||||
|
{ .compatible = "fsl,imx8qm-pixel-combiner", },
|
||||||
|
{ .compatible = "fsl,imx8qxp-pixel-combiner", },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
|
struct platform_driver pc_drv = {
|
||||||
|
.probe = pc_probe,
|
||||||
|
.remove = pc_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = "imx8-pixel-combiner",
|
||||||
|
.of_match_table = pc_dt_ids,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
module_platform_driver(pc_drv);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("i.MX8 Pixel Combiner driver");
|
||||||
|
MODULE_AUTHOR("NXP Semiconductor");
|
||||||
|
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018,2019 NXP
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IMX8_PIXEL_COMBINER_H_
|
||||||
|
#define _IMX8_PIXEL_COMBINER_H_
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PC_BYPASS,
|
||||||
|
PC_COMBINE,
|
||||||
|
PC_CONVERSION,
|
||||||
|
PC_SPLIT_RGB,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pc;
|
||||||
|
|
||||||
|
void pc_enable(struct pc *pc);
|
||||||
|
void pc_disable(struct pc *pc);
|
||||||
|
void pc_configure(struct pc *pc, unsigned int di, unsigned int frame_width,
|
||||||
|
u32 mode, u32 format);
|
||||||
|
struct pc *pc_lookup_by_phandle(struct device *dev, const char *name);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue