Merge commit 'b27c911206af7ad9cec2250922846cb1f3ea40cb'

* commit 'b27c911206af7ad9cec2250922846cb1f3ea40cb':
  arm64: dts: rockchip: rk3576-vehicle-evb: modify maxim lock gpio
  hwspinlock: rockchip: support to set hwlock numbers in dt
  dt-bindings: hwlock: rockchip: add number of hwlocks property
  video: rockchip: rga3: add 'reset' debug node
  arm64: dts: rockchip: update rk3576-ebook-color panel parameter
  drm/rockchip: dsi2: add connector polling connect/disconnect flags
  drm/bridge: attach dsi in probe according to dsi driver
  dt-bindings: phy: Add lvds output voltage for rockchip,px30-dsi-dphy
  phy: rockchip: inno-dsidphy: Add support to change lvds output voltage
  video: rockchip: mpp: rkvenc2: Update address trans table
  arm64: dts: rockchip: rk3576-vehicle-evb: support rkvpss

Change-Id: I0a3c700380d14ff2d487a2db98fa735e7d9fe760
This commit is contained in:
Tao Huang
2024-05-31 19:11:06 +08:00
15 changed files with 253 additions and 41 deletions

View File

@@ -10,6 +10,8 @@ Required properties :
- #hwlock-cells : hwlock users only use the hwlock id to represent a specific
hwlock, so the number of cells should be <1> here.
- rockchip,hwlock-num-locks number of hwlocks provided by this device.
Optional properties :
- rockchip,hwlock-user-id : Set hwlock user id (4 bit, default is 0x01).
@@ -21,6 +23,7 @@ Example of hwlock provider:
compatible = "rockchip,hwspinlock";
reg = <0 0xff040000 0 0x10000>;
#hwlock-cells = <1>;
rockchip,hwlock-num-locks = <64>;
};
Example of hwlock users:

View File

@@ -45,6 +45,18 @@ properties:
items:
- const: apb
inno,lanes:
description: Number of MIPI DSI lanes used
enum: [1, 2, 3, 4]
inno,lvds-vcom:
description: LVDS output common-mode voltage in millivolts
enum: [850, 900, 950, 1000]
inno,lvds-vod:
description: LVDS output differential voltage in millivolts
enum: [250, 300, 350, 400]
required:
- "#phy-cells"
- compatible

View File

@@ -19,7 +19,7 @@
panel,vir_height = <1944>;
panel,sdck = <60000000>;
panel,lsl = <64>;
panel,lbl = <64>;
panel,lbl = <20>;
panel,ldl = <312>;
panel,lel = <22>;
panel,gdck-sta = <1>;

View File

@@ -339,6 +339,18 @@
};
&rkvpss {
status = "okay";
};
&rkvpss_mmu {
status = "okay";
};
&rkvpss_vir0 {
status = "okay";
};
&sdmmc {
status = "disabled";
};

View File

@@ -237,7 +237,7 @@
reg = <0x42>;
pinctrl-names = "default";
pinctrl-0 = <&i2c8_serdes_pins>;
lock-gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_HIGH>;
lock-gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_HIGH>;
sel-mipi;
id-serdes-bridge-split = <0x01>;
status = "okay";
@@ -566,7 +566,7 @@
reg = <0x42>;
pinctrl-names = "default";
pinctrl-0 = <&i2c5_serdes_pins>;
lock-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_HIGH>;
lock-gpios = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
id-serdes-bridge-split = <0x02>;
@@ -1090,7 +1090,7 @@
reg = <0x42>;
pinctrl-names = "default";
pinctrl-0 = <&i2c2_serdes_pins>;
lock-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_HIGH>;
lock-gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
id-serdes-bridge-split = <0x02>;
@@ -1616,19 +1616,23 @@
&pinctrl {
serdes {
/*EDP*/
i2c2_serdes_pins: i2c2-serdes-pins {
rockchip,pins =
<2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
<2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>,/*lock*/
<2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;/*err*/
};
/*DP*/
i2c5_serdes_pins: i2c5-serdes-pins {
rockchip,pins =
<2 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
<2 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>,/*err*/
<2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;/*lock*/
};
/*DSI*/
i2c8_serdes_pins: i2c8-serdes-pins {
rockchip,pins =
<2 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>;
<2 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>,/*err*/
<3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;/*lock*/
};
};
};

