mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-26 04:25:27 +08:00
- Misc fixes and improvements to the R-Car DU driver
- Synopsys DW HDMI bridge DT bindings update -----BEGIN PGP SIGNATURE----- iJgEABYKAEAWIQTAnvhxs4J7QT+XHKnMPy2AAyfeZAUCYxkKPCIcbGF1cmVudC5w aW5jaGFydEBpZGVhc29uYm9hcmQuY29tAAoJEMw/LYADJ95k4zUA/RP0aGqIpT24 2qm66JmO7MnwP5w0oKuj7L7rzHj5E5TtAQDDzo6El3ui0uKykNpNdquFzPqWLkHN byEcViYzbCjBCg== =cAsg -----END PGP SIGNATURE----- Merge tag 'du-next-20220907' of git://linuxtv.org/pinchartl/media into drm-next - Misc fixes and improvements to the R-Car DU driver - Synopsys DW HDMI bridge DT bindings update Signed-off-by: Dave Airlie <airlied@redhat.com> From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/YxkL+tRI8uXDCvj9@pendragon.ideasonboard.com
This commit is contained in:
commit
320305923c
@ -38,6 +38,9 @@ properties:
|
|||||||
clock-names:
|
clock-names:
|
||||||
maxItems: 2
|
maxItems: 2
|
||||||
|
|
||||||
|
resets:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
$ref: /schemas/graph.yaml#/properties/ports
|
$ref: /schemas/graph.yaml#/properties/ports
|
||||||
|
|
||||||
@ -67,6 +70,7 @@ required:
|
|||||||
- reg
|
- reg
|
||||||
- clocks
|
- clocks
|
||||||
- clock-names
|
- clock-names
|
||||||
|
- resets
|
||||||
- interrupts
|
- interrupts
|
||||||
- ports
|
- ports
|
||||||
|
|
||||||
@ -85,6 +89,7 @@ examples:
|
|||||||
clocks = <&cpg CPG_CORE R8A7795_CLK_S0D4>, <&cpg CPG_MOD 729>;
|
clocks = <&cpg CPG_CORE R8A7795_CLK_S0D4>, <&cpg CPG_MOD 729>;
|
||||||
clock-names = "iahb", "isfr";
|
clock-names = "iahb", "isfr";
|
||||||
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
|
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
|
||||||
|
resets = <&cpg 729>;
|
||||||
|
|
||||||
ports {
|
ports {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
|
@ -14,10 +14,3 @@ obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o
|
|||||||
obj-$(CONFIG_DRM_RCAR_DW_HDMI) += rcar_dw_hdmi.o
|
obj-$(CONFIG_DRM_RCAR_DW_HDMI) += rcar_dw_hdmi.o
|
||||||
obj-$(CONFIG_DRM_RCAR_LVDS) += rcar_lvds.o
|
obj-$(CONFIG_DRM_RCAR_LVDS) += rcar_lvds.o
|
||||||
obj-$(CONFIG_DRM_RCAR_MIPI_DSI) += rcar_mipi_dsi.o
|
obj-$(CONFIG_DRM_RCAR_MIPI_DSI) += rcar_mipi_dsi.o
|
||||||
|
|
||||||
# 'remote-endpoint' is fixed up at run-time
|
|
||||||
DTC_FLAGS_rcar_du_of_lvds_r8a7790 += -Wno-graph_endpoint
|
|
||||||
DTC_FLAGS_rcar_du_of_lvds_r8a7791 += -Wno-graph_endpoint
|
|
||||||
DTC_FLAGS_rcar_du_of_lvds_r8a7793 += -Wno-graph_endpoint
|
|
||||||
DTC_FLAGS_rcar_du_of_lvds_r8a7795 += -Wno-graph_endpoint
|
|
||||||
DTC_FLAGS_rcar_du_of_lvds_r8a7796 += -Wno-graph_endpoint
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "rcar_du_regs.h"
|
#include "rcar_du_regs.h"
|
||||||
#include "rcar_du_vsp.h"
|
#include "rcar_du_vsp.h"
|
||||||
#include "rcar_lvds.h"
|
#include "rcar_lvds.h"
|
||||||
|
#include "rcar_mipi_dsi.h"
|
||||||
|
|
||||||
static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
|
static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
|
||||||
{
|
{
|
||||||
@ -744,7 +745,19 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
|
|||||||
const struct drm_display_mode *mode =
|
const struct drm_display_mode *mode =
|
||||||
&crtc->state->adjusted_mode;
|
&crtc->state->adjusted_mode;
|
||||||
|
|
||||||
rcar_lvds_clk_enable(bridge, mode->clock * 1000);
|
rcar_lvds_pclk_enable(bridge, mode->clock * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Similarly to LVDS, on V3U the dot clock is provided by the DSI
|
||||||
|
* encoder, and we need to enable the DSI clocks before enabling the CRTC.
|
||||||
|
*/
|
||||||
|
if ((rcdu->info->dsi_clk_mask & BIT(rcrtc->index)) &&
|
||||||
|
(rstate->outputs &
|
||||||
|
(BIT(RCAR_DU_OUTPUT_DSI0) | BIT(RCAR_DU_OUTPUT_DSI1)))) {
|
||||||
|
struct drm_bridge *bridge = rcdu->dsi[rcrtc->index];
|
||||||
|
|
||||||
|
rcar_mipi_dsi_pclk_enable(bridge, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
rcar_du_crtc_start(rcrtc);
|
rcar_du_crtc_start(rcrtc);
|
||||||
@ -777,7 +790,20 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
|
|||||||
* Disable the LVDS clock output, see
|
* Disable the LVDS clock output, see
|
||||||
* rcar_du_crtc_atomic_enable().
|
* rcar_du_crtc_atomic_enable().
|
||||||
*/
|
*/
|
||||||
rcar_lvds_clk_disable(bridge);
|
rcar_lvds_pclk_disable(bridge);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rcdu->info->dsi_clk_mask & BIT(rcrtc->index)) &&
|
||||||
|
(rstate->outputs &
|
||||||
|
(BIT(RCAR_DU_OUTPUT_DSI0) | BIT(RCAR_DU_OUTPUT_DSI1)))) {
|
||||||
|
struct drm_bridge *bridge = rcdu->dsi[rcrtc->index];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable the DSI clock output, see
|
||||||
|
* rcar_du_crtc_atomic_enable().
|
||||||
|
*/
|
||||||
|
|
||||||
|
rcar_mipi_dsi_pclk_disable(bridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irq(&crtc->dev->event_lock);
|
spin_lock_irq(&crtc->dev->event_lock);
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "rcar_du_drv.h"
|
#include "rcar_du_drv.h"
|
||||||
#include "rcar_du_kms.h"
|
#include "rcar_du_kms.h"
|
||||||
#include "rcar_du_regs.h"
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Device Information
|
* Device Information
|
||||||
@ -507,7 +506,8 @@ static const struct rcar_du_device_info rcar_du_r8a7799x_info = {
|
|||||||
static const struct rcar_du_device_info rcar_du_r8a779a0_info = {
|
static const struct rcar_du_device_info rcar_du_r8a779a0_info = {
|
||||||
.gen = 3,
|
.gen = 3,
|
||||||
.features = RCAR_DU_FEATURE_CRTC_IRQ
|
.features = RCAR_DU_FEATURE_CRTC_IRQ
|
||||||
| RCAR_DU_FEATURE_VSP1_SOURCE,
|
| RCAR_DU_FEATURE_VSP1_SOURCE
|
||||||
|
| RCAR_DU_FEATURE_NO_BLENDING,
|
||||||
.channels_mask = BIT(1) | BIT(0),
|
.channels_mask = BIT(1) | BIT(0),
|
||||||
.routes = {
|
.routes = {
|
||||||
/* R8A779A0 has two MIPI DSI outputs. */
|
/* R8A779A0 has two MIPI DSI outputs. */
|
||||||
|
@ -31,6 +31,7 @@ struct rcar_du_device;
|
|||||||
#define RCAR_DU_FEATURE_VSP1_SOURCE BIT(2) /* Has inputs from VSP1 */
|
#define RCAR_DU_FEATURE_VSP1_SOURCE BIT(2) /* Has inputs from VSP1 */
|
||||||
#define RCAR_DU_FEATURE_INTERLACED BIT(3) /* HW supports interlaced */
|
#define RCAR_DU_FEATURE_INTERLACED BIT(3) /* HW supports interlaced */
|
||||||
#define RCAR_DU_FEATURE_TVM_SYNC BIT(4) /* Has TV switch/sync modes */
|
#define RCAR_DU_FEATURE_TVM_SYNC BIT(4) /* Has TV switch/sync modes */
|
||||||
|
#define RCAR_DU_FEATURE_NO_BLENDING BIT(5) /* PnMR.SPIM does not have ALP nor EOR bits */
|
||||||
|
|
||||||
#define RCAR_DU_QUIRK_ALIGN_128B BIT(0) /* Align pitches to 128 bytes */
|
#define RCAR_DU_QUIRK_ALIGN_128B BIT(0) /* Align pitches to 128 bytes */
|
||||||
|
|
||||||
@ -91,6 +92,7 @@ struct rcar_du_device_info {
|
|||||||
#define RCAR_DU_MAX_GROUPS DIV_ROUND_UP(RCAR_DU_MAX_CRTCS, 2)
|
#define RCAR_DU_MAX_GROUPS DIV_ROUND_UP(RCAR_DU_MAX_CRTCS, 2)
|
||||||
#define RCAR_DU_MAX_VSPS 4
|
#define RCAR_DU_MAX_VSPS 4
|
||||||
#define RCAR_DU_MAX_LVDS 2
|
#define RCAR_DU_MAX_LVDS 2
|
||||||
|
#define RCAR_DU_MAX_DSI 2
|
||||||
|
|
||||||
struct rcar_du_device {
|
struct rcar_du_device {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
@ -107,6 +109,7 @@ struct rcar_du_device {
|
|||||||
struct platform_device *cmms[RCAR_DU_MAX_CRTCS];
|
struct platform_device *cmms[RCAR_DU_MAX_CRTCS];
|
||||||
struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
|
struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
|
||||||
struct drm_bridge *lvds[RCAR_DU_MAX_LVDS];
|
struct drm_bridge *lvds[RCAR_DU_MAX_LVDS];
|
||||||
|
struct drm_bridge *dsi[RCAR_DU_MAX_DSI];
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct drm_property *colorkey;
|
struct drm_property *colorkey;
|
||||||
|
@ -9,18 +9,13 @@
|
|||||||
|
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/slab.h>
|
|
||||||
|
|
||||||
#include <drm/drm_bridge.h>
|
#include <drm/drm_bridge.h>
|
||||||
#include <drm/drm_bridge_connector.h>
|
#include <drm/drm_bridge_connector.h>
|
||||||
#include <drm/drm_crtc.h>
|
|
||||||
#include <drm/drm_managed.h>
|
|
||||||
#include <drm/drm_modeset_helper_vtables.h>
|
|
||||||
#include <drm/drm_panel.h>
|
#include <drm/drm_panel.h>
|
||||||
|
|
||||||
#include "rcar_du_drv.h"
|
#include "rcar_du_drv.h"
|
||||||
#include "rcar_du_encoder.h"
|
#include "rcar_du_encoder.h"
|
||||||
#include "rcar_du_kms.h"
|
|
||||||
#include "rcar_lvds.h"
|
#include "rcar_lvds.h"
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
@ -84,6 +79,10 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
|
|||||||
if (output == RCAR_DU_OUTPUT_LVDS0 ||
|
if (output == RCAR_DU_OUTPUT_LVDS0 ||
|
||||||
output == RCAR_DU_OUTPUT_LVDS1)
|
output == RCAR_DU_OUTPUT_LVDS1)
|
||||||
rcdu->lvds[output - RCAR_DU_OUTPUT_LVDS0] = bridge;
|
rcdu->lvds[output - RCAR_DU_OUTPUT_LVDS0] = bridge;
|
||||||
|
|
||||||
|
if (output == RCAR_DU_OUTPUT_DSI0 ||
|
||||||
|
output == RCAR_DU_OUTPUT_DSI1)
|
||||||
|
rcdu->dsi[output - RCAR_DU_OUTPUT_DSI0] = bridge;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -405,8 +405,8 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
|
|||||||
|
|
||||||
format = rcar_du_format_info(mode_cmd->pixel_format);
|
format = rcar_du_format_info(mode_cmd->pixel_format);
|
||||||
if (format == NULL) {
|
if (format == NULL) {
|
||||||
dev_dbg(dev->dev, "unsupported pixel format %08x\n",
|
dev_dbg(dev->dev, "unsupported pixel format %p4cc\n",
|
||||||
mode_cmd->pixel_format);
|
&mode_cmd->pixel_format);
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,8 +506,15 @@ static void rcar_du_plane_setup_format_gen3(struct rcar_du_group *rgrp,
|
|||||||
unsigned int index,
|
unsigned int index,
|
||||||
const struct rcar_du_plane_state *state)
|
const struct rcar_du_plane_state *state)
|
||||||
{
|
{
|
||||||
rcar_du_plane_write(rgrp, index, PnMR,
|
struct rcar_du_device *rcdu = rgrp->dev;
|
||||||
PnMR_SPIM_TP_OFF | state->format->pnmr);
|
u32 pnmr = state->format->pnmr | PnMR_SPIM_TP_OFF;
|
||||||
|
|
||||||
|
if (rcdu->info->features & RCAR_DU_FEATURE_NO_BLENDING) {
|
||||||
|
/* No blending. ALP and EOR are not supported. */
|
||||||
|
pnmr &= ~(PnMR_SPIM_ALP | PnMR_SPIM_EOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
rcar_du_plane_write(rgrp, index, PnMR, pnmr);
|
||||||
|
|
||||||
rcar_du_plane_write(rgrp, index, PnDDCR4,
|
rcar_du_plane_write(rgrp, index, PnDDCR4,
|
||||||
state->format->edf | PnDDCR4_CODE);
|
state->format->edf | PnDDCR4_CODE);
|
||||||
@ -521,7 +528,6 @@ static void rcar_du_plane_setup_format_gen3(struct rcar_du_group *rgrp,
|
|||||||
* register to 0 to avoid this.
|
* register to 0 to avoid this.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* TODO: Check if alpha-blending should be disabled in PnMR. */
|
|
||||||
rcar_du_plane_write(rgrp, index, PnALPHAR, 0);
|
rcar_du_plane_write(rgrp, index, PnALPHAR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,8 +625,8 @@ int __rcar_du_plane_atomic_check(struct drm_plane *plane,
|
|||||||
|
|
||||||
*format = rcar_du_format_info(state->fb->format->format);
|
*format = rcar_du_format_info(state->fb->format->format);
|
||||||
if (*format == NULL) {
|
if (*format == NULL) {
|
||||||
dev_dbg(dev->dev, "%s: unsupported format %08x\n", __func__,
|
dev_dbg(dev->dev, "%s: unsupported format %p4cc\n", __func__,
|
||||||
state->fb->format->format);
|
&state->fb->format->format);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,6 +152,7 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
|
|||||||
.alpha = state->state.alpha >> 8,
|
.alpha = state->state.alpha >> 8,
|
||||||
.zpos = state->state.zpos,
|
.zpos = state->state.zpos,
|
||||||
};
|
};
|
||||||
|
u32 fourcc = state->format->fourcc;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
cfg.src.left = state->state.src.x1 >> 16;
|
cfg.src.left = state->state.src.x1 >> 16;
|
||||||
@ -168,9 +169,27 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
|
|||||||
cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl)
|
cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl)
|
||||||
+ fb->offsets[i];
|
+ fb->offsets[i];
|
||||||
|
|
||||||
format = rcar_du_format_info(state->format->fourcc);
|
if (state->state.pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE) {
|
||||||
|
switch (fourcc) {
|
||||||
|
case DRM_FORMAT_ARGB1555:
|
||||||
|
fourcc = DRM_FORMAT_XRGB1555;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRM_FORMAT_ARGB4444:
|
||||||
|
fourcc = DRM_FORMAT_XRGB4444;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DRM_FORMAT_ARGB8888:
|
||||||
|
fourcc = DRM_FORMAT_XRGB8888;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
format = rcar_du_format_info(fourcc);
|
||||||
cfg.pixelformat = format->v4l2;
|
cfg.pixelformat = format->v4l2;
|
||||||
|
|
||||||
|
cfg.premult = state->state.pixel_blend_mode == DRM_MODE_BLEND_PREMULTI;
|
||||||
|
|
||||||
vsp1_du_atomic_update(plane->vsp->vsp, crtc->vsp_pipe,
|
vsp1_du_atomic_update(plane->vsp->vsp, crtc->vsp_pipe,
|
||||||
plane->index, &cfg);
|
plane->index, &cfg);
|
||||||
}
|
}
|
||||||
@ -436,6 +455,11 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
|
|||||||
drm_plane_create_zpos_property(&plane->plane, i, 0,
|
drm_plane_create_zpos_property(&plane->plane, i, 0,
|
||||||
num_planes - 1);
|
num_planes - 1);
|
||||||
|
|
||||||
|
drm_plane_create_blend_mode_property(&plane->plane,
|
||||||
|
BIT(DRM_MODE_BLEND_PIXEL_NONE) |
|
||||||
|
BIT(DRM_MODE_BLEND_PREMULTI) |
|
||||||
|
BIT(DRM_MODE_BLEND_COVERAGE));
|
||||||
|
|
||||||
vsp->num_planes++;
|
vsp->num_planes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,8 +166,8 @@ static int rcar_du_wb_enc_atomic_check(struct drm_encoder *encoder,
|
|||||||
|
|
||||||
wb_state->format = rcar_du_format_info(fb->format->format);
|
wb_state->format = rcar_du_format_info(fb->format->format);
|
||||||
if (wb_state->format == NULL) {
|
if (wb_state->format == NULL) {
|
||||||
dev_dbg(dev->dev, "%s: unsupported format %08x\n", __func__,
|
dev_dbg(dev->dev, "%s: unsupported format %p4cc\n", __func__,
|
||||||
fb->format->format);
|
&fb->format->format);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq)
|
|||||||
* Clock - D3/E3 only
|
* Clock - D3/E3 only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int rcar_lvds_clk_enable(struct drm_bridge *bridge, unsigned long freq)
|
int rcar_lvds_pclk_enable(struct drm_bridge *bridge, unsigned long freq)
|
||||||
{
|
{
|
||||||
struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
|
struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
|
||||||
int ret;
|
int ret;
|
||||||
@ -324,9 +324,9 @@ int rcar_lvds_clk_enable(struct drm_bridge *bridge, unsigned long freq)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rcar_lvds_clk_enable);
|
EXPORT_SYMBOL_GPL(rcar_lvds_pclk_enable);
|
||||||
|
|
||||||
void rcar_lvds_clk_disable(struct drm_bridge *bridge)
|
void rcar_lvds_pclk_disable(struct drm_bridge *bridge)
|
||||||
{
|
{
|
||||||
struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
|
struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
|
||||||
|
|
||||||
@ -339,7 +339,7 @@ void rcar_lvds_clk_disable(struct drm_bridge *bridge)
|
|||||||
|
|
||||||
clk_disable_unprepare(lvds->clocks.mod);
|
clk_disable_unprepare(lvds->clocks.mod);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rcar_lvds_clk_disable);
|
EXPORT_SYMBOL_GPL(rcar_lvds_pclk_disable);
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Bridge
|
* Bridge
|
||||||
|
@ -13,17 +13,17 @@
|
|||||||
struct drm_bridge;
|
struct drm_bridge;
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_DRM_RCAR_LVDS)
|
#if IS_ENABLED(CONFIG_DRM_RCAR_LVDS)
|
||||||
int rcar_lvds_clk_enable(struct drm_bridge *bridge, unsigned long freq);
|
int rcar_lvds_pclk_enable(struct drm_bridge *bridge, unsigned long freq);
|
||||||
void rcar_lvds_clk_disable(struct drm_bridge *bridge);
|
void rcar_lvds_pclk_disable(struct drm_bridge *bridge);
|
||||||
bool rcar_lvds_dual_link(struct drm_bridge *bridge);
|
bool rcar_lvds_dual_link(struct drm_bridge *bridge);
|
||||||
bool rcar_lvds_is_connected(struct drm_bridge *bridge);
|
bool rcar_lvds_is_connected(struct drm_bridge *bridge);
|
||||||
#else
|
#else
|
||||||
static inline int rcar_lvds_clk_enable(struct drm_bridge *bridge,
|
static inline int rcar_lvds_pclk_enable(struct drm_bridge *bridge,
|
||||||
unsigned long freq)
|
unsigned long freq)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
static inline void rcar_lvds_clk_disable(struct drm_bridge *bridge) { }
|
static inline void rcar_lvds_pclk_disable(struct drm_bridge *bridge) { }
|
||||||
static inline bool rcar_lvds_dual_link(struct drm_bridge *bridge)
|
static inline bool rcar_lvds_dual_link(struct drm_bridge *bridge)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <drm/drm_panel.h>
|
#include <drm/drm_panel.h>
|
||||||
#include <drm/drm_probe_helper.h>
|
#include <drm/drm_probe_helper.h>
|
||||||
|
|
||||||
|
#include "rcar_mipi_dsi.h"
|
||||||
#include "rcar_mipi_dsi_regs.h"
|
#include "rcar_mipi_dsi_regs.h"
|
||||||
|
|
||||||
struct rcar_mipi_dsi {
|
struct rcar_mipi_dsi {
|
||||||
@ -414,7 +415,7 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
|
|||||||
|
|
||||||
/* Enable DOT clock */
|
/* Enable DOT clock */
|
||||||
vclkset = VCLKSET_CKEN;
|
vclkset = VCLKSET_CKEN;
|
||||||
rcar_mipi_dsi_set(dsi, VCLKSET, vclkset);
|
rcar_mipi_dsi_write(dsi, VCLKSET, vclkset);
|
||||||
|
|
||||||
if (dsi_format == 24)
|
if (dsi_format == 24)
|
||||||
vclkset |= VCLKSET_BPP_24;
|
vclkset |= VCLKSET_BPP_24;
|
||||||
@ -429,7 +430,7 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
|
|||||||
vclkset |= VCLKSET_COLOR_RGB | VCLKSET_DIV(setup_info.div)
|
vclkset |= VCLKSET_COLOR_RGB | VCLKSET_DIV(setup_info.div)
|
||||||
| VCLKSET_LANE(dsi->lanes - 1);
|
| VCLKSET_LANE(dsi->lanes - 1);
|
||||||
|
|
||||||
rcar_mipi_dsi_set(dsi, VCLKSET, vclkset);
|
rcar_mipi_dsi_write(dsi, VCLKSET, vclkset);
|
||||||
|
|
||||||
/* After setting VCLKSET register, enable VCLKEN */
|
/* After setting VCLKSET register, enable VCLKEN */
|
||||||
rcar_mipi_dsi_set(dsi, VCLKEN, VCLKEN_CKEN);
|
rcar_mipi_dsi_set(dsi, VCLKEN, VCLKEN_CKEN);
|
||||||
@ -441,9 +442,21 @@ static int rcar_mipi_dsi_startup(struct rcar_mipi_dsi *dsi,
|
|||||||
|
|
||||||
static void rcar_mipi_dsi_shutdown(struct rcar_mipi_dsi *dsi)
|
static void rcar_mipi_dsi_shutdown(struct rcar_mipi_dsi *dsi)
|
||||||
{
|
{
|
||||||
|
/* Disable VCLKEN */
|
||||||
|
rcar_mipi_dsi_write(dsi, VCLKSET, 0);
|
||||||
|
|
||||||
|
/* Disable DOT clock */
|
||||||
|
rcar_mipi_dsi_write(dsi, VCLKSET, 0);
|
||||||
|
|
||||||
rcar_mipi_dsi_clr(dsi, PHYSETUP, PHYSETUP_RSTZ);
|
rcar_mipi_dsi_clr(dsi, PHYSETUP, PHYSETUP_RSTZ);
|
||||||
rcar_mipi_dsi_clr(dsi, PHYSETUP, PHYSETUP_SHUTDOWNZ);
|
rcar_mipi_dsi_clr(dsi, PHYSETUP, PHYSETUP_SHUTDOWNZ);
|
||||||
|
|
||||||
|
/* CFGCLK disable */
|
||||||
|
rcar_mipi_dsi_clr(dsi, CFGCLKSET, CFGCLKSET_CKEN);
|
||||||
|
|
||||||
|
/* LPCLK disable */
|
||||||
|
rcar_mipi_dsi_clr(dsi, LPCLKSET, LPCLKSET_CKEN);
|
||||||
|
|
||||||
dev_dbg(dsi->dev, "DSI device is shutdown\n");
|
dev_dbg(dsi->dev, "DSI device is shutdown\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,6 +555,34 @@ static int rcar_mipi_dsi_start_video(struct rcar_mipi_dsi *dsi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rcar_mipi_dsi_stop_video(struct rcar_mipi_dsi *dsi)
|
||||||
|
{
|
||||||
|
u32 status;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Disable transmission in video mode. */
|
||||||
|
rcar_mipi_dsi_clr(dsi, TXVMCR, TXVMCR_EN_VIDEO);
|
||||||
|
|
||||||
|
ret = read_poll_timeout(rcar_mipi_dsi_read, status,
|
||||||
|
!(status & TXVMSR_ACT),
|
||||||
|
2000, 100000, false, dsi, TXVMSR);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dsi->dev, "Failed to disable video transmission\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assert video FIFO clear. */
|
||||||
|
rcar_mipi_dsi_set(dsi, TXVMCR, TXVMCR_VFCLR);
|
||||||
|
|
||||||
|
ret = read_poll_timeout(rcar_mipi_dsi_read, status,
|
||||||
|
!(status & TXVMSR_VFRDY),
|
||||||
|
2000, 100000, false, dsi, TXVMSR);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dsi->dev, "Failed to assert video FIFO clear\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Bridge
|
* Bridge
|
||||||
*/
|
*/
|
||||||
@ -558,7 +599,22 @@ static int rcar_mipi_dsi_attach(struct drm_bridge *bridge,
|
|||||||
static void rcar_mipi_dsi_atomic_enable(struct drm_bridge *bridge,
|
static void rcar_mipi_dsi_atomic_enable(struct drm_bridge *bridge,
|
||||||
struct drm_bridge_state *old_bridge_state)
|
struct drm_bridge_state *old_bridge_state)
|
||||||
{
|
{
|
||||||
struct drm_atomic_state *state = old_bridge_state->base.state;
|
struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
|
||||||
|
|
||||||
|
rcar_mipi_dsi_start_video(dsi);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rcar_mipi_dsi_atomic_disable(struct drm_bridge *bridge,
|
||||||
|
struct drm_bridge_state *old_bridge_state)
|
||||||
|
{
|
||||||
|
struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
|
||||||
|
|
||||||
|
rcar_mipi_dsi_stop_video(dsi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rcar_mipi_dsi_pclk_enable(struct drm_bridge *bridge,
|
||||||
|
struct drm_atomic_state *state)
|
||||||
|
{
|
||||||
struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
|
struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
|
||||||
const struct drm_display_mode *mode;
|
const struct drm_display_mode *mode;
|
||||||
struct drm_connector *connector;
|
struct drm_connector *connector;
|
||||||
@ -586,8 +642,6 @@ static void rcar_mipi_dsi_atomic_enable(struct drm_bridge *bridge,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_dsi_start_hs;
|
goto err_dsi_start_hs;
|
||||||
|
|
||||||
rcar_mipi_dsi_start_video(dsi);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err_dsi_start_hs:
|
err_dsi_start_hs:
|
||||||
@ -595,15 +649,16 @@ err_dsi_start_hs:
|
|||||||
err_dsi_startup:
|
err_dsi_startup:
|
||||||
rcar_mipi_dsi_clk_disable(dsi);
|
rcar_mipi_dsi_clk_disable(dsi);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(rcar_mipi_dsi_pclk_enable);
|
||||||
|
|
||||||
static void rcar_mipi_dsi_atomic_disable(struct drm_bridge *bridge,
|
void rcar_mipi_dsi_pclk_disable(struct drm_bridge *bridge)
|
||||||
struct drm_bridge_state *old_bridge_state)
|
|
||||||
{
|
{
|
||||||
struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
|
struct rcar_mipi_dsi *dsi = bridge_to_rcar_mipi_dsi(bridge);
|
||||||
|
|
||||||
rcar_mipi_dsi_shutdown(dsi);
|
rcar_mipi_dsi_shutdown(dsi);
|
||||||
rcar_mipi_dsi_clk_disable(dsi);
|
rcar_mipi_dsi_clk_disable(dsi);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(rcar_mipi_dsi_pclk_disable);
|
||||||
|
|
||||||
static enum drm_mode_status
|
static enum drm_mode_status
|
||||||
rcar_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
|
rcar_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
|
||||||
|
31
drivers/gpu/drm/rcar-du/rcar_mipi_dsi.h
Normal file
31
drivers/gpu/drm/rcar-du/rcar_mipi_dsi.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
/*
|
||||||
|
* R-Car DSI Encoder
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Renesas Electronics Corporation
|
||||||
|
*
|
||||||
|
* Contact: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RCAR_MIPI_DSI_H__
|
||||||
|
#define __RCAR_MIPI_DSI_H__
|
||||||
|
|
||||||
|
struct drm_atomic_state;
|
||||||
|
struct drm_bridge;
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_DRM_RCAR_MIPI_DSI)
|
||||||
|
void rcar_mipi_dsi_pclk_enable(struct drm_bridge *bridge,
|
||||||
|
struct drm_atomic_state *state);
|
||||||
|
void rcar_mipi_dsi_pclk_disable(struct drm_bridge *bridge);
|
||||||
|
#else
|
||||||
|
static inline void rcar_mipi_dsi_pclk_enable(struct drm_bridge *bridge,
|
||||||
|
struct drm_atomic_state *state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void rcar_mipi_dsi_pclk_disable(struct drm_bridge *bridge)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_DRM_RCAR_MIPI_DSI */
|
||||||
|
|
||||||
|
#endif /* __RCAR_MIPI_DSI_H__ */
|
@ -856,6 +856,8 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
|
|||||||
rpf->mem.addr[1] = cfg->mem[1];
|
rpf->mem.addr[1] = cfg->mem[1];
|
||||||
rpf->mem.addr[2] = cfg->mem[2];
|
rpf->mem.addr[2] = cfg->mem[2];
|
||||||
|
|
||||||
|
rpf->format.flags = cfg->premult ? V4L2_PIX_FMT_FLAG_PREMUL_ALPHA : 0;
|
||||||
|
|
||||||
vsp1->drm->inputs[rpf_index].crop = cfg->src;
|
vsp1->drm->inputs[rpf_index].crop = cfg->src;
|
||||||
vsp1->drm->inputs[rpf_index].compose = cfg->dst;
|
vsp1->drm->inputs[rpf_index].compose = cfg->dst;
|
||||||
vsp1->drm->inputs[rpf_index].zpos = cfg->zpos;
|
vsp1->drm->inputs[rpf_index].zpos = cfg->zpos;
|
||||||
|
@ -51,6 +51,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
|
|||||||
* @dst: destination rectangle on the display (integer coordinates)
|
* @dst: destination rectangle on the display (integer coordinates)
|
||||||
* @alpha: alpha value (0: fully transparent, 255: fully opaque)
|
* @alpha: alpha value (0: fully transparent, 255: fully opaque)
|
||||||
* @zpos: Z position of the plane (from 0 to number of planes minus 1)
|
* @zpos: Z position of the plane (from 0 to number of planes minus 1)
|
||||||
|
* @premult: true for premultiplied alpha
|
||||||
*/
|
*/
|
||||||
struct vsp1_du_atomic_config {
|
struct vsp1_du_atomic_config {
|
||||||
u32 pixelformat;
|
u32 pixelformat;
|
||||||
@ -60,6 +61,7 @@ struct vsp1_du_atomic_config {
|
|||||||
struct v4l2_rect dst;
|
struct v4l2_rect dst;
|
||||||
unsigned int alpha;
|
unsigned int alpha;
|
||||||
unsigned int zpos;
|
unsigned int zpos;
|
||||||
|
bool premult;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user