mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 22:26:55 +00:00
Merge branch 'sti-drm-next-2016-09-20' of https://github.com/vinceab/linux into drm-next
Here are some patches for drm-next. It contains: - minor fixes for typo and warning. - sparse and coccicheck warning fixes - bunch of patches fixing issues found while testing drm/sti with an atomic version of weston - the removal of the support of stih415-416 sti platform * 'sti-drm-next-2016-09-20' of https://github.com/vinceab/linux: drm/sti: remove stih415-416 platform support drm/sti: fix compositor debugfs creation drm/sti: use valid video mode drm/sti: in crtc_atomic_flush, enable only planes of this crtc drm/sti: use vtg array instead of vtg_main/aux drm/sti: use different notifier_block for each pipe drm/sti: fix atomic_disable check drm/sti: run gdp init sequence only once drm/sti: run hqvdp init sequence only once drm/sti: fix debug logs drm/sti: dpms function missing for HDMI connector drm/sti: Fix sparse warnings drm: sti: fix coccicheck warnings drm: sti: Replace drm_fb_get_bpp_depth() with drm_format_plane_cpp()
This commit is contained in:
commit
f01ebbdb46
19 changed files with 99 additions and 561 deletions
|
@ -1,6 +1,6 @@
|
||||||
config DRM_STI
|
config DRM_STI
|
||||||
tristate "DRM Support for STMicroelectronics SoC stiH41x Series"
|
tristate "DRM Support for STMicroelectronics SoC stiH4xx Series"
|
||||||
depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM)
|
depends on DRM && (ARCH_STI || ARCH_MULTIPLATFORM)
|
||||||
select RESET_CONTROLLER
|
select RESET_CONTROLLER
|
||||||
select DRM_KMS_HELPER
|
select DRM_KMS_HELPER
|
||||||
select DRM_GEM_CMA_HELPER
|
select DRM_GEM_CMA_HELPER
|
||||||
|
@ -9,4 +9,4 @@ config DRM_STI
|
||||||
select FW_LOADER
|
select FW_LOADER
|
||||||
select SND_SOC_HDMI_CODEC if SND_SOC
|
select SND_SOC_HDMI_CODEC if SND_SOC
|
||||||
help
|
help
|
||||||
Choose this option to enable DRM on STM stiH41x chipset
|
Choose this option to enable DRM on STM stiH4xx chipset
|
||||||
|
|
|
@ -9,7 +9,6 @@ sti-drm-y := \
|
||||||
sti_crtc.o \
|
sti_crtc.o \
|
||||||
sti_plane.o \
|
sti_plane.o \
|
||||||
sti_hdmi.o \
|
sti_hdmi.o \
|
||||||
sti_hdmi_tx3g0c55phy.o \
|
|
||||||
sti_hdmi_tx3g4c28phy.o \
|
sti_hdmi_tx3g4c28phy.o \
|
||||||
sti_dvo.o \
|
sti_dvo.o \
|
||||||
sti_awg_utils.o \
|
sti_awg_utils.o \
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
/*
|
/*
|
||||||
* stiH407 compositor properties
|
* stiH407 compositor properties
|
||||||
*/
|
*/
|
||||||
struct sti_compositor_data stih407_compositor_data = {
|
static const struct sti_compositor_data stih407_compositor_data = {
|
||||||
.nb_subdev = 8,
|
.nb_subdev = 8,
|
||||||
.subdev_desc = {
|
.subdev_desc = {
|
||||||
{STI_CURSOR_SUBDEV, (int)STI_CURSOR, 0x000},
|
{STI_CURSOR_SUBDEV, (int)STI_CURSOR, 0x000},
|
||||||
|
@ -39,38 +39,18 @@ struct sti_compositor_data stih407_compositor_data = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
int sti_compositor_debugfs_init(struct sti_compositor *compo,
|
||||||
* stiH416 compositor properties
|
struct drm_minor *minor)
|
||||||
* Note:
|
|
||||||
* on stih416 MIXER_AUX has a different base address from MIXER_MAIN
|
|
||||||
* Moreover, GDPx is different for Main and Aux Mixer. So this subdev map does
|
|
||||||
* not fit for stiH416 if we want to enable the MIXER_AUX.
|
|
||||||
*/
|
|
||||||
struct sti_compositor_data stih416_compositor_data = {
|
|
||||||
.nb_subdev = 3,
|
|
||||||
.subdev_desc = {
|
|
||||||
{STI_GPD_SUBDEV, (int)STI_GDP_0, 0x100},
|
|
||||||
{STI_GPD_SUBDEV, (int)STI_GDP_1, 0x200},
|
|
||||||
{STI_MIXER_MAIN_SUBDEV, STI_MIXER_MAIN, 0xC00}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
int sti_compositor_debufs_init(struct sti_compositor *compo,
|
|
||||||
struct drm_minor *minor)
|
|
||||||
{
|
{
|
||||||
int ret = 0, i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; compo->vid[i]; i++) {
|
for (i = 0; i < STI_MAX_VID; i++)
|
||||||
ret = vid_debugfs_init(compo->vid[i], minor);
|
if (compo->vid[i])
|
||||||
if (ret)
|
vid_debugfs_init(compo->vid[i], minor);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; compo->mixer[i]; i++) {
|
for (i = 0; i < STI_MAX_MIXER; i++)
|
||||||
ret = sti_mixer_debugfs_init(compo->mixer[i], minor);
|
if (compo->mixer[i])
|
||||||
if (ret)
|
sti_mixer_debugfs_init(compo->mixer[i], minor);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -183,9 +163,6 @@ static const struct component_ops sti_compositor_ops = {
|
||||||
|
|
||||||
static const struct of_device_id compositor_of_match[] = {
|
static const struct of_device_id compositor_of_match[] = {
|
||||||
{
|
{
|
||||||
.compatible = "st,stih416-compositor",
|
|
||||||
.data = &stih416_compositor_data,
|
|
||||||
}, {
|
|
||||||
.compatible = "st,stih407-compositor",
|
.compatible = "st,stih407-compositor",
|
||||||
.data = &stih407_compositor_data,
|
.data = &stih407_compositor_data,
|
||||||
}, {
|
}, {
|
||||||
|
@ -201,6 +178,7 @@ static int sti_compositor_probe(struct platform_device *pdev)
|
||||||
struct device_node *vtg_np;
|
struct device_node *vtg_np;
|
||||||
struct sti_compositor *compo;
|
struct sti_compositor *compo;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
compo = devm_kzalloc(dev, sizeof(*compo), GFP_KERNEL);
|
compo = devm_kzalloc(dev, sizeof(*compo), GFP_KERNEL);
|
||||||
if (!compo) {
|
if (!compo) {
|
||||||
|
@ -208,7 +186,8 @@ static int sti_compositor_probe(struct platform_device *pdev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
compo->dev = dev;
|
compo->dev = dev;
|
||||||
compo->vtg_vblank_nb.notifier_call = sti_crtc_vblank_cb;
|
for (i = 0; i < STI_MAX_MIXER; i++)
|
||||||
|
compo->vtg_vblank_nb[i].notifier_call = sti_crtc_vblank_cb;
|
||||||
|
|
||||||
/* populate data structure depending on compatibility */
|
/* populate data structure depending on compatibility */
|
||||||
BUG_ON(!of_match_node(compositor_of_match, np)->data);
|
BUG_ON(!of_match_node(compositor_of_match, np)->data);
|
||||||
|
@ -266,12 +245,12 @@ static int sti_compositor_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
vtg_np = of_parse_phandle(pdev->dev.of_node, "st,vtg", 0);
|
vtg_np = of_parse_phandle(pdev->dev.of_node, "st,vtg", 0);
|
||||||
if (vtg_np)
|
if (vtg_np)
|
||||||
compo->vtg_main = of_vtg_find(vtg_np);
|
compo->vtg[STI_MIXER_MAIN] = of_vtg_find(vtg_np);
|
||||||
of_node_put(vtg_np);
|
of_node_put(vtg_np);
|
||||||
|
|
||||||
vtg_np = of_parse_phandle(pdev->dev.of_node, "st,vtg", 1);
|
vtg_np = of_parse_phandle(pdev->dev.of_node, "st,vtg", 1);
|
||||||
if (vtg_np)
|
if (vtg_np)
|
||||||
compo->vtg_aux = of_vtg_find(vtg_np);
|
compo->vtg[STI_MIXER_AUX] = of_vtg_find(vtg_np);
|
||||||
of_node_put(vtg_np);
|
of_node_put(vtg_np);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, compo);
|
platform_set_drvdata(pdev, compo);
|
||||||
|
|
|
@ -60,9 +60,8 @@ struct sti_compositor_data {
|
||||||
* @rst_aux: reset control of the aux path
|
* @rst_aux: reset control of the aux path
|
||||||
* @mixer: array of mixers
|
* @mixer: array of mixers
|
||||||
* @vid: array of vids
|
* @vid: array of vids
|
||||||
* @vtg_main: vtg for main data path
|
* @vtg: array of vtgs
|
||||||
* @vtg_aux: vtg for auxillary data path
|
* @vtg_vblank_nb: array of callbacks for VTG VSYNC notification
|
||||||
* @vtg_vblank_nb: callback for VTG VSYNC notification
|
|
||||||
*/
|
*/
|
||||||
struct sti_compositor {
|
struct sti_compositor {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
@ -76,12 +75,11 @@ struct sti_compositor {
|
||||||
struct reset_control *rst_aux;
|
struct reset_control *rst_aux;
|
||||||
struct sti_mixer *mixer[STI_MAX_MIXER];
|
struct sti_mixer *mixer[STI_MAX_MIXER];
|
||||||
struct sti_vid *vid[STI_MAX_VID];
|
struct sti_vid *vid[STI_MAX_VID];
|
||||||
struct sti_vtg *vtg_main;
|
struct sti_vtg *vtg[STI_MAX_MIXER];
|
||||||
struct sti_vtg *vtg_aux;
|
struct notifier_block vtg_vblank_nb[STI_MAX_MIXER];
|
||||||
struct notifier_block vtg_vblank_nb;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int sti_compositor_debufs_init(struct sti_compositor *compo,
|
int sti_compositor_debugfs_init(struct sti_compositor *compo,
|
||||||
struct drm_minor *minor);
|
struct drm_minor *minor);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -86,8 +86,7 @@ sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||||
goto pix_error;
|
goto pix_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
sti_vtg_set_config(mixer->id == STI_MIXER_MAIN ?
|
sti_vtg_set_config(compo->vtg[mixer->id], &crtc->mode);
|
||||||
compo->vtg_main : compo->vtg_aux, &crtc->mode);
|
|
||||||
|
|
||||||
if (sti_mixer_active_video_area(mixer, &crtc->mode)) {
|
if (sti_mixer_active_video_area(mixer, &crtc->mode)) {
|
||||||
DRM_ERROR("Can't set active video area\n");
|
DRM_ERROR("Can't set active video area\n");
|
||||||
|
@ -166,6 +165,10 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||||
|
|
||||||
switch (plane->status) {
|
switch (plane->status) {
|
||||||
case STI_PLANE_UPDATED:
|
case STI_PLANE_UPDATED:
|
||||||
|
/* ignore update for other CRTC */
|
||||||
|
if (p->state->crtc != crtc)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* update planes tag as updated */
|
/* update planes tag as updated */
|
||||||
DRM_DEBUG_DRIVER("update plane %s\n",
|
DRM_DEBUG_DRIVER("update plane %s\n",
|
||||||
sti_plane_to_str(plane));
|
sti_plane_to_str(plane));
|
||||||
|
@ -244,8 +247,7 @@ static int sti_crtc_set_property(struct drm_crtc *crtc,
|
||||||
int sti_crtc_vblank_cb(struct notifier_block *nb,
|
int sti_crtc_vblank_cb(struct notifier_block *nb,
|
||||||
unsigned long event, void *data)
|
unsigned long event, void *data)
|
||||||
{
|
{
|
||||||
struct sti_compositor *compo =
|
struct sti_compositor *compo;
|
||||||
container_of(nb, struct sti_compositor, vtg_vblank_nb);
|
|
||||||
struct drm_crtc *crtc = data;
|
struct drm_crtc *crtc = data;
|
||||||
struct sti_mixer *mixer;
|
struct sti_mixer *mixer;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -254,6 +256,7 @@ int sti_crtc_vblank_cb(struct notifier_block *nb,
|
||||||
|
|
||||||
priv = crtc->dev->dev_private;
|
priv = crtc->dev->dev_private;
|
||||||
pipe = drm_crtc_index(crtc);
|
pipe = drm_crtc_index(crtc);
|
||||||
|
compo = container_of(nb, struct sti_compositor, vtg_vblank_nb[pipe]);
|
||||||
mixer = compo->mixer[pipe];
|
mixer = compo->mixer[pipe];
|
||||||
|
|
||||||
if ((event != VTG_TOP_FIELD_EVENT) &&
|
if ((event != VTG_TOP_FIELD_EVENT) &&
|
||||||
|
@ -295,14 +298,13 @@ int sti_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe)
|
||||||
{
|
{
|
||||||
struct sti_private *dev_priv = dev->dev_private;
|
struct sti_private *dev_priv = dev->dev_private;
|
||||||
struct sti_compositor *compo = dev_priv->compo;
|
struct sti_compositor *compo = dev_priv->compo;
|
||||||
struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb;
|
struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb[pipe];
|
||||||
struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc;
|
struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc;
|
||||||
|
struct sti_vtg *vtg = compo->vtg[pipe];
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("\n");
|
DRM_DEBUG_DRIVER("\n");
|
||||||
|
|
||||||
if (sti_vtg_register_client(pipe == STI_MIXER_MAIN ?
|
if (sti_vtg_register_client(vtg, vtg_vblank_nb, crtc)) {
|
||||||
compo->vtg_main : compo->vtg_aux,
|
|
||||||
vtg_vblank_nb, crtc)) {
|
|
||||||
DRM_ERROR("Cannot register VTG notifier\n");
|
DRM_ERROR("Cannot register VTG notifier\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -314,13 +316,13 @@ void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe)
|
||||||
{
|
{
|
||||||
struct sti_private *priv = drm_dev->dev_private;
|
struct sti_private *priv = drm_dev->dev_private;
|
||||||
struct sti_compositor *compo = priv->compo;
|
struct sti_compositor *compo = priv->compo;
|
||||||
struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb;
|
struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb[pipe];
|
||||||
struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc;
|
struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc;
|
||||||
|
struct sti_vtg *vtg = compo->vtg[pipe];
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("\n");
|
DRM_DEBUG_DRIVER("\n");
|
||||||
|
|
||||||
if (sti_vtg_unregister_client(pipe == STI_MIXER_MAIN ?
|
if (sti_vtg_unregister_client(vtg, vtg_vblank_nb))
|
||||||
compo->vtg_main : compo->vtg_aux, vtg_vblank_nb))
|
|
||||||
DRM_DEBUG_DRIVER("Warning: cannot unregister VTG notifier\n");
|
DRM_DEBUG_DRIVER("Warning: cannot unregister VTG notifier\n");
|
||||||
|
|
||||||
/* free the resources of the pending requests */
|
/* free the resources of the pending requests */
|
||||||
|
@ -336,7 +338,7 @@ static int sti_crtc_late_register(struct drm_crtc *crtc)
|
||||||
struct sti_compositor *compo = dev_get_drvdata(mixer->dev);
|
struct sti_compositor *compo = dev_get_drvdata(mixer->dev);
|
||||||
|
|
||||||
if (drm_crtc_index(crtc) == 0)
|
if (drm_crtc_index(crtc) == 0)
|
||||||
return sti_compositor_debufs_init(compo, crtc->dev->primary);
|
return sti_compositor_debugfs_init(compo, crtc->dev->primary);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,15 +309,15 @@ static void sti_cursor_atomic_disable(struct drm_plane *drm_plane,
|
||||||
{
|
{
|
||||||
struct sti_plane *plane = to_sti_plane(drm_plane);
|
struct sti_plane *plane = to_sti_plane(drm_plane);
|
||||||
|
|
||||||
if (!drm_plane->crtc) {
|
if (!oldstate->crtc) {
|
||||||
DRM_DEBUG_DRIVER("drm plane:%d not enabled\n",
|
DRM_DEBUG_DRIVER("drm plane:%d not enabled\n",
|
||||||
drm_plane->base.id);
|
drm_plane->base.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("CRTC:%d (%s) drm plane:%d (%s)\n",
|
DRM_DEBUG_DRIVER("CRTC:%d (%s) drm plane:%d (%s)\n",
|
||||||
drm_plane->crtc->base.id,
|
oldstate->crtc->base.id,
|
||||||
sti_mixer_to_str(to_sti_mixer(drm_plane->crtc)),
|
sti_mixer_to_str(to_sti_mixer(oldstate->crtc)),
|
||||||
drm_plane->base.id, sti_plane_to_str(plane));
|
drm_plane->base.id, sti_plane_to_str(plane));
|
||||||
|
|
||||||
plane->status = STI_PLANE_DISABLING;
|
plane->status = STI_PLANE_DISABLING;
|
||||||
|
@ -345,7 +345,7 @@ static int sti_cursor_late_register(struct drm_plane *drm_plane)
|
||||||
return cursor_debugfs_init(cursor, drm_plane->dev->primary);
|
return cursor_debugfs_init(cursor, drm_plane->dev->primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drm_plane_funcs sti_cursor_plane_helpers_funcs = {
|
static const struct drm_plane_funcs sti_cursor_plane_helpers_funcs = {
|
||||||
.update_plane = drm_atomic_helper_update_plane,
|
.update_plane = drm_atomic_helper_update_plane,
|
||||||
.disable_plane = drm_atomic_helper_disable_plane,
|
.disable_plane = drm_atomic_helper_disable_plane,
|
||||||
.destroy = sti_cursor_destroy,
|
.destroy = sti_cursor_destroy,
|
||||||
|
|
|
@ -140,7 +140,7 @@ static int sti_drm_dbg_init(struct drm_minor *minor)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sti_drm_dbg_cleanup(struct drm_minor *minor)
|
static void sti_drm_dbg_cleanup(struct drm_minor *minor)
|
||||||
{
|
{
|
||||||
drm_debugfs_remove_files(sti_drm_dbg_list,
|
drm_debugfs_remove_files(sti_drm_dbg_list,
|
||||||
ARRAY_SIZE(sti_drm_dbg_list), minor);
|
ARRAY_SIZE(sti_drm_dbg_list), minor);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <drm/drm_panel.h>
|
#include <drm/drm_panel.h>
|
||||||
|
|
||||||
#include "sti_awg_utils.h"
|
#include "sti_awg_utils.h"
|
||||||
|
#include "sti_drv.h"
|
||||||
#include "sti_mixer.h"
|
#include "sti_mixer.h"
|
||||||
|
|
||||||
/* DVO registers */
|
/* DVO registers */
|
||||||
|
@ -106,7 +107,7 @@ struct sti_dvo_connector {
|
||||||
container_of(x, struct sti_dvo_connector, drm_connector)
|
container_of(x, struct sti_dvo_connector, drm_connector)
|
||||||
|
|
||||||
#define BLANKING_LEVEL 16
|
#define BLANKING_LEVEL 16
|
||||||
int dvo_awg_generate_code(struct sti_dvo *dvo, u8 *ram_size, u32 *ram_code)
|
static int dvo_awg_generate_code(struct sti_dvo *dvo, u8 *ram_size, u32 *ram_code)
|
||||||
{
|
{
|
||||||
struct drm_display_mode *mode = &dvo->mode;
|
struct drm_display_mode *mode = &dvo->mode;
|
||||||
struct dvo_config *config = dvo->config;
|
struct dvo_config *config = dvo->config;
|
||||||
|
|
|
@ -460,6 +460,7 @@ static void sti_gdp_disable(struct sti_gdp *gdp)
|
||||||
clk_disable_unprepare(gdp->clk_pix);
|
clk_disable_unprepare(gdp->clk_pix);
|
||||||
|
|
||||||
gdp->plane.status = STI_PLANE_DISABLED;
|
gdp->plane.status = STI_PLANE_DISABLED;
|
||||||
|
gdp->vtg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -473,8 +474,8 @@ static void sti_gdp_disable(struct sti_gdp *gdp)
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* 0 on success.
|
* 0 on success.
|
||||||
*/
|
*/
|
||||||
int sti_gdp_field_cb(struct notifier_block *nb,
|
static int sti_gdp_field_cb(struct notifier_block *nb,
|
||||||
unsigned long event, void *data)
|
unsigned long event, void *data)
|
||||||
{
|
{
|
||||||
struct sti_gdp *gdp = container_of(nb, struct sti_gdp, vtg_field_nb);
|
struct sti_gdp *gdp = container_of(nb, struct sti_gdp, vtg_field_nb);
|
||||||
|
|
||||||
|
@ -611,7 +612,6 @@ static int sti_gdp_atomic_check(struct drm_plane *drm_plane,
|
||||||
struct drm_crtc *crtc = state->crtc;
|
struct drm_crtc *crtc = state->crtc;
|
||||||
struct sti_compositor *compo = dev_get_drvdata(gdp->dev);
|
struct sti_compositor *compo = dev_get_drvdata(gdp->dev);
|
||||||
struct drm_framebuffer *fb = state->fb;
|
struct drm_framebuffer *fb = state->fb;
|
||||||
bool first_prepare = plane->status == STI_PLANE_DISABLED ? true : false;
|
|
||||||
struct drm_crtc_state *crtc_state;
|
struct drm_crtc_state *crtc_state;
|
||||||
struct sti_mixer *mixer;
|
struct sti_mixer *mixer;
|
||||||
struct drm_display_mode *mode;
|
struct drm_display_mode *mode;
|
||||||
|
@ -628,8 +628,8 @@ static int sti_gdp_atomic_check(struct drm_plane *drm_plane,
|
||||||
mode = &crtc_state->mode;
|
mode = &crtc_state->mode;
|
||||||
dst_x = state->crtc_x;
|
dst_x = state->crtc_x;
|
||||||
dst_y = state->crtc_y;
|
dst_y = state->crtc_y;
|
||||||
dst_w = clamp_val(state->crtc_w, 0, mode->crtc_hdisplay - dst_x);
|
dst_w = clamp_val(state->crtc_w, 0, mode->hdisplay - dst_x);
|
||||||
dst_h = clamp_val(state->crtc_h, 0, mode->crtc_vdisplay - dst_y);
|
dst_h = clamp_val(state->crtc_h, 0, mode->vdisplay - dst_y);
|
||||||
/* src_x are in 16.16 format */
|
/* src_x are in 16.16 format */
|
||||||
src_x = state->src_x >> 16;
|
src_x = state->src_x >> 16;
|
||||||
src_y = state->src_y >> 16;
|
src_y = state->src_y >> 16;
|
||||||
|
@ -648,10 +648,9 @@ static int sti_gdp_atomic_check(struct drm_plane *drm_plane,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_prepare) {
|
if (!gdp->vtg) {
|
||||||
/* Register gdp callback */
|
/* Register gdp callback */
|
||||||
gdp->vtg = mixer->id == STI_MIXER_MAIN ?
|
gdp->vtg = compo->vtg[mixer->id];
|
||||||
compo->vtg_main : compo->vtg_aux;
|
|
||||||
if (sti_vtg_register_client(gdp->vtg,
|
if (sti_vtg_register_client(gdp->vtg,
|
||||||
&gdp->vtg_field_nb, crtc)) {
|
&gdp->vtg_field_nb, crtc)) {
|
||||||
DRM_ERROR("Cannot register VTG notifier\n");
|
DRM_ERROR("Cannot register VTG notifier\n");
|
||||||
|
@ -719,7 +718,7 @@ static void sti_gdp_atomic_update(struct drm_plane *drm_plane,
|
||||||
u32 dma_updated_top;
|
u32 dma_updated_top;
|
||||||
u32 dma_updated_btm;
|
u32 dma_updated_btm;
|
||||||
int format;
|
int format;
|
||||||
unsigned int depth, bpp;
|
unsigned int bpp;
|
||||||
u32 ydo, xdo, yds, xds;
|
u32 ydo, xdo, yds, xds;
|
||||||
|
|
||||||
if (!crtc || !fb)
|
if (!crtc || !fb)
|
||||||
|
@ -728,8 +727,8 @@ static void sti_gdp_atomic_update(struct drm_plane *drm_plane,
|
||||||
mode = &crtc->mode;
|
mode = &crtc->mode;
|
||||||
dst_x = state->crtc_x;
|
dst_x = state->crtc_x;
|
||||||
dst_y = state->crtc_y;
|
dst_y = state->crtc_y;
|
||||||
dst_w = clamp_val(state->crtc_w, 0, mode->crtc_hdisplay - dst_x);
|
dst_w = clamp_val(state->crtc_w, 0, mode->hdisplay - dst_x);
|
||||||
dst_h = clamp_val(state->crtc_h, 0, mode->crtc_vdisplay - dst_y);
|
dst_h = clamp_val(state->crtc_h, 0, mode->vdisplay - dst_y);
|
||||||
/* src_x are in 16.16 format */
|
/* src_x are in 16.16 format */
|
||||||
src_x = state->src_x >> 16;
|
src_x = state->src_x >> 16;
|
||||||
src_y = state->src_y >> 16;
|
src_y = state->src_y >> 16;
|
||||||
|
@ -758,9 +757,9 @@ static void sti_gdp_atomic_update(struct drm_plane *drm_plane,
|
||||||
(unsigned long)cma_obj->paddr);
|
(unsigned long)cma_obj->paddr);
|
||||||
|
|
||||||
/* pixel memory location */
|
/* pixel memory location */
|
||||||
drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
|
bpp = drm_format_plane_cpp(fb->pixel_format, 0);
|
||||||
top_field->gam_gdp_pml = (u32)cma_obj->paddr + fb->offsets[0];
|
top_field->gam_gdp_pml = (u32)cma_obj->paddr + fb->offsets[0];
|
||||||
top_field->gam_gdp_pml += src_x * (bpp >> 3);
|
top_field->gam_gdp_pml += src_x * bpp;
|
||||||
top_field->gam_gdp_pml += src_y * fb->pitches[0];
|
top_field->gam_gdp_pml += src_y * fb->pitches[0];
|
||||||
|
|
||||||
/* output parameters (clamped / cropped) */
|
/* output parameters (clamped / cropped) */
|
||||||
|
@ -810,7 +809,7 @@ static void sti_gdp_atomic_update(struct drm_plane *drm_plane,
|
||||||
if (!curr_list) {
|
if (!curr_list) {
|
||||||
/* First update or invalid node should directly write in the
|
/* First update or invalid node should directly write in the
|
||||||
* hw register */
|
* hw register */
|
||||||
DRM_DEBUG_DRIVER("%s first update (or invalid node)",
|
DRM_DEBUG_DRIVER("%s first update (or invalid node)\n",
|
||||||
sti_plane_to_str(plane));
|
sti_plane_to_str(plane));
|
||||||
|
|
||||||
writel(gdp->is_curr_top ?
|
writel(gdp->is_curr_top ?
|
||||||
|
@ -846,15 +845,15 @@ static void sti_gdp_atomic_disable(struct drm_plane *drm_plane,
|
||||||
{
|
{
|
||||||
struct sti_plane *plane = to_sti_plane(drm_plane);
|
struct sti_plane *plane = to_sti_plane(drm_plane);
|
||||||
|
|
||||||
if (!drm_plane->crtc) {
|
if (!oldstate->crtc) {
|
||||||
DRM_DEBUG_DRIVER("drm plane:%d not enabled\n",
|
DRM_DEBUG_DRIVER("drm plane:%d not enabled\n",
|
||||||
drm_plane->base.id);
|
drm_plane->base.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("CRTC:%d (%s) drm plane:%d (%s)\n",
|
DRM_DEBUG_DRIVER("CRTC:%d (%s) drm plane:%d (%s)\n",
|
||||||
drm_plane->crtc->base.id,
|
oldstate->crtc->base.id,
|
||||||
sti_mixer_to_str(to_sti_mixer(drm_plane->crtc)),
|
sti_mixer_to_str(to_sti_mixer(oldstate->crtc)),
|
||||||
drm_plane->base.id, sti_plane_to_str(plane));
|
drm_plane->base.id, sti_plane_to_str(plane));
|
||||||
|
|
||||||
plane->status = STI_PLANE_DISABLING;
|
plane->status = STI_PLANE_DISABLING;
|
||||||
|
@ -882,7 +881,7 @@ static int sti_gdp_late_register(struct drm_plane *drm_plane)
|
||||||
return gdp_debugfs_init(gdp, drm_plane->dev->primary);
|
return gdp_debugfs_init(gdp, drm_plane->dev->primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drm_plane_funcs sti_gdp_plane_helpers_funcs = {
|
static const struct drm_plane_funcs sti_gdp_plane_helpers_funcs = {
|
||||||
.update_plane = drm_atomic_helper_update_plane,
|
.update_plane = drm_atomic_helper_update_plane,
|
||||||
.disable_plane = drm_atomic_helper_disable_plane,
|
.disable_plane = drm_atomic_helper_disable_plane,
|
||||||
.destroy = sti_gdp_destroy,
|
.destroy = sti_gdp_destroy,
|
||||||
|
|
|
@ -62,14 +62,8 @@
|
||||||
#define SCALE_CTRL_CR_DFLT 0x00DB0249
|
#define SCALE_CTRL_CR_DFLT 0x00DB0249
|
||||||
|
|
||||||
/* Video DACs control */
|
/* Video DACs control */
|
||||||
#define VIDEO_DACS_CONTROL_MASK 0x0FFF
|
|
||||||
#define VIDEO_DACS_CONTROL_SYSCFG2535 0x085C /* for stih416 */
|
|
||||||
#define DAC_CFG_HD_OFF_SHIFT 5
|
|
||||||
#define DAC_CFG_HD_OFF_MASK (0x7 << DAC_CFG_HD_OFF_SHIFT)
|
|
||||||
#define VIDEO_DACS_CONTROL_SYSCFG5072 0x0120 /* for stih407 */
|
|
||||||
#define DAC_CFG_HD_HZUVW_OFF_MASK BIT(1)
|
#define DAC_CFG_HD_HZUVW_OFF_MASK BIT(1)
|
||||||
|
|
||||||
|
|
||||||
/* Upsampler values for the alternative 2X Filter */
|
/* Upsampler values for the alternative 2X Filter */
|
||||||
#define SAMPLER_COEF_NB 8
|
#define SAMPLER_COEF_NB 8
|
||||||
#define HDA_ANA_SRC_Y_CFG_ALT_2X 0x01130000
|
#define HDA_ANA_SRC_Y_CFG_ALT_2X 0x01130000
|
||||||
|
@ -300,28 +294,14 @@ static bool hda_get_mode_idx(struct drm_display_mode mode, int *idx)
|
||||||
*/
|
*/
|
||||||
static void hda_enable_hd_dacs(struct sti_hda *hda, bool enable)
|
static void hda_enable_hd_dacs(struct sti_hda *hda, bool enable)
|
||||||
{
|
{
|
||||||
u32 mask;
|
|
||||||
|
|
||||||
if (hda->video_dacs_ctrl) {
|
if (hda->video_dacs_ctrl) {
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
switch ((u32)hda->video_dacs_ctrl & VIDEO_DACS_CONTROL_MASK) {
|
|
||||||
case VIDEO_DACS_CONTROL_SYSCFG2535:
|
|
||||||
mask = DAC_CFG_HD_OFF_MASK;
|
|
||||||
break;
|
|
||||||
case VIDEO_DACS_CONTROL_SYSCFG5072:
|
|
||||||
mask = DAC_CFG_HD_HZUVW_OFF_MASK;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DRM_INFO("Video DACS control register not supported!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = readl(hda->video_dacs_ctrl);
|
val = readl(hda->video_dacs_ctrl);
|
||||||
if (enable)
|
if (enable)
|
||||||
val &= ~mask;
|
val &= ~DAC_CFG_HD_HZUVW_OFF_MASK;
|
||||||
else
|
else
|
||||||
val |= mask;
|
val |= DAC_CFG_HD_HZUVW_OFF_MASK;
|
||||||
|
|
||||||
writel(val, hda->video_dacs_ctrl);
|
writel(val, hda->video_dacs_ctrl);
|
||||||
}
|
}
|
||||||
|
@ -352,24 +332,11 @@ static void hda_dbg_awg_microcode(struct seq_file *s, void __iomem *reg)
|
||||||
static void hda_dbg_video_dacs_ctrl(struct seq_file *s, void __iomem *reg)
|
static void hda_dbg_video_dacs_ctrl(struct seq_file *s, void __iomem *reg)
|
||||||
{
|
{
|
||||||
u32 val = readl(reg);
|
u32 val = readl(reg);
|
||||||
u32 mask;
|
|
||||||
|
|
||||||
switch ((u32)reg & VIDEO_DACS_CONTROL_MASK) {
|
|
||||||
case VIDEO_DACS_CONTROL_SYSCFG2535:
|
|
||||||
mask = DAC_CFG_HD_OFF_MASK;
|
|
||||||
break;
|
|
||||||
case VIDEO_DACS_CONTROL_SYSCFG5072:
|
|
||||||
mask = DAC_CFG_HD_HZUVW_OFF_MASK;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DRM_DEBUG_DRIVER("Warning: DACS ctrl register not supported!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_puts(s, "\n");
|
seq_puts(s, "\n");
|
||||||
seq_printf(s, "\n %-25s 0x%08X", "VIDEO_DACS_CONTROL", val);
|
seq_printf(s, "\n %-25s 0x%08X", "VIDEO_DACS_CONTROL", val);
|
||||||
seq_puts(s, "\tHD DACs ");
|
seq_puts(s, "\tHD DACs ");
|
||||||
seq_puts(s, val & mask ? "disabled" : "enabled");
|
seq_puts(s, val & DAC_CFG_HD_HZUVW_OFF_MASK ? "disabled" : "enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hda_dbg_show(struct seq_file *s, void *data)
|
static int hda_dbg_show(struct seq_file *s, void *data)
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include "sti_hdmi.h"
|
#include "sti_hdmi.h"
|
||||||
#include "sti_hdmi_tx3g4c28phy.h"
|
#include "sti_hdmi_tx3g4c28phy.h"
|
||||||
#include "sti_hdmi_tx3g0c55phy.h"
|
|
||||||
#include "sti_vtg.h"
|
#include "sti_vtg.h"
|
||||||
|
|
||||||
#define HDMI_CFG 0x0000
|
#define HDMI_CFG 0x0000
|
||||||
|
@ -203,7 +202,7 @@ static irqreturn_t hdmi_irq_thread(int irq, void *arg)
|
||||||
|
|
||||||
/* Audio FIFO underrun IRQ */
|
/* Audio FIFO underrun IRQ */
|
||||||
if (hdmi->irq_status & HDMI_INT_AUDIO_FIFO_XRUN)
|
if (hdmi->irq_status & HDMI_INT_AUDIO_FIFO_XRUN)
|
||||||
DRM_INFO("Warning: audio FIFO underrun occurs!");
|
DRM_INFO("Warning: audio FIFO underrun occurs!\n");
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
@ -569,7 +568,7 @@ static void hdmi_swreset(struct sti_hdmi *hdmi)
|
||||||
|
|
||||||
/* Wait reset completed */
|
/* Wait reset completed */
|
||||||
wait_event_interruptible_timeout(hdmi->wait_event,
|
wait_event_interruptible_timeout(hdmi->wait_event,
|
||||||
hdmi->event_received == true,
|
hdmi->event_received,
|
||||||
msecs_to_jiffies
|
msecs_to_jiffies
|
||||||
(HDMI_TIMEOUT_SWRESET));
|
(HDMI_TIMEOUT_SWRESET));
|
||||||
|
|
||||||
|
@ -1054,6 +1053,7 @@ static int sti_hdmi_late_register(struct drm_connector *connector)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct drm_connector_funcs sti_hdmi_connector_funcs = {
|
static const struct drm_connector_funcs sti_hdmi_connector_funcs = {
|
||||||
|
.dpms = drm_atomic_helper_connector_dpms,
|
||||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||||
.detect = sti_hdmi_connector_detect,
|
.detect = sti_hdmi_connector_detect,
|
||||||
.destroy = drm_connector_cleanup,
|
.destroy = drm_connector_cleanup,
|
||||||
|
@ -1181,7 +1181,7 @@ static void hdmi_audio_shutdown(struct device *dev, void *data)
|
||||||
HDMI_AUD_CFG_ONE_BIT_INVALID;
|
HDMI_AUD_CFG_ONE_BIT_INVALID;
|
||||||
hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG);
|
hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG);
|
||||||
|
|
||||||
hdmi->audio.enabled = 0;
|
hdmi->audio.enabled = false;
|
||||||
hdmi_audio_infoframe_config(hdmi);
|
hdmi_audio_infoframe_config(hdmi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1213,7 +1213,7 @@ static int hdmi_audio_hw_params(struct device *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
audio.enabled = 1;
|
audio.enabled = true;
|
||||||
|
|
||||||
ret = hdmi_audio_configure(hdmi, &audio);
|
ret = hdmi_audio_configure(hdmi, &audio);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -1265,7 +1265,7 @@ static int sti_hdmi_register_audio_driver(struct device *dev,
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("\n");
|
DRM_DEBUG_DRIVER("\n");
|
||||||
|
|
||||||
hdmi->audio.enabled = 0;
|
hdmi->audio.enabled = false;
|
||||||
|
|
||||||
hdmi->audio_pdev = platform_device_register_data(
|
hdmi->audio_pdev = platform_device_register_data(
|
||||||
dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
|
dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
|
||||||
|
@ -1373,9 +1373,6 @@ static const struct component_ops sti_hdmi_ops = {
|
||||||
|
|
||||||
static const struct of_device_id hdmi_of_match[] = {
|
static const struct of_device_id hdmi_of_match[] = {
|
||||||
{
|
{
|
||||||
.compatible = "st,stih416-hdmi",
|
|
||||||
.data = &tx3g0c55phy_ops,
|
|
||||||
}, {
|
|
||||||
.compatible = "st,stih407-hdmi",
|
.compatible = "st,stih407-hdmi",
|
||||||
.data = &tx3g4c28phy_ops,
|
.data = &tx3g4c28phy_ops,
|
||||||
}, {
|
}, {
|
||||||
|
@ -1422,22 +1419,6 @@ static int sti_hdmi_probe(struct platform_device *pdev)
|
||||||
goto release_adapter;
|
goto release_adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (of_device_is_compatible(np, "st,stih416-hdmi")) {
|
|
||||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
|
||||||
"syscfg");
|
|
||||||
if (!res) {
|
|
||||||
DRM_ERROR("Invalid syscfg resource\n");
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto release_adapter;
|
|
||||||
}
|
|
||||||
hdmi->syscfg = devm_ioremap_nocache(dev, res->start,
|
|
||||||
resource_size(res));
|
|
||||||
if (!hdmi->syscfg) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto release_adapter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hdmi->phy_ops = (struct hdmi_phy_ops *)
|
hdmi->phy_ops = (struct hdmi_phy_ops *)
|
||||||
of_match_node(hdmi_of_match, np)->data;
|
of_match_node(hdmi_of_match, np)->data;
|
||||||
|
|
||||||
|
|
|
@ -1,336 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) STMicroelectronics SA 2014
|
|
||||||
* Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
|
|
||||||
* License terms: GNU General Public License (GPL), version 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sti_hdmi_tx3g0c55phy.h"
|
|
||||||
|
|
||||||
#define HDMI_SRZ_PLL_CFG 0x0504
|
|
||||||
#define HDMI_SRZ_TAP_1 0x0508
|
|
||||||
#define HDMI_SRZ_TAP_2 0x050C
|
|
||||||
#define HDMI_SRZ_TAP_3 0x0510
|
|
||||||
#define HDMI_SRZ_CTRL 0x0514
|
|
||||||
|
|
||||||
#define HDMI_SRZ_PLL_CFG_POWER_DOWN BIT(0)
|
|
||||||
#define HDMI_SRZ_PLL_CFG_VCOR_SHIFT 1
|
|
||||||
#define HDMI_SRZ_PLL_CFG_VCOR_425MHZ 0
|
|
||||||
#define HDMI_SRZ_PLL_CFG_VCOR_850MHZ 1
|
|
||||||
#define HDMI_SRZ_PLL_CFG_VCOR_1700MHZ 2
|
|
||||||
#define HDMI_SRZ_PLL_CFG_VCOR_3000MHZ 3
|
|
||||||
#define HDMI_SRZ_PLL_CFG_VCOR_MASK 3
|
|
||||||
#define HDMI_SRZ_PLL_CFG_VCOR(x) (x << HDMI_SRZ_PLL_CFG_VCOR_SHIFT)
|
|
||||||
#define HDMI_SRZ_PLL_CFG_NDIV_SHIFT 8
|
|
||||||
#define HDMI_SRZ_PLL_CFG_NDIV_MASK (0x1F << HDMI_SRZ_PLL_CFG_NDIV_SHIFT)
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_SHIFT 16
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_13_5_MHZ 0x1
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_25_2_MHZ 0x4
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_27_MHZ 0x5
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_33_75_MHZ 0x6
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_40_5_MHZ 0x7
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_54_MHZ 0x8
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_67_5_MHZ 0x9
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_74_25_MHZ 0xA
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_81_MHZ 0xB
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_82_5_MHZ 0xC
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_108_MHZ 0xD
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_148_5_MHZ 0xE
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_165_MHZ 0xF
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE_MASK 0xF
|
|
||||||
#define HDMI_SRZ_PLL_CFG_MODE(x) (x << HDMI_SRZ_PLL_CFG_MODE_SHIFT)
|
|
||||||
|
|
||||||
#define HDMI_SRZ_CTRL_POWER_DOWN (1 << 0)
|
|
||||||
#define HDMI_SRZ_CTRL_EXTERNAL_DATA_EN (1 << 1)
|
|
||||||
|
|
||||||
/* sysconf registers */
|
|
||||||
#define HDMI_REJECTION_PLL_CONFIGURATION 0x0858 /* SYSTEM_CONFIG2534 */
|
|
||||||
#define HDMI_REJECTION_PLL_STATUS 0x0948 /* SYSTEM_CONFIG2594 */
|
|
||||||
|
|
||||||
#define REJECTION_PLL_HDMI_ENABLE_SHIFT 0
|
|
||||||
#define REJECTION_PLL_HDMI_ENABLE_MASK (0x1 << REJECTION_PLL_HDMI_ENABLE_SHIFT)
|
|
||||||
#define REJECTION_PLL_HDMI_PDIV_SHIFT 24
|
|
||||||
#define REJECTION_PLL_HDMI_PDIV_MASK (0x7 << REJECTION_PLL_HDMI_PDIV_SHIFT)
|
|
||||||
#define REJECTION_PLL_HDMI_NDIV_SHIFT 16
|
|
||||||
#define REJECTION_PLL_HDMI_NDIV_MASK (0xFF << REJECTION_PLL_HDMI_NDIV_SHIFT)
|
|
||||||
#define REJECTION_PLL_HDMI_MDIV_SHIFT 8
|
|
||||||
#define REJECTION_PLL_HDMI_MDIV_MASK (0xFF << REJECTION_PLL_HDMI_MDIV_SHIFT)
|
|
||||||
|
|
||||||
#define REJECTION_PLL_HDMI_REJ_PLL_LOCK BIT(0)
|
|
||||||
|
|
||||||
#define HDMI_TIMEOUT_PLL_LOCK 50 /*milliseconds */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pll mode structure
|
|
||||||
*
|
|
||||||
* A pointer to an array of these structures is passed to a TMDS (HDMI) output
|
|
||||||
* via the control interface to provide board and SoC specific
|
|
||||||
* configurations of the HDMI PHY. Each entry in the array specifies a hardware
|
|
||||||
* specific configuration for a given TMDS clock frequency range. The array
|
|
||||||
* should be terminated with an entry that has all fields set to zero.
|
|
||||||
*
|
|
||||||
* @min: Lower bound of TMDS clock frequency this entry applies to
|
|
||||||
* @max: Upper bound of TMDS clock frequency this entry applies to
|
|
||||||
* @mode: SoC specific register configuration
|
|
||||||
*/
|
|
||||||
struct pllmode {
|
|
||||||
u32 min;
|
|
||||||
u32 max;
|
|
||||||
u32 mode;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NB_PLL_MODE 7
|
|
||||||
static struct pllmode pllmodes[NB_PLL_MODE] = {
|
|
||||||
{13500000, 13513500, HDMI_SRZ_PLL_CFG_MODE_13_5_MHZ},
|
|
||||||
{25174800, 25200000, HDMI_SRZ_PLL_CFG_MODE_25_2_MHZ},
|
|
||||||
{27000000, 27027000, HDMI_SRZ_PLL_CFG_MODE_27_MHZ},
|
|
||||||
{54000000, 54054000, HDMI_SRZ_PLL_CFG_MODE_54_MHZ},
|
|
||||||
{72000000, 74250000, HDMI_SRZ_PLL_CFG_MODE_74_25_MHZ},
|
|
||||||
{108000000, 108108000, HDMI_SRZ_PLL_CFG_MODE_108_MHZ},
|
|
||||||
{148351648, 297000000, HDMI_SRZ_PLL_CFG_MODE_148_5_MHZ}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NB_HDMI_PHY_CONFIG 5
|
|
||||||
static struct hdmi_phy_config hdmiphy_config[NB_HDMI_PHY_CONFIG] = {
|
|
||||||
{0, 40000000, {0x00101010, 0x00101010, 0x00101010, 0x02} },
|
|
||||||
{40000000, 140000000, {0x00111111, 0x00111111, 0x00111111, 0x02} },
|
|
||||||
{140000000, 160000000, {0x00131313, 0x00101010, 0x00101010, 0x02} },
|
|
||||||
{160000000, 250000000, {0x00131313, 0x00111111, 0x00111111, 0x03FE} },
|
|
||||||
{250000000, 300000000, {0x00151515, 0x00101010, 0x00101010, 0x03FE} },
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PLL_CHANGE_DELAY 1 /* ms */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable the pll rejection
|
|
||||||
*
|
|
||||||
* @hdmi: pointer on the hdmi internal structure
|
|
||||||
*
|
|
||||||
* return true if the pll has been disabled
|
|
||||||
*/
|
|
||||||
static bool disable_pll_rejection(struct sti_hdmi *hdmi)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("\n");
|
|
||||||
|
|
||||||
val = readl(hdmi->syscfg + HDMI_REJECTION_PLL_CONFIGURATION);
|
|
||||||
val &= ~REJECTION_PLL_HDMI_ENABLE_MASK;
|
|
||||||
writel(val, hdmi->syscfg + HDMI_REJECTION_PLL_CONFIGURATION);
|
|
||||||
|
|
||||||
msleep(PLL_CHANGE_DELAY);
|
|
||||||
val = readl(hdmi->syscfg + HDMI_REJECTION_PLL_STATUS);
|
|
||||||
|
|
||||||
return !(val & REJECTION_PLL_HDMI_REJ_PLL_LOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable the old BCH/rejection PLL is now reused to provide the CLKPXPLL
|
|
||||||
* clock input to the new PHY PLL that generates the serializer clock
|
|
||||||
* (TMDS*10) and the TMDS clock which is now fed back into the HDMI
|
|
||||||
* formatter instead of the TMDS clock line from ClockGenB.
|
|
||||||
*
|
|
||||||
* @hdmi: pointer on the hdmi internal structure
|
|
||||||
*
|
|
||||||
* return true if pll has been correctly set
|
|
||||||
*/
|
|
||||||
static bool enable_pll_rejection(struct sti_hdmi *hdmi)
|
|
||||||
{
|
|
||||||
unsigned int inputclock;
|
|
||||||
u32 mdiv, ndiv, pdiv, val;
|
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("\n");
|
|
||||||
|
|
||||||
if (!disable_pll_rejection(hdmi))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
inputclock = hdmi->mode.clock * 1000;
|
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("hdmi rejection pll input clock = %dHz\n", inputclock);
|
|
||||||
|
|
||||||
|
|
||||||
/* Power up the HDMI rejection PLL
|
|
||||||
* Note: On this SoC (stiH416) we are forced to have the input clock
|
|
||||||
* be equal to the HDMI pixel clock.
|
|
||||||
*
|
|
||||||
* The values here have been suggested by validation however they are
|
|
||||||
* still provisional and subject to change.
|
|
||||||
*
|
|
||||||
* PLLout = (Fin*Mdiv) / ((2 * Ndiv) / 2^Pdiv)
|
|
||||||
*/
|
|
||||||
if (inputclock < 50000000) {
|
|
||||||
/*
|
|
||||||
* For slower clocks we need to multiply more to keep the
|
|
||||||
* internal VCO frequency within the physical specification
|
|
||||||
* of the PLL.
|
|
||||||
*/
|
|
||||||
pdiv = 4;
|
|
||||||
ndiv = 240;
|
|
||||||
mdiv = 30;
|
|
||||||
} else {
|
|
||||||
pdiv = 2;
|
|
||||||
ndiv = 60;
|
|
||||||
mdiv = 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = readl(hdmi->syscfg + HDMI_REJECTION_PLL_CONFIGURATION);
|
|
||||||
|
|
||||||
val &= ~(REJECTION_PLL_HDMI_PDIV_MASK |
|
|
||||||
REJECTION_PLL_HDMI_NDIV_MASK |
|
|
||||||
REJECTION_PLL_HDMI_MDIV_MASK |
|
|
||||||
REJECTION_PLL_HDMI_ENABLE_MASK);
|
|
||||||
|
|
||||||
val |= (pdiv << REJECTION_PLL_HDMI_PDIV_SHIFT) |
|
|
||||||
(ndiv << REJECTION_PLL_HDMI_NDIV_SHIFT) |
|
|
||||||
(mdiv << REJECTION_PLL_HDMI_MDIV_SHIFT) |
|
|
||||||
(0x1 << REJECTION_PLL_HDMI_ENABLE_SHIFT);
|
|
||||||
|
|
||||||
writel(val, hdmi->syscfg + HDMI_REJECTION_PLL_CONFIGURATION);
|
|
||||||
|
|
||||||
msleep(PLL_CHANGE_DELAY);
|
|
||||||
val = readl(hdmi->syscfg + HDMI_REJECTION_PLL_STATUS);
|
|
||||||
|
|
||||||
return (val & REJECTION_PLL_HDMI_REJ_PLL_LOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start hdmi phy macro cell tx3g0c55
|
|
||||||
*
|
|
||||||
* @hdmi: pointer on the hdmi internal structure
|
|
||||||
*
|
|
||||||
* Return false if an error occur
|
|
||||||
*/
|
|
||||||
static bool sti_hdmi_tx3g0c55phy_start(struct sti_hdmi *hdmi)
|
|
||||||
{
|
|
||||||
u32 ckpxpll = hdmi->mode.clock * 1000;
|
|
||||||
u32 val, tmdsck, freqvco, pllctrl = 0;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (!enable_pll_rejection(hdmi))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("ckpxpll = %dHz\n", ckpxpll);
|
|
||||||
|
|
||||||
/* Assuming no pixel repetition and 24bits color */
|
|
||||||
tmdsck = ckpxpll;
|
|
||||||
pllctrl = 2 << HDMI_SRZ_PLL_CFG_NDIV_SHIFT;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup the PLL mode parameter based on the ckpxpll. If we haven't got
|
|
||||||
* a clock frequency supported by one of the specific PLL modes then we
|
|
||||||
* will end up using the generic mode (0) which only supports a 10x
|
|
||||||
* multiplier, hence only 24bit color.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < NB_PLL_MODE; i++) {
|
|
||||||
if (ckpxpll >= pllmodes[i].min && ckpxpll <= pllmodes[i].max)
|
|
||||||
pllctrl |= HDMI_SRZ_PLL_CFG_MODE(pllmodes[i].mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
freqvco = tmdsck * 10;
|
|
||||||
if (freqvco <= 425000000UL)
|
|
||||||
pllctrl |= HDMI_SRZ_PLL_CFG_VCOR(HDMI_SRZ_PLL_CFG_VCOR_425MHZ);
|
|
||||||
else if (freqvco <= 850000000UL)
|
|
||||||
pllctrl |= HDMI_SRZ_PLL_CFG_VCOR(HDMI_SRZ_PLL_CFG_VCOR_850MHZ);
|
|
||||||
else if (freqvco <= 1700000000UL)
|
|
||||||
pllctrl |= HDMI_SRZ_PLL_CFG_VCOR(HDMI_SRZ_PLL_CFG_VCOR_1700MHZ);
|
|
||||||
else if (freqvco <= 2970000000UL)
|
|
||||||
pllctrl |= HDMI_SRZ_PLL_CFG_VCOR(HDMI_SRZ_PLL_CFG_VCOR_3000MHZ);
|
|
||||||
else {
|
|
||||||
DRM_ERROR("PHY serializer clock out of range\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Configure and power up the PHY PLL
|
|
||||||
*/
|
|
||||||
hdmi->event_received = false;
|
|
||||||
DRM_DEBUG_DRIVER("pllctrl = 0x%x\n", pllctrl);
|
|
||||||
hdmi_write(hdmi, pllctrl, HDMI_SRZ_PLL_CFG);
|
|
||||||
|
|
||||||
/* wait PLL interrupt */
|
|
||||||
wait_event_interruptible_timeout(hdmi->wait_event,
|
|
||||||
hdmi->event_received == true,
|
|
||||||
msecs_to_jiffies
|
|
||||||
(HDMI_TIMEOUT_PLL_LOCK));
|
|
||||||
|
|
||||||
if ((hdmi_read(hdmi, HDMI_STA) & HDMI_STA_DLL_LCK) == 0) {
|
|
||||||
DRM_ERROR("hdmi phy pll not locked\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("got PHY PLL Lock\n");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* To configure the source termination and pre-emphasis appropriately
|
|
||||||
* for different high speed TMDS clock frequencies a phy configuration
|
|
||||||
* table must be provided, tailored to the SoC and board combination.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < NB_HDMI_PHY_CONFIG; i++) {
|
|
||||||
if ((hdmiphy_config[i].min_tmds_freq <= tmdsck) &&
|
|
||||||
(hdmiphy_config[i].max_tmds_freq >= tmdsck)) {
|
|
||||||
val = hdmiphy_config[i].config[0];
|
|
||||||
hdmi_write(hdmi, val, HDMI_SRZ_TAP_1);
|
|
||||||
val = hdmiphy_config[i].config[1];
|
|
||||||
hdmi_write(hdmi, val, HDMI_SRZ_TAP_2);
|
|
||||||
val = hdmiphy_config[i].config[2];
|
|
||||||
hdmi_write(hdmi, val, HDMI_SRZ_TAP_3);
|
|
||||||
val = hdmiphy_config[i].config[3];
|
|
||||||
val |= HDMI_SRZ_CTRL_EXTERNAL_DATA_EN;
|
|
||||||
val &= ~HDMI_SRZ_CTRL_POWER_DOWN;
|
|
||||||
hdmi_write(hdmi, val, HDMI_SRZ_CTRL);
|
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("serializer cfg 0x%x 0x%x 0x%x 0x%x\n",
|
|
||||||
hdmiphy_config[i].config[0],
|
|
||||||
hdmiphy_config[i].config[1],
|
|
||||||
hdmiphy_config[i].config[2],
|
|
||||||
hdmiphy_config[i].config[3]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Default, power up the serializer with no pre-emphasis or source
|
|
||||||
* termination.
|
|
||||||
*/
|
|
||||||
hdmi_write(hdmi, 0x0, HDMI_SRZ_TAP_1);
|
|
||||||
hdmi_write(hdmi, 0x0, HDMI_SRZ_TAP_2);
|
|
||||||
hdmi_write(hdmi, 0x0, HDMI_SRZ_TAP_3);
|
|
||||||
hdmi_write(hdmi, HDMI_SRZ_CTRL_EXTERNAL_DATA_EN, HDMI_SRZ_CTRL);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
err:
|
|
||||||
disable_pll_rejection(hdmi);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop hdmi phy macro cell tx3g0c55
|
|
||||||
*
|
|
||||||
* @hdmi: pointer on the hdmi internal structure
|
|
||||||
*/
|
|
||||||
static void sti_hdmi_tx3g0c55phy_stop(struct sti_hdmi *hdmi)
|
|
||||||
{
|
|
||||||
DRM_DEBUG_DRIVER("\n");
|
|
||||||
|
|
||||||
hdmi->event_received = false;
|
|
||||||
|
|
||||||
hdmi_write(hdmi, HDMI_SRZ_CTRL_POWER_DOWN, HDMI_SRZ_CTRL);
|
|
||||||
hdmi_write(hdmi, HDMI_SRZ_PLL_CFG_POWER_DOWN, HDMI_SRZ_PLL_CFG);
|
|
||||||
|
|
||||||
/* wait PLL interrupt */
|
|
||||||
wait_event_interruptible_timeout(hdmi->wait_event,
|
|
||||||
hdmi->event_received == true,
|
|
||||||
msecs_to_jiffies
|
|
||||||
(HDMI_TIMEOUT_PLL_LOCK));
|
|
||||||
|
|
||||||
if (hdmi_read(hdmi, HDMI_STA) & HDMI_STA_DLL_LCK)
|
|
||||||
DRM_ERROR("hdmi phy pll not well disabled\n");
|
|
||||||
|
|
||||||
disable_pll_rejection(hdmi);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct hdmi_phy_ops tx3g0c55phy_ops = {
|
|
||||||
.start = sti_hdmi_tx3g0c55phy_start,
|
|
||||||
.stop = sti_hdmi_tx3g0c55phy_stop,
|
|
||||||
};
|
|
|
@ -1,14 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) STMicroelectronics SA 2014
|
|
||||||
* Author: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics.
|
|
||||||
* License terms: GNU General Public License (GPL), version 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _STI_HDMI_TX3G0C55PHY_H_
|
|
||||||
#define _STI_HDMI_TX3G0C55PHY_H_
|
|
||||||
|
|
||||||
#include "sti_hdmi.h"
|
|
||||||
|
|
||||||
extern struct hdmi_phy_ops tx3g0c55phy_ops;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "sti_hqvdp_lut.h"
|
#include "sti_hqvdp_lut.h"
|
||||||
#include "sti_plane.h"
|
#include "sti_plane.h"
|
||||||
#include "sti_vtg.h"
|
#include "sti_vtg.h"
|
||||||
|
#include "sti_drv.h"
|
||||||
|
|
||||||
/* Firmware name */
|
/* Firmware name */
|
||||||
#define HQVDP_FMW_NAME "hqvdp-stih407.bin"
|
#define HQVDP_FMW_NAME "hqvdp-stih407.bin"
|
||||||
|
@ -770,6 +771,7 @@ static void sti_hqvdp_disable(struct sti_hqvdp *hqvdp)
|
||||||
DRM_ERROR("XP70 could not revert to idle\n");
|
DRM_ERROR("XP70 could not revert to idle\n");
|
||||||
|
|
||||||
hqvdp->plane.status = STI_PLANE_DISABLED;
|
hqvdp->plane.status = STI_PLANE_DISABLED;
|
||||||
|
hqvdp->xp70_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -783,7 +785,7 @@ static void sti_hqvdp_disable(struct sti_hqvdp *hqvdp)
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* 0 on success.
|
* 0 on success.
|
||||||
*/
|
*/
|
||||||
int sti_hqvdp_vtg_cb(struct notifier_block *nb, unsigned long evt, void *data)
|
static int sti_hqvdp_vtg_cb(struct notifier_block *nb, unsigned long evt, void *data)
|
||||||
{
|
{
|
||||||
struct sti_hqvdp *hqvdp = container_of(nb, struct sti_hqvdp, vtg_nb);
|
struct sti_hqvdp *hqvdp = container_of(nb, struct sti_hqvdp, vtg_nb);
|
||||||
int btm_cmd_offset, top_cmd_offest;
|
int btm_cmd_offset, top_cmd_offest;
|
||||||
|
@ -1012,7 +1014,6 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane,
|
||||||
struct sti_hqvdp *hqvdp = to_sti_hqvdp(plane);
|
struct sti_hqvdp *hqvdp = to_sti_hqvdp(plane);
|
||||||
struct drm_crtc *crtc = state->crtc;
|
struct drm_crtc *crtc = state->crtc;
|
||||||
struct drm_framebuffer *fb = state->fb;
|
struct drm_framebuffer *fb = state->fb;
|
||||||
bool first_prepare = plane->status == STI_PLANE_DISABLED ? true : false;
|
|
||||||
struct drm_crtc_state *crtc_state;
|
struct drm_crtc_state *crtc_state;
|
||||||
struct drm_display_mode *mode;
|
struct drm_display_mode *mode;
|
||||||
int dst_x, dst_y, dst_w, dst_h;
|
int dst_x, dst_y, dst_w, dst_h;
|
||||||
|
@ -1026,8 +1027,8 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane,
|
||||||
mode = &crtc_state->mode;
|
mode = &crtc_state->mode;
|
||||||
dst_x = state->crtc_x;
|
dst_x = state->crtc_x;
|
||||||
dst_y = state->crtc_y;
|
dst_y = state->crtc_y;
|
||||||
dst_w = clamp_val(state->crtc_w, 0, mode->crtc_hdisplay - dst_x);
|
dst_w = clamp_val(state->crtc_w, 0, mode->hdisplay - dst_x);
|
||||||
dst_h = clamp_val(state->crtc_h, 0, mode->crtc_vdisplay - dst_y);
|
dst_h = clamp_val(state->crtc_h, 0, mode->vdisplay - dst_y);
|
||||||
/* src_x are in 16.16 format */
|
/* src_x are in 16.16 format */
|
||||||
src_x = state->src_x >> 16;
|
src_x = state->src_x >> 16;
|
||||||
src_y = state->src_y >> 16;
|
src_y = state->src_y >> 16;
|
||||||
|
@ -1063,7 +1064,7 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_prepare) {
|
if (!hqvdp->xp70_initialized) {
|
||||||
/* Start HQVDP XP70 coprocessor */
|
/* Start HQVDP XP70 coprocessor */
|
||||||
sti_hqvdp_start_xp70(hqvdp);
|
sti_hqvdp_start_xp70(hqvdp);
|
||||||
|
|
||||||
|
@ -1115,8 +1116,8 @@ static void sti_hqvdp_atomic_update(struct drm_plane *drm_plane,
|
||||||
mode = &crtc->mode;
|
mode = &crtc->mode;
|
||||||
dst_x = state->crtc_x;
|
dst_x = state->crtc_x;
|
||||||
dst_y = state->crtc_y;
|
dst_y = state->crtc_y;
|
||||||
dst_w = clamp_val(state->crtc_w, 0, mode->crtc_hdisplay - dst_x);
|
dst_w = clamp_val(state->crtc_w, 0, mode->hdisplay - dst_x);
|
||||||
dst_h = clamp_val(state->crtc_h, 0, mode->crtc_vdisplay - dst_y);
|
dst_h = clamp_val(state->crtc_h, 0, mode->vdisplay - dst_y);
|
||||||
/* src_x are in 16.16 format */
|
/* src_x are in 16.16 format */
|
||||||
src_x = state->src_x >> 16;
|
src_x = state->src_x >> 16;
|
||||||
src_y = state->src_y >> 16;
|
src_y = state->src_y >> 16;
|
||||||
|
@ -1214,15 +1215,15 @@ static void sti_hqvdp_atomic_disable(struct drm_plane *drm_plane,
|
||||||
{
|
{
|
||||||
struct sti_plane *plane = to_sti_plane(drm_plane);
|
struct sti_plane *plane = to_sti_plane(drm_plane);
|
||||||
|
|
||||||
if (!drm_plane->crtc) {
|
if (!oldstate->crtc) {
|
||||||
DRM_DEBUG_DRIVER("drm plane:%d not enabled\n",
|
DRM_DEBUG_DRIVER("drm plane:%d not enabled\n",
|
||||||
drm_plane->base.id);
|
drm_plane->base.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("CRTC:%d (%s) drm plane:%d (%s)\n",
|
DRM_DEBUG_DRIVER("CRTC:%d (%s) drm plane:%d (%s)\n",
|
||||||
drm_plane->crtc->base.id,
|
oldstate->crtc->base.id,
|
||||||
sti_mixer_to_str(to_sti_mixer(drm_plane->crtc)),
|
sti_mixer_to_str(to_sti_mixer(oldstate->crtc)),
|
||||||
drm_plane->base.id, sti_plane_to_str(plane));
|
drm_plane->base.id, sti_plane_to_str(plane));
|
||||||
|
|
||||||
plane->status = STI_PLANE_DISABLING;
|
plane->status = STI_PLANE_DISABLING;
|
||||||
|
@ -1250,7 +1251,7 @@ static int sti_hqvdp_late_register(struct drm_plane *drm_plane)
|
||||||
return hqvdp_debugfs_init(hqvdp, drm_plane->dev->primary);
|
return hqvdp_debugfs_init(hqvdp, drm_plane->dev->primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = {
|
static const struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = {
|
||||||
.update_plane = drm_atomic_helper_update_plane,
|
.update_plane = drm_atomic_helper_update_plane,
|
||||||
.disable_plane = drm_atomic_helper_disable_plane,
|
.disable_plane = drm_atomic_helper_disable_plane,
|
||||||
.destroy = sti_hqvdp_destroy,
|
.destroy = sti_hqvdp_destroy,
|
||||||
|
@ -1289,7 +1290,7 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev,
|
||||||
return &hqvdp->plane.drm_plane;
|
return &hqvdp->plane.drm_plane;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sti_hqvdp_bind(struct device *dev, struct device *master, void *data)
|
static int sti_hqvdp_bind(struct device *dev, struct device *master, void *data)
|
||||||
{
|
{
|
||||||
struct sti_hqvdp *hqvdp = dev_get_drvdata(dev);
|
struct sti_hqvdp *hqvdp = dev_get_drvdata(dev);
|
||||||
struct drm_device *drm_dev = data;
|
struct drm_device *drm_dev = data;
|
||||||
|
|
|
@ -16,12 +16,6 @@ static unsigned int bkg_color = 0x000000;
|
||||||
MODULE_PARM_DESC(bkgcolor, "Value of the background color 0xRRGGBB");
|
MODULE_PARM_DESC(bkgcolor, "Value of the background color 0xRRGGBB");
|
||||||
module_param_named(bkgcolor, bkg_color, int, 0644);
|
module_param_named(bkgcolor, bkg_color, int, 0644);
|
||||||
|
|
||||||
/* Identity: G=Y , B=Cb , R=Cr */
|
|
||||||
static const u32 mixerColorSpaceMatIdentity[] = {
|
|
||||||
0x10000000, 0x00000000, 0x10000000, 0x00001000,
|
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
/* regs offset */
|
/* regs offset */
|
||||||
#define GAM_MIXER_CTL 0x00
|
#define GAM_MIXER_CTL 0x00
|
||||||
#define GAM_MIXER_BKC 0x04
|
#define GAM_MIXER_BKC 0x04
|
||||||
|
@ -358,22 +352,12 @@ int sti_mixer_set_plane_status(struct sti_mixer *mixer,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sti_mixer_set_matrix(struct sti_mixer *mixer)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(mixerColorSpaceMatIdentity); i++)
|
|
||||||
sti_mixer_reg_write(mixer, GAM_MIXER_MX0 + (i * 4),
|
|
||||||
mixerColorSpaceMatIdentity[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sti_mixer *sti_mixer_create(struct device *dev,
|
struct sti_mixer *sti_mixer_create(struct device *dev,
|
||||||
struct drm_device *drm_dev,
|
struct drm_device *drm_dev,
|
||||||
int id,
|
int id,
|
||||||
void __iomem *baseaddr)
|
void __iomem *baseaddr)
|
||||||
{
|
{
|
||||||
struct sti_mixer *mixer = devm_kzalloc(dev, sizeof(*mixer), GFP_KERNEL);
|
struct sti_mixer *mixer = devm_kzalloc(dev, sizeof(*mixer), GFP_KERNEL);
|
||||||
struct device_node *np = dev->of_node;
|
|
||||||
|
|
||||||
dev_dbg(dev, "%s\n", __func__);
|
dev_dbg(dev, "%s\n", __func__);
|
||||||
if (!mixer) {
|
if (!mixer) {
|
||||||
|
@ -384,9 +368,6 @@ struct sti_mixer *sti_mixer_create(struct device *dev,
|
||||||
mixer->dev = dev;
|
mixer->dev = dev;
|
||||||
mixer->id = id;
|
mixer->id = id;
|
||||||
|
|
||||||
if (of_device_is_compatible(np, "st,stih416-compositor"))
|
|
||||||
sti_mixer_set_matrix(mixer);
|
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("%s created. Regs=%p\n",
|
DRM_DEBUG_DRIVER("%s created. Regs=%p\n",
|
||||||
sti_mixer_to_str(mixer), mixer->regs);
|
sti_mixer_to_str(mixer), mixer->regs);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <drm/drm_crtc_helper.h>
|
#include <drm/drm_crtc_helper.h>
|
||||||
|
|
||||||
#include "sti_crtc.h"
|
#include "sti_crtc.h"
|
||||||
|
#include "sti_drv.h"
|
||||||
#include "sti_vtg.h"
|
#include "sti_vtg.h"
|
||||||
|
|
||||||
/* glue registers */
|
/* glue registers */
|
||||||
|
@ -209,13 +210,11 @@ static void tvout_vip_set_rnd(struct sti_tvout *tvout, int reg, u32 rnd)
|
||||||
* @tvout: tvout structure
|
* @tvout: tvout structure
|
||||||
* @reg: register to set
|
* @reg: register to set
|
||||||
* @main_path: main or auxiliary path
|
* @main_path: main or auxiliary path
|
||||||
* @sel_input_logic_inverted: need to invert the logic
|
|
||||||
* @sel_input: selected_input (main/aux + conv)
|
* @sel_input: selected_input (main/aux + conv)
|
||||||
*/
|
*/
|
||||||
static void tvout_vip_set_sel_input(struct sti_tvout *tvout,
|
static void tvout_vip_set_sel_input(struct sti_tvout *tvout,
|
||||||
int reg,
|
int reg,
|
||||||
bool main_path,
|
bool main_path,
|
||||||
bool sel_input_logic_inverted,
|
|
||||||
enum sti_tvout_video_out_type video_out)
|
enum sti_tvout_video_out_type video_out)
|
||||||
{
|
{
|
||||||
u32 sel_input;
|
u32 sel_input;
|
||||||
|
@ -236,8 +235,7 @@ static void tvout_vip_set_sel_input(struct sti_tvout *tvout,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* on stih407 chip the sel_input bypass mode logic is inverted */
|
/* on stih407 chip the sel_input bypass mode logic is inverted */
|
||||||
if (sel_input_logic_inverted)
|
sel_input = sel_input ^ TVO_VIP_SEL_INPUT_BYPASS_MASK;
|
||||||
sel_input = sel_input ^ TVO_VIP_SEL_INPUT_BYPASS_MASK;
|
|
||||||
|
|
||||||
val &= ~TVO_VIP_SEL_INPUT_MASK;
|
val &= ~TVO_VIP_SEL_INPUT_MASK;
|
||||||
val |= sel_input;
|
val |= sel_input;
|
||||||
|
@ -295,8 +293,6 @@ static void tvout_preformatter_set_matrix(struct sti_tvout *tvout,
|
||||||
*/
|
*/
|
||||||
static void tvout_dvo_start(struct sti_tvout *tvout, bool main_path)
|
static void tvout_dvo_start(struct sti_tvout *tvout, bool main_path)
|
||||||
{
|
{
|
||||||
struct device_node *node = tvout->dev->of_node;
|
|
||||||
bool sel_input_logic_inverted = false;
|
|
||||||
u32 tvo_in_vid_format;
|
u32 tvo_in_vid_format;
|
||||||
int val, tmp;
|
int val, tmp;
|
||||||
|
|
||||||
|
@ -334,16 +330,11 @@ static void tvout_dvo_start(struct sti_tvout *tvout, bool main_path)
|
||||||
/* Set round mode (rounded to 8-bit per component) */
|
/* Set round mode (rounded to 8-bit per component) */
|
||||||
tvout_vip_set_rnd(tvout, TVO_VIP_DVO, TVO_VIP_RND_8BIT_ROUNDED);
|
tvout_vip_set_rnd(tvout, TVO_VIP_DVO, TVO_VIP_RND_8BIT_ROUNDED);
|
||||||
|
|
||||||
if (of_device_is_compatible(node, "st,stih407-tvout")) {
|
/* Set input video format */
|
||||||
/* Set input video format */
|
tvout_vip_set_in_vid_fmt(tvout, tvo_in_vid_format, TVO_IN_FMT_SIGNED);
|
||||||
tvout_vip_set_in_vid_fmt(tvout, tvo_in_vid_format,
|
|
||||||
TVO_IN_FMT_SIGNED);
|
|
||||||
sel_input_logic_inverted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Input selection */
|
/* Input selection */
|
||||||
tvout_vip_set_sel_input(tvout, TVO_VIP_DVO, main_path,
|
tvout_vip_set_sel_input(tvout, TVO_VIP_DVO, main_path,
|
||||||
sel_input_logic_inverted,
|
|
||||||
STI_TVOUT_VIDEO_OUT_RGB);
|
STI_TVOUT_VIDEO_OUT_RGB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,8 +347,6 @@ static void tvout_dvo_start(struct sti_tvout *tvout, bool main_path)
|
||||||
*/
|
*/
|
||||||
static void tvout_hdmi_start(struct sti_tvout *tvout, bool main_path)
|
static void tvout_hdmi_start(struct sti_tvout *tvout, bool main_path)
|
||||||
{
|
{
|
||||||
struct device_node *node = tvout->dev->of_node;
|
|
||||||
bool sel_input_logic_inverted = false;
|
|
||||||
u32 tvo_in_vid_format;
|
u32 tvo_in_vid_format;
|
||||||
|
|
||||||
dev_dbg(tvout->dev, "%s\n", __func__);
|
dev_dbg(tvout->dev, "%s\n", __func__);
|
||||||
|
@ -390,16 +379,12 @@ static void tvout_hdmi_start(struct sti_tvout *tvout, bool main_path)
|
||||||
/* set round mode (rounded to 8-bit per component) */
|
/* set round mode (rounded to 8-bit per component) */
|
||||||
tvout_vip_set_rnd(tvout, TVO_VIP_HDMI, TVO_VIP_RND_8BIT_ROUNDED);
|
tvout_vip_set_rnd(tvout, TVO_VIP_HDMI, TVO_VIP_RND_8BIT_ROUNDED);
|
||||||
|
|
||||||
if (of_device_is_compatible(node, "st,stih407-tvout")) {
|
/* set input video format */
|
||||||
/* set input video format */
|
tvout_vip_set_in_vid_fmt(tvout, tvo_in_vid_format, TVO_IN_FMT_SIGNED);
|
||||||
tvout_vip_set_in_vid_fmt(tvout, tvo_in_vid_format,
|
|
||||||
TVO_IN_FMT_SIGNED);
|
|
||||||
sel_input_logic_inverted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* input selection */
|
/* input selection */
|
||||||
tvout_vip_set_sel_input(tvout, TVO_VIP_HDMI, main_path,
|
tvout_vip_set_sel_input(tvout, TVO_VIP_HDMI, main_path,
|
||||||
sel_input_logic_inverted, STI_TVOUT_VIDEO_OUT_RGB);
|
STI_TVOUT_VIDEO_OUT_RGB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -411,8 +396,6 @@ static void tvout_hdmi_start(struct sti_tvout *tvout, bool main_path)
|
||||||
*/
|
*/
|
||||||
static void tvout_hda_start(struct sti_tvout *tvout, bool main_path)
|
static void tvout_hda_start(struct sti_tvout *tvout, bool main_path)
|
||||||
{
|
{
|
||||||
struct device_node *node = tvout->dev->of_node;
|
|
||||||
bool sel_input_logic_inverted = false;
|
|
||||||
u32 tvo_in_vid_format;
|
u32 tvo_in_vid_format;
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
|
@ -448,16 +431,11 @@ static void tvout_hda_start(struct sti_tvout *tvout, bool main_path)
|
||||||
/* set round mode (rounded to 10-bit per component) */
|
/* set round mode (rounded to 10-bit per component) */
|
||||||
tvout_vip_set_rnd(tvout, TVO_VIP_HDF, TVO_VIP_RND_10BIT_ROUNDED);
|
tvout_vip_set_rnd(tvout, TVO_VIP_HDF, TVO_VIP_RND_10BIT_ROUNDED);
|
||||||
|
|
||||||
if (of_device_is_compatible(node, "st,stih407-tvout")) {
|
/* Set input video format */
|
||||||
/* set input video format */
|
tvout_vip_set_in_vid_fmt(tvout, tvo_in_vid_format, TVO_IN_FMT_SIGNED);
|
||||||
tvout_vip_set_in_vid_fmt(tvout,
|
|
||||||
tvo_in_vid_format, TVO_IN_FMT_SIGNED);
|
|
||||||
sel_input_logic_inverted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Input selection */
|
/* Input selection */
|
||||||
tvout_vip_set_sel_input(tvout, TVO_VIP_HDF, main_path,
|
tvout_vip_set_sel_input(tvout, TVO_VIP_HDF, main_path,
|
||||||
sel_input_logic_inverted,
|
|
||||||
STI_TVOUT_VIDEO_OUT_YUV);
|
STI_TVOUT_VIDEO_OUT_YUV);
|
||||||
|
|
||||||
/* power up HD DAC */
|
/* power up HD DAC */
|
||||||
|
@ -905,7 +883,6 @@ static int sti_tvout_remove(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id tvout_of_match[] = {
|
static const struct of_device_id tvout_of_match[] = {
|
||||||
{ .compatible = "st,stih416-tvout", },
|
|
||||||
{ .compatible = "st,stih407-tvout", },
|
{ .compatible = "st,stih407-tvout", },
|
||||||
{ /* end node */ }
|
{ /* end node */ }
|
||||||
};
|
};
|
||||||
|
|
|
@ -142,8 +142,8 @@ void sti_vid_commit(struct sti_vid *vid,
|
||||||
struct drm_display_mode *mode = &crtc->mode;
|
struct drm_display_mode *mode = &crtc->mode;
|
||||||
int dst_x = state->crtc_x;
|
int dst_x = state->crtc_x;
|
||||||
int dst_y = state->crtc_y;
|
int dst_y = state->crtc_y;
|
||||||
int dst_w = clamp_val(state->crtc_w, 0, mode->crtc_hdisplay - dst_x);
|
int dst_w = clamp_val(state->crtc_w, 0, mode->hdisplay - dst_x);
|
||||||
int dst_h = clamp_val(state->crtc_h, 0, mode->crtc_vdisplay - dst_y);
|
int dst_h = clamp_val(state->crtc_h, 0, mode->vdisplay - dst_y);
|
||||||
int src_h = state->src_h >> 16;
|
int src_h = state->src_h >> 16;
|
||||||
u32 val, ydo, xdo, yds, xds;
|
u32 val, ydo, xdo, yds, xds;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
#include <drm/drmP.h>
|
#include <drm/drmP.h>
|
||||||
|
|
||||||
|
#include "sti_drv.h"
|
||||||
|
|
||||||
/* registers offset */
|
/* registers offset */
|
||||||
#define VTAC_CONFIG 0x00
|
#define VTAC_CONFIG 0x00
|
||||||
#define VTAC_RX_FIFO_CONFIG 0x04
|
#define VTAC_RX_FIFO_CONFIG 0x04
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <drm/drmP.h>
|
#include <drm/drmP.h>
|
||||||
|
|
||||||
|
#include "sti_drv.h"
|
||||||
#include "sti_vtg.h"
|
#include "sti_vtg.h"
|
||||||
|
|
||||||
#define VTG_MODE_MASTER 0
|
#define VTG_MODE_MASTER 0
|
||||||
|
@ -72,7 +73,7 @@
|
||||||
#define AWG_DELAY_ED (-8)
|
#define AWG_DELAY_ED (-8)
|
||||||
#define AWG_DELAY_SD (-7)
|
#define AWG_DELAY_SD (-7)
|
||||||
|
|
||||||
LIST_HEAD(vtg_lookup);
|
static LIST_HEAD(vtg_lookup);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* STI VTG register offset structure
|
* STI VTG register offset structure
|
||||||
|
|
Loading…
Reference in a new issue