mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
drm/rockchip/rk628: Add scaler functions.
Signed-off-by: Shunqing Chen <csq@rock-chips.com> Change-Id: Ia08c718e0a0967f69922f5a6ca11aacddcb09e2b
This commit is contained in:
@@ -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
24
include/linux/mfd/rk628.h
Normal file → Executable 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
|
||||
|
||||
Reference in New Issue
Block a user