diff options
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_vec.c')
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_vec.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index a3782d05cd66..b84fad2a5b23 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -17,12 +17,13 @@ #include <drm/drm_drv.h> #include <drm/drm_edid.h> #include <drm/drm_panel.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/drm_simple_kms_helper.h> #include <linux/clk.h> #include <linux/component.h> -#include <linux/of_graph.h> -#include <linux/of_platform.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include "vc4_drv.h" @@ -219,17 +220,11 @@ struct vc4_vec { writel(val, vec->regs + (offset)); \ } while (0) -static inline struct vc4_vec * -encoder_to_vc4_vec(struct drm_encoder *encoder) -{ - return container_of(encoder, struct vc4_vec, encoder.base); -} +#define encoder_to_vc4_vec(_encoder) \ + container_of_const(_encoder, struct vc4_vec, encoder.base) -static inline struct vc4_vec * -connector_to_vc4_vec(struct drm_connector *connector) -{ - return container_of(connector, struct vc4_vec, connector); -} +#define connector_to_vc4_vec(_connector) \ + container_of_const(_connector, struct vc4_vec, connector) enum vc4_vec_tv_mode_id { VC4_VEC_TV_MODE_NTSC, @@ -240,6 +235,7 @@ enum vc4_vec_tv_mode_id { VC4_VEC_TV_MODE_PAL_60, VC4_VEC_TV_MODE_PAL_N, VC4_VEC_TV_MODE_SECAM, + VC4_VEC_TV_MODE_MONOCHROME, }; struct vc4_vec_tv_mode { @@ -330,6 +326,22 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = { .config1 = VEC_CONFIG1_C_CVBS_CVBS, .custom_freq = 0x29c71c72, }, + { + /* 50Hz mono */ + .mode = DRM_MODE_TV_MODE_MONOCHROME, + .expected_htotal = 864, + .config0 = VEC_CONFIG0_PAL_BDGHI_STD | VEC_CONFIG0_BURDIS | + VEC_CONFIG0_CHRDIS, + .config1 = VEC_CONFIG1_C_CVBS_CVBS, + }, + { + /* 60Hz mono */ + .mode = DRM_MODE_TV_MODE_MONOCHROME, + .expected_htotal = 858, + .config0 = VEC_CONFIG0_PAL_M_STD | VEC_CONFIG0_BURDIS | + VEC_CONFIG0_CHRDIS, + .config1 = VEC_CONFIG1_C_CVBS_CVBS, + }, }; static inline const struct vc4_vec_tv_mode * @@ -357,6 +369,7 @@ static const struct drm_prop_enum_list legacy_tv_mode_names[] = { { VC4_VEC_TV_MODE_PAL_M, "PAL-M", }, { VC4_VEC_TV_MODE_PAL_N, "PAL-N", }, { VC4_VEC_TV_MODE_SECAM, "SECAM", }, + { VC4_VEC_TV_MODE_MONOCHROME, "Mono", }, }; static enum drm_connector_status @@ -412,6 +425,10 @@ vc4_vec_connector_set_property(struct drm_connector *connector, state->tv.mode = DRM_MODE_TV_MODE_SECAM; break; + case VC4_VEC_TV_MODE_MONOCHROME: + state->tv.mode = DRM_MODE_TV_MODE_MONOCHROME; + break; + default: return -EINVAL; } @@ -459,6 +476,10 @@ vc4_vec_connector_get_property(struct drm_connector *connector, *val = VC4_VEC_TV_MODE_SECAM; break; + case DRM_MODE_TV_MODE_MONOCHROME: + *val = VC4_VEC_TV_MODE_MONOCHROME; + break; + default: return -EINVAL; } @@ -509,6 +530,8 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) drm_object_attach_property(&connector->base, prop, VC4_VEC_TV_MODE_NTSC); + drm_connector_attach_tv_margin_properties(connector); + drm_connector_attach_encoder(connector, &vec->encoder.base); return 0; @@ -535,7 +558,7 @@ static void vc4_vec_encoder_disable(struct drm_encoder *encoder, ret = pm_runtime_put(&vec->pdev->dev); if (ret < 0) { - DRM_ERROR("Failed to release power domain: %d\n", ret); + drm_err(drm, "Failed to release power domain: %d\n", ret); goto err_dev_exit; } @@ -569,7 +592,7 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder, ret = pm_runtime_resume_and_get(&vec->pdev->dev); if (ret < 0) { - DRM_ERROR("Failed to retain power domain: %d\n", ret); + drm_err(drm, "Failed to retain power domain: %d\n", ret); goto err_dev_exit; } @@ -582,13 +605,13 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder, */ ret = clk_set_rate(vec->clock, 108000000); if (ret) { - DRM_ERROR("Failed to set clock rate: %d\n", ret); + drm_err(drm, "Failed to set clock rate: %d\n", ret); goto err_put_runtime_pm; } ret = clk_prepare_enable(vec->clock); if (ret) { - DRM_ERROR("Failed to turn on core clock: %d\n", ret); + drm_err(drm, "Failed to turn on core clock: %d\n", ret); goto err_put_runtime_pm; } @@ -760,7 +783,8 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data) BIT(DRM_MODE_TV_MODE_PAL) | BIT(DRM_MODE_TV_MODE_PAL_M) | BIT(DRM_MODE_TV_MODE_PAL_N) | - BIT(DRM_MODE_TV_MODE_SECAM)); + BIT(DRM_MODE_TV_MODE_SECAM) | + BIT(DRM_MODE_TV_MODE_MONOCHROME)); if (ret) return ret; @@ -783,7 +807,7 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data) if (IS_ERR(vec->clock)) { ret = PTR_ERR(vec->clock); if (ret != -EPROBE_DEFER) - DRM_ERROR("Failed to get clock: %d\n", ret); + drm_err(drm, "Failed to get clock: %d\n", ret); return ret; } @@ -818,10 +842,9 @@ static int vc4_vec_dev_probe(struct platform_device *pdev) return component_add(&pdev->dev, &vc4_vec_ops); } -static int vc4_vec_dev_remove(struct platform_device *pdev) +static void vc4_vec_dev_remove(struct platform_device *pdev) { component_del(&pdev->dev, &vc4_vec_ops); - return 0; } struct platform_driver vc4_vec_driver = { |
