drm/rockchip/rk628: Add scaler functions.

Signed-off-by: Shunqing Chen <csq@rock-chips.com>
Change-Id: Ia08c718e0a0967f69922f5a6ca11aacddcb09e2b
This commit is contained in:
Shunqing Chen
2020-09-21 15:55:31 +08:00
committed by Tao Huang
parent 3074bbc054
commit 05b8bba67f
2 changed files with 90 additions and 2 deletions

View File

@@ -30,6 +30,7 @@ struct rk628_post_process {
struct reset_control *rstc_decoder;
struct reset_control *rstc_clk_rx;
struct reset_control *rstc_vop;
struct rk628 *parent;
};
static inline struct rk628_post_process *bridge_to_pp(struct drm_bridge *bridge)
@@ -260,11 +261,12 @@ static void rk628_post_process_bridge_mode_set(struct drm_bridge *bridge,
struct drm_display_mode *adj)
{
struct rk628_post_process *pp = bridge_to_pp(bridge);
struct rk628 *rk628 = pp->parent;
drm_mode_copy(&pp->src_mode, adj);
if (pp->bridge->driver_private)
drm_mode_copy(&pp->dst_mode, pp->bridge->driver_private);
if (rk628->dst_mode_valid)
drm_mode_copy(&pp->dst_mode, &rk628->dst_mode);
else
drm_mode_copy(&pp->dst_mode, &pp->src_mode);
}
@@ -311,11 +313,69 @@ static const struct drm_bridge_funcs rk628_post_process_bridge_funcs = {
.attach = rk628_post_process_bridge_attach,
};
/**
* rk628_scaler_add_src_mode - add source mode for scaler
* @rk628: parent device
* @connector: DRM connector
* If need scale, call the function at last of get_modes.
*/
int rk628_scaler_add_src_mode(struct rk628 *rk628,
struct drm_connector *connector)
{
struct drm_display_mode *pmode;
struct drm_display_mode *dst;
if (!rk628 || !connector)
return 0;
if (drm_mode_validate_driver(connector->dev, &rk628->src_mode) !=
MODE_OK)
return 0;
list_for_each_entry(pmode, &connector->probed_modes, head) {
if (pmode->type & DRM_MODE_TYPE_PREFERRED) {
drm_mode_copy(&rk628->dst_mode, pmode);
drm_mode_copy(pmode, &rk628->src_mode);
pmode->type |= DRM_MODE_TYPE_PREFERRED;
rk628->dst_mode_valid = true;
break;
}
}
if (rk628->dst_mode_valid) {
dst = drm_mode_duplicate(connector->dev, &rk628->dst_mode);
dst->type &= ~DRM_MODE_TYPE_PREFERRED;
drm_mode_probed_add(connector, dst);
return 1;
}
return 0;
}
EXPORT_SYMBOL(rk628_scaler_add_src_mode);
/**
* rk628_mode_copy - rk628 mode copy
* @rk628: parent device
* @dst: dst mode
* @src: src mode
* Call the function at mode_set, replace drm_mode_copy.
*/
void rk628_mode_copy(struct rk628 *rk628, struct drm_display_mode *dst,
struct drm_display_mode *src)
{
if (rk628->dst_mode_valid)
drm_mode_copy(dst, &rk628->dst_mode);
else
drm_mode_copy(dst, src);
}
EXPORT_SYMBOL(rk628_mode_copy);
static int rk628_post_process_probe(struct platform_device *pdev)
{
struct rk628 *rk628 = dev_get_drvdata(pdev->dev.parent);
struct device *dev = &pdev->dev;
struct rk628_post_process *pp;
u32 bus_flags;
int ret;
if (!of_device_is_available(dev->of_node))
@@ -328,6 +388,7 @@ static int rk628_post_process_probe(struct platform_device *pdev)
pp->dev = dev;
pp->grf = rk628->grf;
platform_set_drvdata(pdev, pp);
pp->parent = rk628;
pp->sclk_vop = devm_clk_get(dev, "sclk_vop");
if (IS_ERR(pp->sclk_vop)) {
@@ -368,6 +429,9 @@ static int rk628_post_process_probe(struct platform_device *pdev)
pp->base.of_node = dev->of_node;
drm_bridge_add(&pp->base);
of_get_drm_display_mode(dev->of_node, &rk628->src_mode, &bus_flags,
OF_USE_NATIVE_MODE);
return 0;
}

24
include/linux/mfd/rk628.h Normal file → Executable file
View File

@@ -14,6 +14,8 @@
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <drm/drm_crtc_helper.h>
#define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
#define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16))
@@ -224,6 +226,28 @@ struct rk628 {
struct gpio_desc *reset_gpio;
struct gpio_desc *enable_gpio;
struct rk628_irq_chip_data *irq_data;
struct drm_display_mode src_mode;
struct drm_display_mode dst_mode;
bool dst_mode_valid;
};
/**
* rk628_scaler_add_src_mode - add source mode for scaler
* @rk628: parent device
* @connector: DRM connector
* If need scale, call the function at last of get_modes.
*/
int rk628_scaler_add_src_mode(struct rk628 *rk628,
struct drm_connector *connector);
/**
* rk628_mode_copy - rk628 mode copy
* @rk628: parent device
* @dst: dst mode
* @src: src mode
* Call the function at mode_set, replace drm_mode_copy.
*/
void rk628_mode_copy(struct rk628 *rk628, struct drm_display_mode *dst,
struct drm_display_mode *src);
#endif