Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RetrOLED CM5: Fix PWM fan frequency and display rotation #274

Merged
merged 2 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions arch/arm64/boot/dts/rockchip/rk3588s-retroled-cm5.dts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
compatible = "pwm-fan";
#cooling-cells = <2>;
cooling-levels = <15 55 95 135 175 215 255>;
pwms = <&pwm11 0 10000 0>;
pwms = <&pwm11 0 40000 0>;
};

wm8960_mclk: wm8960-mclk {
Expand Down Expand Up @@ -484,8 +484,8 @@
* 1: non-burst mode with sync event
* 2: non-burst mode with sync pulse
*/
panel-width-mm = <68>;
panel-height-mm = <121>;
width-mm = <68>;
height-mm = <121>;

disp_timings0: display-timings {
native-mode = <&dsi1_timing0>;
Expand Down
125 changes: 125 additions & 0 deletions drivers/gpu/drm/panel/panel-raydium-rm67191.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
#include <linux/of_platform.h>
#include <linux/regulator/consumer.h>

#include <video/display_timing.h>
#include <video/mipi_display.h>
#include <video/of_display_timing.h>
#include <video/of_videomode.h>
#include <video/videomode.h>

Expand Down Expand Up @@ -123,6 +125,23 @@ static const u32 rad_bus_formats[] = {
static const u32 rad_bus_flags = DRM_BUS_FLAG_DE_LOW |
DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE;

struct panel_desc {
/** @modes: Pointer to array of fixed modes appropriate for this panel. */
const struct drm_display_mode *modes;

/** @num_modes: Number of elements in modes array. */
unsigned int num_modes;

/** @size: Structure containing the physical size of this panel. */
struct {
/** @size.width: Width (in mm) of the active display area. */
unsigned int width;

/** @size.height: Height (in mm) of the active display area. */
unsigned int height;
} size;
};

struct rad_panel {
struct drm_panel panel;
struct mipi_dsi_device *dsi;
Expand All @@ -137,6 +156,9 @@ struct rad_panel {
bool enabled;

const struct rad_platform_data *pdata;

const struct panel_desc *desc;
enum drm_panel_orientation orientation;
};

struct rad_platform_data {
Expand Down Expand Up @@ -476,10 +498,63 @@ static int rad_panel_disable(struct drm_panel *panel)
return 0;
}

static int rad_panel_get_desc_modes(struct drm_panel *panel,
struct drm_connector *connector)
{
struct drm_display_mode *mode;
struct rad_panel *p = to_rad_panel(panel);
unsigned int i, num = 0;

if (!p->desc)
return 0;

for (i = 0; i < p->desc->num_modes; i++) {
const struct drm_display_mode *m = &p->desc->modes[i];

mode = drm_mode_duplicate(connector->dev, m);
if (!mode) {
dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
m->hdisplay, m->vdisplay,
drm_mode_vrefresh(m));
continue;
}

mode->type |= DRM_MODE_TYPE_DRIVER;

if (p->desc->num_modes == 1)
mode->type |= DRM_MODE_TYPE_PREFERRED;

drm_mode_set_name(mode);

drm_mode_probed_add(connector, mode);
num++;
}

if (num > 0) {
if (p->desc->size.width)
connector->display_info.width_mm = p->desc->size.width;
if (p->desc->size.height)
connector->display_info.height_mm = p->desc->size.height;
connector->display_info.bus_flags = rad_bus_flags;

drm_display_info_set_bus_formats(&connector->display_info,
rad_bus_formats,
ARRAY_SIZE(rad_bus_formats));

drm_connector_set_panel_orientation(connector, p->orientation);
}

return num;
}

static int rad_panel_get_modes(struct drm_panel *panel,
struct drm_connector *connector)
{
struct drm_display_mode *mode;
int num = rad_panel_get_desc_modes(panel, connector);

if (num > 0)
return num;

mode = drm_mode_duplicate(connector->dev, &default_mode);
if (!mode) {
Expand Down Expand Up @@ -521,6 +596,13 @@ static int rad_bl_update_status(struct backlight_device *bl)
return 0;
}

static enum drm_panel_orientation rad_panel_get_orientation(struct drm_panel *panel)
{
struct rad_panel *p = to_rad_panel(panel);

return p->orientation;
}

static const struct backlight_ops rad_bl_ops = {
.update_status = rad_bl_update_status,
};
Expand All @@ -531,6 +613,7 @@ static const struct drm_panel_funcs rad_panel_funcs = {
.enable = rad_panel_enable,
.disable = rad_panel_disable,
.get_modes = rad_panel_get_modes,
.get_orientation = rad_panel_get_orientation,
};

static const char * const rad_supply_names[] = {
Expand Down Expand Up @@ -570,6 +653,17 @@ static const struct of_device_id rad_of_match[] = {
};
MODULE_DEVICE_TABLE(of, rad_of_match);

static bool of_child_node_is_present(const struct device_node *node,
const char *name)
{
struct device_node *child;

child = of_get_child_by_name(node, name);
of_node_put(child);

return !!child;
}

static int rad_panel_probe(struct mipi_dsi_device *dsi)
{
struct device *dev = &dsi->dev;
Expand Down Expand Up @@ -637,6 +731,37 @@ static int rad_panel_probe(struct mipi_dsi_device *dsi)
dev_err(dev, "Failed to get reset gpio (%d)\n", ret);
return ret;
}

ret = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
if (ret) {
dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, ret);
return ret;
}

if (of_child_node_is_present(np, "display-timings")) {
struct drm_display_mode *mode;
struct panel_desc *desc;
u32 bus_flags;

mode = devm_kzalloc(dev, sizeof(*mode), GFP_KERNEL);
if (!mode)
return -ENOMEM;

desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
if (!desc)
return -ENOMEM;

if (!of_get_drm_display_mode(np, mode, &bus_flags,
OF_USE_NATIVE_MODE)) {
desc->modes = mode;
desc->num_modes = 1;
of_property_read_u32(np, "width-mm", &desc->size.width);
of_property_read_u32(np, "height-mm", &desc->size.height);
}

panel->desc = desc;
}

gpiod_set_value_cansleep(panel->reset, 1);

memset(&bl_props, 0, sizeof(bl_props));
Expand Down