1,内核添加如下补丁后可通过节点查看phy的各项参数:
--- a/kernel/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
@@ -148,6 +148,25 @@
#define T_TA_GET(x) UPDATE(x, 7, 4)
#define T_TA_GO(x) UPDATE(x, 3, 0)
+#define REG_400M_MASK GENMASK(6, 4)
+#define REG_400M(x) UPDATE(x, 6, 4)
+#define BIAS_CON4 0x0010
+#define I_MUX_SEL_MASK GENMASK(6, 5)
+#define I_MUX_SEL(x) UPDATE(x, 6, 5)
+#define CAP_PEAKING_MASK GENMASK(14, 12)
+#define CAP_PEAKING(x) UPDATE(x, 14, 12)
+#define RES_UP_MASK GENMASK(7, 4)
+#define RES_UP(x) UPDATE(x, 7, 4)
+#define RES_DN_MASK GENMASK(3, 0)
+#define RES_DN(x) UPDATE(x, 3, 0)
+#define T_HS_ZERO_MASK GENMASK(15, 8)
+#define T_HS_PREPARE_MASK GENMASK(7, 0)
+#define T_HS_EXIT_MASK GENMASK(15, 8)
+#define T_HS_TRAIL_MASK GENMASK(7, 0)
+#define T_TA_GET_MASK GENMASK(7, 4)
+#define T_TA_GO_MASK GENMASK(3, 0)
/* MIPI_CDPHY_GRF registers */
#define MIPI_DCPHY_GRF_CON0 0x0000
#define S_CPHY_MODE HIWORD_UPDATE(1, 3, 3)
@@ -1236,6 +1255,456 @@ struct samsung_mipi_cphy_timing samsung_mipi_cphy_timing_table\[\] = {
{ 80, 1, 50, 25, 2, 0, 2 },
};
+static ssize_t
+reg_400m_show(struct device *device, struct device_attribute *attr, char *buf)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned int val;
-
unsigned int level;
-
regmap_read(samsung->regmap, BIAS_CON2, &val);
-
level = (val & REG_400M_MASK) >> 4;
-
return sprintf(buf, "%d\n", level);
+}
+static ssize_t
+reg_400m_store(struct device *device, struct device_attribute *attr,
- const char *buf, size_t count)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned long val;
-
if (kstrtoul(buf, 10, &val))
-
return -EINVAL;
-
if (val > 7)
-
val = 7;
-
regmap_update_bits(samsung->regmap, BIAS_CON2, REG_400M_MASK, REG_400M(val));
- return count;
+}
+static DEVICE_ATTR_RW(reg_400m);
+static ssize_t
+cap_peaking_show(struct device *device, struct device_attribute *attr, char
- *buf)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned int val;
-
unsigned int level;
-
regmap_read(samsung->regmap, COMBO_MD0_ANA_CON0, &val);
-
level = (val & CAP_PEAKING_MASK) >> 12;
-
return sprintf(buf, "%d\n", level);
+}
+static ssize_t
+cap_peaking_store(struct device *device, struct device_attribute *attr,
- const char *buf, size_t count)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned long val;
-
if (kstrtoul(buf, 10, &val))
-
return -EINVAL;
-
if (val > 7)
-
val = 7;
-
regmap_update_bits(samsung->regmap, DPHY_MC_ANA_CON0, CAP_PEAKING_MASK,
-
CAP_PEAKING(val));
-
regmap_update_bits(samsung->regmap, COMBO_MD0_ANA_CON0, CAP_PEAKING_MASK,
-
CAP_PEAKING(val));
-
regmap_update_bits(samsung->regmap, COMBO_MD1_ANA_CON0, CAP_PEAKING_MASK,
-
CAP_PEAKING(val));
-
regmap_update_bits(samsung->regmap, COMBO_MD2_ANA_CON0, CAP_PEAKING_MASK,
-
CAP_PEAKING(val));
-
regmap_update_bits(samsung->regmap, DPHY_MD3_ANA_CON0, CAP_PEAKING_MASK,
-
CAP_PEAKING(val));
- return count;
+}
+static DEVICE_ATTR_RW(cap_peaking);
+static ssize_t
+res_up_show(struct device *device, struct device_attribute *attr, char *buf)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned int val;
-
unsigned int level;
-
regmap_read(samsung->regmap, COMBO_MD0_ANA_CON0, &val);
-
level = (val & RES_UP_MASK) >> 4;
-
return sprintf(buf, "%d\n", level);
+}
+static ssize_t
+res_up_store(struct device *device, struct device_attribute *attr,
- const char *buf, size_t count)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned long val;
-
if (kstrtoul(buf, 10, &val))
-
return -EINVAL;
-
if (val > 15)
-
val = 15;
-
regmap_update_bits(samsung->regmap, DPHY_MC_ANA_CON0, RES_UP_MASK,
-
RES_UP(val));
-
regmap_update_bits(samsung->regmap, COMBO_MD0_ANA_CON0, RES_UP_MASK,
-
RES_UP(val));
-
regmap_update_bits(samsung->regmap, COMBO_MD1_ANA_CON0, RES_UP_MASK,
-
RES_UP(val));
-
regmap_update_bits(samsung->regmap, COMBO_MD2_ANA_CON0, RES_UP_MASK,
-
RES_UP(val));
-
regmap_update_bits(samsung->regmap, DPHY_MD3_ANA_CON0, RES_UP_MASK,
-
RES_UP(val));
- return count;
+}
+static DEVICE_ATTR_RW(res_up);
+static ssize_t
+res_dn_show(struct device *device, struct device_attribute *attr, char *buf)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned int val;
-
unsigned int level;
-
regmap_read(samsung->regmap, COMBO_MD0_ANA_CON0, &val);
-
level = (val & RES_DN_MASK);
-
return sprintf(buf, "%d\n", level);
+}
+static ssize_t
+res_dn_store(struct device *device, struct device_attribute *attr,
- const char *buf, size_t count)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned long val;
-
if (kstrtoul(buf, 10, &val))
-
return -EINVAL;
-
if (val > 15)
-
val = 15;
-
regmap_update_bits(samsung->regmap, DPHY_MC_ANA_CON0, RES_DN_MASK,
-
RES_DN(val));
-
regmap_update_bits(samsung->regmap, COMBO_MD0_ANA_CON0, RES_DN_MASK,
-
RES_DN(val));
-
regmap_update_bits(samsung->regmap, COMBO_MD1_ANA_CON0, RES_DN_MASK,
-
RES_DN(val));
-
regmap_update_bits(samsung->regmap, COMBO_MD2_ANA_CON0, RES_DN_MASK,
-
RES_DN(val));
-
regmap_update_bits(samsung->regmap, DPHY_MD3_ANA_CON0, RES_DN_MASK,
-
RES_DN(val));
- return count;
+}
+static DEVICE_ATTR_RW(res_dn);
+static ssize_t
+output_voltage_show(struct device *device, struct device_attribute *attr, char
- *buf)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned int val;
-
unsigned int level;
-
regmap_read(samsung->regmap, BIAS_CON4, &val);
-
level = (val & I_MUX_SEL_MASK) >> 5;
-
return sprintf(buf, "%d\n", level);
+}
+static ssize_t
+output_voltage_store(struct device *device, struct device_attribute *attr,
- const char *buf, size_t count)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned long val;
-
if (kstrtoul(buf, 10, &val))
-
return -EINVAL;
-
if (val > 3)
-
val = 3;
-
regmap_update_bits(samsung->regmap, BIAS_CON4,
-
I_MUX_SEL_MASK, I_MUX_SEL(val));
- return count;
+}
+static DEVICE_ATTR_RW(output_voltage);
+static ssize_t
+hs_exit_show(struct device *device, struct device_attribute *attr, char *buf)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned int val;
-
unsigned int hs_exit;
-
regmap_read(samsung->regmap, COMBO_MD0_TIME_CON2, &val);
-
hs_exit = (val & GENMASK(15, 8)) >> 8;
-
return sprintf(buf, "%d\n", hs_exit);
+}
+static ssize_t hs_exit_store(struct device *device, struct device_attribute
-
*attr,
-
const char *buf, size_t count)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned long val;
-
unsigned long hs_exit;
-
if (kstrtoul(buf, 10, &val))
-
return -EINVAL;
-
hs_exit = T_HS_EXIT(val);
-
regmap_update_bits(samsung->regmap, COMBO_MD0_TIME_CON2, T_HS_EXIT_MASK,
-
hs_exit);
-
regmap_update_bits(samsung->regmap, COMBO_MD1_TIME_CON2, T_HS_EXIT_MASK,
-
hs_exit);
-
regmap_update_bits(samsung->regmap, COMBO_MD2_TIME_CON2, T_HS_EXIT_MASK,
-
hs_exit);
-
if (!samsung->c_option) {
-
regmap_update_bits(samsung->regmap, DPHY_MC_TIME_CON2, T_HS_EXIT_MASK,
-
hs_exit);
-
regmap_update_bits(samsung->regmap, DPHY_MD3_TIME_CON2, T_HS_EXIT_MASK,
-
hs_exit);
-
}
- return count;
+}
+static DEVICE_ATTR_RW(hs_exit);
+static ssize_t
+hs_trail_or_post_3_show(struct device *device, struct device_attribute *attr,
- char *buf)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned int val;
-
unsigned int hs_trail;
-
regmap_read(samsung->regmap, COMBO_MD0_TIME_CON2, &val);
-
hs_trail = val & GENMASK(7, 0);
-
return sprintf(buf, "%d\n", hs_trail);
+}
+static ssize_t hs_trail_or_post_3_store(struct device *device, struct
-
device_attribute *attr,
-
const char *buf, size_t count)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned long val;
-
unsigned long hs_trail;
-
if (kstrtoul(buf, 10, &val))
-
return -EINVAL;
-
hs_trail = T_HS_TRAIL(val);
-
regmap_update_bits(samsung->regmap, COMBO_MD0_TIME_CON2, T_HS_TRAIL_MASK,
-
hs_trail);
-
regmap_update_bits(samsung->regmap, COMBO_MD1_TIME_CON2, T_HS_TRAIL_MASK,
-
hs_trail);
-
regmap_update_bits(samsung->regmap, COMBO_MD2_TIME_CON2, T_HS_TRAIL_MASK,
-
hs_trail);
-
if (!samsung->c_option) {
-
regmap_update_bits(samsung->regmap, DPHY_MC_TIME_CON2, T_HS_TRAIL_MASK,
-
hs_trail);
-
regmap_update_bits(samsung->regmap, DPHY_MD3_TIME_CON2, T_HS_TRAIL_MASK,
-
hs_trail);
-
}
- return count;
+}
+static DEVICE_ATTR_RW(hs_trail_or_post_3);
+static ssize_t
+hs_zero_or_prebegin_3_show(struct device *device, struct device_attribute *attr,
- char *buf)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned int val;
-
unsigned int hs_zero;
-
regmap_read(samsung->regmap, COMBO_MD0_TIME_CON1, &val);
-
hs_zero = (val & GENMASK(15, 8)) >> 8;
-
return sprintf(buf, "%d\n", hs_zero);
+}
+static ssize_t hs_zero_or_prebegin_3_store(struct device *device, struct
-
device_attribute *attr,
-
const char *buf, size_t count)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned long val;
-
unsigned long hs_zero;
-
if (kstrtoul(buf, 10, &val))
-
return -EINVAL;
-
hs_zero = T_HS_ZERO(val);
-
regmap_update_bits(samsung->regmap, COMBO_MD0_TIME_CON1,
-
T_HS_ZERO_MASK, hs_zero);
-
regmap_update_bits(samsung->regmap, COMBO_MD1_TIME_CON1,
-
T_HS_ZERO_MASK, hs_zero);
-
regmap_update_bits(samsung->regmap, COMBO_MD2_TIME_CON1,
-
T_HS_ZERO_MASK, hs_zero);
-
if (!samsung->c_option) {
-
regmap_update_bits(samsung->regmap, DPHY_MC_TIME_CON1,
-
T_HS_ZERO_MASK, hs_zero);
-
regmap_update_bits(samsung->regmap, DPHY_MD3_TIME_CON1,
-
T_HS_ZERO_MASK, hs_zero);
-
}
- return count;
+}
+static DEVICE_ATTR_RW(hs_zero_or_prebegin_3);
+static ssize_t
+hs_prepare_or_prepare_3_show(struct device *device, struct device_attribute
- *attr, char *buf)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned int val;
-
unsigned int hs_prepare;
-
regmap_read(samsung->regmap, COMBO_MD0_TIME_CON1, &val);
-
hs_prepare = val & GENMASK(7, 0);
- return sprintf(buf, "%d\n", hs_prepare);
+}
+static ssize_t hs_prepare_or_prepare_3_store(struct device *device, struct
+device_attribute *attr,
- const char *buf, size_t count)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned long val;
-
unsigned long hs_prepare;
-
if (kstrtoul(buf, 10, &val))
-
return -EINVAL;
-
hs_prepare = T_HS_PREPARE(val);
-
regmap_update_bits(samsung->regmap, COMBO_MD0_TIME_CON1,
-
T_HS_PREPARE_MASK, hs_prepare);
-
regmap_update_bits(samsung->regmap, COMBO_MD1_TIME_CON1,
-
T_HS_PREPARE_MASK, hs_prepare);
-
regmap_update_bits(samsung->regmap, COMBO_MD2_TIME_CON1,
-
T_HS_PREPARE_MASK, hs_prepare);
-
if (!samsung->c_option) {
-
regmap_update_bits(samsung->regmap, DPHY_MC_TIME_CON1,
-
T_HS_PREPARE_MASK, hs_prepare);
-
regmap_update_bits(samsung->regmap, DPHY_MD3_TIME_CON1,
-
T_HS_PREPARE_MASK, hs_prepare);
-
}
- return count;
+}
+static DEVICE_ATTR_RW(hs_prepare_or_prepare_3);
+static ssize_t
+lpx_show(struct device *device, struct device_attribute *attr, char *buf)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned int val;
-
unsigned int lpx;
-
regmap_read(samsung->regmap, COMBO_MD0_TIME_CON0, &val);
-
lpx = (val & GENMASK(11, 4)) >> 4;
-
return sprintf(buf, "%d\n", lpx);
+}
+static ssize_t lpx_store(struct device *device, struct device_attribute *attr,
- const char *buf, size_t count)
+{
-
struct samsung_mipi_dcphy *samsung = dev_get_drvdata(device);
-
unsigned long val;
-
unsigned long lpx = 0;
-
if (kstrtoul(buf, 10, &val))
-
return -EINVAL;
-
lpx |= T_LPX(val);
-
/* T_LP_EXIT_SKEW/T_LP_ENTRY_SKEW unconfig */
-
regmap_write(samsung->regmap, COMBO_MD0_TIME_CON0, lpx);
-
regmap_write(samsung->regmap, COMBO_MD1_TIME_CON0, lpx);
-
regmap_write(samsung->regmap, COMBO_MD2_TIME_CON0, lpx);
-
if (!samsung->c_option) {
-
regmap_write(samsung->regmap, DPHY_MC_TIME_CON0, lpx);
-
regmap_write(samsung->regmap, DPHY_MD3_TIME_CON0, lpx);
-
}
- return count;
+}
+static DEVICE_ATTR_RW(lpx);
+static struct attribute *samsung_mipi_dcphy_cts_attrs\[\] = {
-
&dev_attr_lpx.attr,
-
&dev_attr_hs_prepare_or_prepare_3.attr,
-
&dev_attr_hs_zero_or_prebegin_3.attr,
-
&dev_attr_hs_trail_or_post_3.attr,
-
&dev_attr_hs_exit.attr,
-
&dev_attr_output_voltage.attr,
-
&dev_attr_res_up.attr,
-
&dev_attr_res_dn.attr,
-
&dev_attr_cap_peaking.attr,
-
&dev_attr_reg_400m.attr,
-
NULL
+};
+static const struct attribute_group samsung_mipi_dcphy_cts_attr_group = {
- .attrs = samsung_mipi_dcphy_cts_attrs,
+};
+static int samsung_mipi_dcphy_cts_sysfs_add(struct samsung_mipi_dcphy *samsung)
+{
-
struct device *dev = samsung->dev;
-
int ret;
-
ret = sysfs_create_group(&dev->kobj, &samsung_mipi_dcphy_cts_attr_group);
-
if (ret) {
-
dev_err(dev, "failed to register sysfs. err: %d\n", ret);
-
return ret;
-
};
- return 0;
+}
struct hsfreq_range {
u32 range_h;
u16 cfg_bit;
@@ -2385,6 +2854,14 @@ static int samsung_mipi_dcphy_probe(struct platform_device *pdev)
samsung->stream_on = samsung_dcphy_rx_stream_on;
samsung->stream_off = samsung_dcphy_rx_stream_off;
mutex_init(&samsung->mutex);
-
ret = samsung_mipi_dcphy_cts_sysfs_add(samsung);
-
if (ret)
-
return ret;
具体节点说明可参考《Rockchip_Developer_Guide_MIPI_DSI2_CN.pdf》中"调试节点"章节。
比如要提高驱动强度,可在samsung_mipi_dcphy_probe末尾添加如下代码:
/*D-PHY默认强度为0(400mV),修改默认设置MIPI驱动强度为最大。b00:400mV b01:200mV b10:530mV b11:530mV*/
regmap_update_bits(samsung->regmap, BIAS_CON4,
I_MUX_SEL_MASK, I_MUX_SEL(3));
查看驱动强度的节点:cat /sys/devices/platform/feda0000.phy/output_voltage
2,uboot中调整phy参数在/u-boot/drivers/video/drm/samsung_mipi_dcphy.c中
可在samsung_mipi_dcphy_bias_block_enable函数中配置,如下:
static void samsung_mipi_dcphy_bias_block_enable(struct samsung_mipi_dcphy *samsung)
{
phy_write(samsung, BIAS_CON0, 0x0010);
phy_write(samsung, BIAS_CON1, 0x0110);
phy_write(samsung, BIAS_CON2, 0x3223);
if (samsung->c_option){
phy_update_bits(samsung, BIAS_CON4, I_MUX_SEL_MASK, I_MUX_SEL(2));
}
}
比如我要修改D-PHY时mipi强度为最大530mV,可如下修改:
static void samsung_mipi_dcphy_bias_block_enable(struct samsung_mipi_dcphy *samsung)
{
phy_write(samsung, BIAS_CON0, 0x0010);
phy_write(samsung, BIAS_CON1, 0x0110);
phy_write(samsung, BIAS_CON2, 0x3223);
// if (samsung->c_option){
phy_update_bits(samsung, BIAS_CON4, I_MUX_SEL_MASK, I_MUX_SEL(2));
// }
}