forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drm/rockchip: Add support for Rockchip Soc RGB output interface
Some Rockchip CRTCs, like rv1108 and px30, can directly output parallel and serial RGB data to panel or conversion chip. So add a feature-bit for vops to mark the ability for these direct outputs and add an internal encoder in that case, that can attach to bridge chipsor panels. Changes in v7: 1. forget to delete rockchip_rgb_driver and delete it. Changes in v6: 1. Update according to Heiko Stuebner' implemention, rgb output is part of vop's feature, should not register as a independent driver. Changes in v5: 1. add SPDX-License-Identifier tag Changes in v4: 1. add support px30; Changes in v3: 1. update for rgb-mode move to panel node. Changes in v2: 1. add error log when probe failed; 2. update name_to_output_mode() according to sean's suggest; 3. Fix uninitialized use of ret. Signed-off-by: Sandy Huang <[email protected]> Reviewed-by: Sean Paul <[email protected]> Signed-off-by: Heiko Stuebner <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
- Loading branch information
1 parent
3880f62
commit 1f0f015
Showing
6 changed files
with
222 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
//SPDX-License-Identifier: GPL-2.0+ | ||
/* | ||
* Copyright (C) Fuzhou Rockchip Electronics Co.Ltd | ||
* Author: | ||
* Sandy Huang <[email protected]> | ||
* | ||
* This software is licensed under the terms of the GNU General Public | ||
* License version 2, as published by the Free Software Foundation, and | ||
* may be copied, distributed, and modified under those terms. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
#include <drm/drmP.h> | ||
#include <drm/drm_atomic_helper.h> | ||
#include <drm/drm_crtc_helper.h> | ||
#include <drm/drm_dp_helper.h> | ||
#include <drm/drm_panel.h> | ||
#include <drm/drm_of.h> | ||
|
||
#include <linux/component.h> | ||
#include <linux/of_graph.h> | ||
|
||
#include "rockchip_drm_drv.h" | ||
#include "rockchip_drm_vop.h" | ||
|
||
#define encoder_to_rgb(c) container_of(c, struct rockchip_rgb, encoder) | ||
|
||
struct rockchip_rgb { | ||
struct device *dev; | ||
struct drm_device *drm_dev; | ||
struct drm_bridge *bridge; | ||
struct drm_encoder encoder; | ||
int output_mode; | ||
}; | ||
|
||
static int | ||
rockchip_rgb_encoder_atomic_check(struct drm_encoder *encoder, | ||
struct drm_crtc_state *crtc_state, | ||
struct drm_connector_state *conn_state) | ||
{ | ||
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); | ||
struct drm_connector *connector = conn_state->connector; | ||
struct drm_display_info *info = &connector->display_info; | ||
u32 bus_format; | ||
|
||
if (info->num_bus_formats) | ||
bus_format = info->bus_formats[0]; | ||
else | ||
bus_format = MEDIA_BUS_FMT_RGB888_1X24; | ||
|
||
switch (bus_format) { | ||
case MEDIA_BUS_FMT_RGB666_1X18: | ||
s->output_mode = ROCKCHIP_OUT_MODE_P666; | ||
break; | ||
case MEDIA_BUS_FMT_RGB565_1X16: | ||
s->output_mode = ROCKCHIP_OUT_MODE_P565; | ||
break; | ||
case MEDIA_BUS_FMT_RGB888_1X24: | ||
case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: | ||
default: | ||
s->output_mode = ROCKCHIP_OUT_MODE_P888; | ||
break; | ||
} | ||
|
||
s->output_type = DRM_MODE_CONNECTOR_LVDS; | ||
|
||
return 0; | ||
} | ||
|
||
static const | ||
struct drm_encoder_helper_funcs rockchip_rgb_encoder_helper_funcs = { | ||
.atomic_check = rockchip_rgb_encoder_atomic_check, | ||
}; | ||
|
||
static const struct drm_encoder_funcs rockchip_rgb_encoder_funcs = { | ||
.destroy = drm_encoder_cleanup, | ||
}; | ||
|
||
struct rockchip_rgb *rockchip_rgb_init(struct device *dev, | ||
struct drm_crtc *crtc, | ||
struct drm_device *drm_dev) | ||
{ | ||
struct rockchip_rgb *rgb; | ||
struct drm_encoder *encoder; | ||
struct device_node *port, *endpoint; | ||
u32 endpoint_id; | ||
int ret = 0, child_count = 0; | ||
struct drm_panel *panel; | ||
struct drm_bridge *bridge; | ||
|
||
rgb = devm_kzalloc(dev, sizeof(*rgb), GFP_KERNEL); | ||
if (!rgb) | ||
return ERR_PTR(-ENOMEM); | ||
|
||
rgb->dev = dev; | ||
rgb->drm_dev = drm_dev; | ||
|
||
port = of_graph_get_port_by_id(dev->of_node, 0); | ||
if (!port) | ||
return ERR_PTR(-EINVAL); | ||
|
||
for_each_child_of_node(port, endpoint) { | ||
if (of_property_read_u32(endpoint, "reg", &endpoint_id)) | ||
endpoint_id = 0; | ||
|
||
if (rockchip_drm_endpoint_is_subdriver(endpoint) > 0) | ||
continue; | ||
|
||
child_count++; | ||
ret = drm_of_find_panel_or_bridge(dev->of_node, 0, endpoint_id, | ||
&panel, &bridge); | ||
if (!ret) | ||
break; | ||
} | ||
|
||
of_node_put(port); | ||
|
||
/* if the rgb output is not connected to anything, just return */ | ||
if (!child_count) | ||
return NULL; | ||
|
||
if (ret < 0) { | ||
if (ret != -EPROBE_DEFER) | ||
DRM_DEV_ERROR(dev, "failed to find panel or bridge %d\n", ret); | ||
return ERR_PTR(ret); | ||
} | ||
|
||
encoder = &rgb->encoder; | ||
encoder->possible_crtcs = drm_crtc_mask(crtc); | ||
|
||
ret = drm_encoder_init(drm_dev, encoder, &rockchip_rgb_encoder_funcs, | ||
DRM_MODE_ENCODER_NONE, NULL); | ||
if (ret < 0) { | ||
DRM_DEV_ERROR(drm_dev->dev, | ||
"failed to initialize encoder: %d\n", ret); | ||
return ERR_PTR(ret); | ||
} | ||
|
||
drm_encoder_helper_add(encoder, &rockchip_rgb_encoder_helper_funcs); | ||
|
||
if (panel) { | ||
bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_LVDS); | ||
if (IS_ERR(bridge)) | ||
return ERR_CAST(bridge); | ||
} | ||
|
||
rgb->bridge = bridge; | ||
|
||
ret = drm_bridge_attach(encoder, rgb->bridge, NULL); | ||
if (ret) { | ||
DRM_DEV_ERROR(drm_dev->dev, | ||
"failed to attach bridge: %d\n", ret); | ||
goto err_free_encoder; | ||
} | ||
|
||
return rgb; | ||
|
||
err_free_encoder: | ||
drm_encoder_cleanup(encoder); | ||
return ERR_PTR(ret); | ||
} | ||
EXPORT_SYMBOL_GPL(rockchip_rgb_init); | ||
|
||
void rockchip_rgb_fini(struct rockchip_rgb *rgb) | ||
{ | ||
drm_panel_bridge_remove(rgb->bridge); | ||
drm_encoder_cleanup(&rgb->encoder); | ||
} | ||
EXPORT_SYMBOL_GPL(rockchip_rgb_fini); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
//SPDX-License-Identifier: GPL-2.0+ | ||
/* | ||
* Copyright (C) Fuzhou Rockchip Electronics Co.Ltd | ||
* Author: | ||
* Sandy Huang <[email protected]> | ||
* | ||
* This software is licensed under the terms of the GNU General Public | ||
* License version 2, as published by the Free Software Foundation, and | ||
* may be copied, distributed, and modified under those terms. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
struct rockchip_rgb *rockchip_rgb_init(struct device *dev, | ||
struct drm_crtc *crtc, | ||
struct drm_device *drm_dev); | ||
void rockchip_rgb_fini(struct rockchip_rgb *rgb); |