View File

@@ -2183,8 +2183,6 @@ static int it6161_bridge_attach(struct drm_bridge *bridge,
goto cleanup_connector;
}
DRM_INFO("%s, ret:%d", __func__, it6161_attach_dsi(it6161));
err = drm_connector_register(&it6161->connector);
if (err < 0) {
DRM_DEV_ERROR(dev, "Failed to register connector: %d", err);
@@ -4030,7 +4028,7 @@ static void hdmi_tx_enable_hdcp(struct it6161 *it6161)
}
#endif
static bool getHDMITX_LinkStatus()
static bool getHDMITX_LinkStatus(void)
{
it6161_debug("%s reg0E:0x%02x reg0x61:0x%02x", __func__, it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS), it6161_hdmi_tx_read(it6161, REG_TX_AFE_DRV_CTRL));//allen
if(B_TX_RXSENDETECT & it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS)) {
@@ -4669,7 +4667,7 @@ static void setHDMITX_HBRAudio(u8 bAudInterface /*I2S/SPDIF/TDM*/)
// it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, rst );
}
static void setHDMITX_DSDAudio()
static void setHDMITX_DSDAudio(void)
{
// to be continue
// u8 rst;
@@ -6812,6 +6810,12 @@ static int it6161_i2c_probe(struct i2c_client *i2c_mipi_rx,
it6161->bridge.funcs = &it6161_bridge_funcs;
drm_bridge_add(&it6161->bridge);
err = it6161_attach_dsi(it6161);
if (err) {
DRM_DEV_ERROR(dev, "failed to attach dsi, ret: %d", err);
goto err_cec;
}
return 0;
err_cec:

View File

@@ -179,21 +179,17 @@ static int max96755f_bridge_attach(struct drm_bridge *bridge,
drm_connector_attach_encoder(connector, bridge->encoder);
ser->dsi = max96755f_attach_dsi(ser, ser->dsi_node);
if (IS_ERR(ser->dsi))
return PTR_ERR(ser->dsi);
return 0;
}
static void max96755f_bridge_detach(struct drm_bridge *bridge)
{
struct max96755f_bridge *ser = to_max96755f_bridge(bridge);
}
if (ser->dsi) {
mipi_dsi_detach(ser->dsi);
mipi_dsi_device_unregister(ser->dsi);
}
static void max96755f_detach_dsi(struct max96755f_bridge *ser)
{
mipi_dsi_detach(ser->dsi);
mipi_dsi_device_unregister(ser->dsi);
}
static void max96755f_mipi_dsi_rx_config(struct max96755f_bridge *ser)
@@ -548,13 +544,27 @@ static int max96755f_bridge_probe(struct platform_device *pdev)
drm_bridge_add(&ser->bridge);
ser->dsi = max96755f_attach_dsi(ser, ser->dsi_node);
if (IS_ERR(ser->dsi)) {
dev_err(ser->dev, "failed to attach dsi\n");
ret = PTR_ERR(ser->dsi);
goto err_remove_bridge;
}
return 0;
err_remove_bridge:
drm_bridge_remove(&ser->bridge);
return ret;
}
static int max96755f_bridge_remove(struct platform_device *pdev)
{
struct max96755f_bridge *ser = platform_get_drvdata(pdev);
if (ser->dsi)
max96755f_detach_dsi(ser);
drm_bridge_remove(&ser->bridge);
return 0;

View File

@@ -169,13 +169,6 @@ static int bu18tl82_bridge_attach(struct drm_bridge *bridge,
if (ret)
return ret;
if (bu18tl82->sel_mipi) {
/* Attach primary DSI */
bu18tl82->dsi = bu18tl82_attach_dsi(bu18tl82, bu18tl82->dsi_node);
if (IS_ERR(bu18tl82->dsi))
return PTR_ERR(bu18tl82->dsi);
}
ret = drm_bridge_attach(bridge->encoder, bu18tl82->bridge,
bridge, flags);
if (ret) {
@@ -191,12 +184,12 @@ static int bu18tl82_bridge_attach(struct drm_bridge *bridge,
static void bu18tl82_bridge_detach(struct drm_bridge *bridge)
{
struct bu18tl82 *bu18tl82 = bridge_to_bu18tl82(bridge);
}
if (bu18tl82->sel_mipi) {
mipi_dsi_detach(bu18tl82->dsi);
mipi_dsi_device_unregister(bu18tl82->dsi);
}
static void bu18tl82_detach_dsi(struct bu18tl82 *bu18tl82)
{
mipi_dsi_detach(bu18tl82->dsi);
mipi_dsi_device_unregister(bu18tl82->dsi);
}
static void bu18tl82_bridge_enable(struct drm_bridge *bridge)
@@ -301,13 +294,30 @@ static int bu18tl82_i2c_probe(struct i2c_client *client,
drm_bridge_add(&bu18tl82->base);
if (bu18tl82->sel_mipi) {
/* Attach primary DSI */
bu18tl82->dsi = bu18tl82_attach_dsi(bu18tl82, bu18tl82->dsi_node);
if (IS_ERR(bu18tl82->dsi)) {
dev_err(bu18tl82->dev, "failed to attach dsi\n");
ret = PTR_ERR(bu18tl82->dsi);
goto err_remove_bridge;
}
}
return 0;
err_remove_bridge:
drm_bridge_remove(&bu18tl82->base);
return ret;
}
static void bu18tl82_i2c_remove(struct i2c_client *client)
{
struct bu18tl82 *bu18tl82 = i2c_get_clientdata(client);
if (bu18tl82->sel_mipi)
bu18tl82_detach_dsi(bu18tl82);
drm_bridge_remove(&bu18tl82->base);
}

View File

@@ -1479,6 +1479,10 @@ static int dw_mipi_dsi2_bind(struct device *dev, struct device *master,
if (ret)
goto encoder_cleanup;
if (dsi2->bridge && (dsi2->bridge->ops & DRM_BRIDGE_OP_DETECT))
dsi2->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
connector = &dsi2->connector;
}

View File

@@ -67,10 +67,16 @@ static int rockchip_hwspinlock_probe(struct platform_device *pdev)
{
struct rockchip_hwspinlock *hwspin;
struct hwspinlock *hwlock;
u32 num_locks = 0;
int idx, ret;
ret = device_property_read_u32(&pdev->dev, "rockchip,hwlock-num-locks",
&num_locks);
if (ret || !num_locks)
num_locks = HWSPINLOCK_NUMBER;
hwspin = devm_kzalloc(&pdev->dev,
struct_size(hwspin, bank.lock, HWSPINLOCK_NUMBER),
struct_size(hwspin, bank.lock, num_locks),
GFP_KERNEL);
if (!hwspin)
return -ENOMEM;
@@ -83,9 +89,9 @@ static int rockchip_hwspinlock_probe(struct platform_device *pdev)
&hwlock_user_id);
if (ret || !hwlock_user_id || hwlock_user_id > HWSPINLOCK_ID_MASK)
hwlock_user_id = HWLOCK_DEFAULT_USER;
dev_info(&pdev->dev, "hwlock user id %u\n", hwlock_user_id);
dev_info(&pdev->dev, "hwlock user id %u, locks %u\n", hwlock_user_id, num_locks);
for (idx = 0; idx < HWSPINLOCK_NUMBER; idx++) {
for (idx = 0; idx < num_locks; idx++) {
hwlock = &hwspin->bank.lock[idx];
hwlock->priv = hwspin->io_base + HWSPINLOCK_OFFSET(idx);
}
@@ -94,7 +100,7 @@ static int rockchip_hwspinlock_probe(struct platform_device *pdev)
return devm_hwspin_lock_register(&pdev->dev, &hwspin->bank,
&rockchip_hwspinlock_ops, 0,
HWSPINLOCK_NUMBER);
num_locks);
}
static const struct of_device_id rockchip_hwpinlock_ids[] = {

View File

@@ -179,6 +179,11 @@
#define TTL_MODE_ENABLE BIT(2)
#define LVDS_MODE_ENABLE BIT(1)
#define MIPI_MODE_ENABLE BIT(0)
/* LVDS Register Part: reg04 */
#define LVDS_VCOM_MASK GENMASK(5, 4)
#define LVDS_VCOM(x) UPDATE(x, 5, 4)
#define LVDS_VOD_MASK GENMASK(7, 6)
#define LVDS_VOD(x) UPDATE(x, 7, 6)
/* LVDS Register Part: reg0b */
#define LVDS_LANE_EN_MASK GENMASK(7, 3)
#define LVDS_DATA_LANE0_EN BIT(7)
@@ -239,6 +244,8 @@ struct inno_dsidphy {
u16 fbdiv;
unsigned long rate;
} pll;
u32 lvds_vcom;
u32 lvds_vod;
};
enum {
@@ -638,6 +645,35 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
inno_mipi_dphy_lane_enable(inno);
}
static void inno_dsiphy_lvds_voltage_set(struct inno_dsidphy *inno)
{
u32 val = 0;
/* This version of inno phy does not have voltage register, skip it. */
if (inno->pdata->max_rate == MAX_1GHZ)
return;
if (inno->lvds_vcom >= 1000)
val |= LVDS_VCOM(3);
else if (inno->lvds_vcom >= 950)
val |= LVDS_VCOM(2);
else if (inno->lvds_vcom >= 900)
val |= LVDS_VCOM(0);
else
val |= LVDS_VCOM(1); /* 850mV */
if (inno->lvds_vod >= 400)
val |= LVDS_VOD(3);
else if (inno->lvds_vod >= 350)
val |= LVDS_VOD(2);
else if (inno->lvds_vod >= 300)
val |= LVDS_VOD(1);
else
val |= LVDS_VOD(0); /* 250mV */
phy_update_bits(inno, REGISTER_PART_LVDS, 0x04, LVDS_VCOM_MASK | LVDS_VOD_MASK, val);
}
static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
{
u8 prediv = 2;
@@ -657,7 +693,7 @@ static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
phy_update_bits(inno, REGISTER_PART_LVDS, 0x00,
LVDS_DIGITAL_INTERNAL_RESET_MASK,
LVDS_DIGITAL_INTERNAL_RESET_DISABLE);
inno_dsiphy_lvds_voltage_set(inno);
/* Select LVDS mode */
phy_update_bits(inno, REGISTER_PART_LVDS, 0x03,
MODE_ENABLE_MASK, LVDS_MODE_ENABLE);
@@ -956,9 +992,15 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
return ret;
}
if (of_property_read_u32(dev->of_node, "inno,lanes", &inno->lanes))
if (device_property_read_u32(dev, "inno,lanes", &inno->lanes))
inno->lanes = 4;
if (device_property_read_u32(dev, "inno,lvds-vcom", &inno->lvds_vcom))
inno->lvds_vcom = 950;
if (device_property_read_u32(dev, "inno,lvds-vod", &inno->lvds_vod))
inno->lvds_vod = 350;
phy_set_drvdata(phy, inno);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);

View File

@@ -590,6 +590,7 @@ static const u16 trans_tbl_h264e_540c[] = {
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
// /* renc and ref wrap */
// 24, 25, 26, 27,
28, 29, 30
};
static const u16 trans_tbl_h264e_540c_osd[] = {
@@ -599,7 +600,8 @@ static const u16 trans_tbl_h264e_540c_osd[] = {
static const u16 trans_tbl_h265e_540c[] = {
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
28, 29, 30
};
static const u16 trans_tbl_h265e_540c_osd[] = {

View File

@@ -35,6 +35,7 @@ struct rga_request *rga_request_lookup(struct rga_pending_request_manager *reque
uint32_t id);
int rga_request_commit(struct rga_request *user_request);
void rga_request_scheduler_abort(struct rga_scheduler_t *scheduler);
void rga_request_session_destroy_abort(struct rga_session *session);
int rga_request_put(struct rga_request *request);
void rga_request_get(struct rga_request *request);

View File

@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/syscalls.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
@@ -21,6 +22,7 @@
#include "rga_drv.h"
#include "rga_mm.h"
#include "rga_common.h"
#include "rga_job.h"
#define RGA_DEBUGGER_ROOT_NAME "rkrga"
@@ -462,6 +464,65 @@ static int rga_hardware_show(struct seq_file *m, void *data)
return 0;
}
static int rga_reset_show(struct seq_file *m, void *data)
{
struct rga_scheduler_t *scheduler = NULL;
int i;
seq_puts(m, "help:\n");
seq_puts(m, " 'echo <core> > reset' to reset hardware.\n");
seq_puts(m, "core:\n");
for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
scheduler = rga_drvdata->scheduler[i];
seq_printf(m, " %s core <%d>\n",
dev_driver_string(scheduler->dev), scheduler->core);
}
return 0;
}
static ssize_t rga_reset_write(struct file *file, const char __user *ubuf,
size_t len, loff_t *offp)
{
char buf[14];
int i, ret;
int reset_core = 0;
int reset_done = false;
struct rga_scheduler_t *scheduler = NULL;
if (len > sizeof(buf) - 1)
return -EINVAL;
if (copy_from_user(buf, ubuf, len))
return -EFAULT;
buf[len - 1] = '\0';
ret = kstrtoint(buf, 10, &reset_core);
if (ret < 0 || reset_core <= 0) {
pr_err("invalid core! failed to reset hardware, data = %s len = %zu.\n", buf, len);
return -EINVAL;
}
for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
scheduler = rga_drvdata->scheduler[i];
if (scheduler->core == reset_core) {
reset_done = true;
pr_info("reset hardware core[%d]!\n", reset_core);
rga_request_scheduler_abort(scheduler);
break;
}
}
if (!reset_done)
pr_err("cannot find core[%d]\n", reset_core);
return len;
}
static struct rga_debugger_list rga_debugger_root_list[] = {
{"debug", rga_debug_show, rga_debug_write, NULL},
{"driver_version", rga_version_show, NULL, NULL},
@@ -474,6 +535,7 @@ static struct rga_debugger_list rga_debugger_root_list[] = {
{"dump_image", rga_dump_image_show, rga_dump_image_write, NULL},
#endif
{"hardware", rga_hardware_show, NULL, NULL},
{"reset", rga_reset_show, rga_reset_write, NULL},
};
static ssize_t rga_debugger_write(struct file *file, const char __user *ubuf,

View File

@@ -651,6 +651,46 @@ struct rga_request *rga_request_lookup(struct rga_pending_request_manager *manag
return request;
}
void rga_request_scheduler_abort(struct rga_scheduler_t *scheduler)
{
struct rga_job *job;
unsigned long flags;
rga_power_enable(scheduler);
spin_lock_irqsave(&scheduler->irq_lock, flags);
job = scheduler->running_job;
if (job) {
scheduler->running_job = NULL;
scheduler->status = RGA_SCHEDULER_ABORT;
scheduler->ops->soft_reset(scheduler);
spin_unlock_irqrestore(&scheduler->irq_lock, flags);
rga_mm_unmap_job_info(job);
job->ret = -EBUSY;
rga_request_release_signal(scheduler, job);
rga_job_next(scheduler);
/*
* Since the running job was abort, turn off the power here that
* should have been turned off after job done (corresponds to
* power_enable in rga_job_run()).
*/
rga_power_disable(scheduler);
} else {
scheduler->status = RGA_SCHEDULER_ABORT;
scheduler->ops->soft_reset(scheduler);
spin_unlock_irqrestore(&scheduler->irq_lock, flags);
}
rga_power_disable(scheduler);
}
static int rga_request_scheduler_job_abort(struct rga_request *request)
{
int i;