[PATCH] drm/nouveau/hwmon: convert sysfs snprintf to sysfs_emit
From: Xuezhi Zhang Fix the following coccicheck warning: drivers/gpu/drm//nouveau/nouveau_hwmon.c:44:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm//nouveau/nouveau_hwmon.c:57:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm//nouveau/nouveau_hwmon.c:90:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Xuezhi Zhang --- drivers/gpu/drm/nouveau/nouveau_hwmon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_hwmon.c index 1c3104d20571..c6e5ee9ece6d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c @@ -41,7 +41,7 @@ static ssize_t nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d, struct device_attribute *a, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", 100); + return sysfs_emit(buf, "%d\n", 100); } static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444, nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0); @@ -54,7 +54,7 @@ nouveau_hwmon_temp1_auto_point1_temp(struct device *d, struct nouveau_drm *drm = nouveau_drm(dev); struct nvkm_therm *therm = nvxx_therm(&drm->client.device); - return snprintf(buf, PAGE_SIZE, "%d\n", + return sysfs_emit(buf, "%d\n", therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST) * 1000); } static ssize_t @@ -87,7 +87,7 @@ nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device *d, struct nouveau_drm *drm = nouveau_drm(dev); struct nvkm_therm *therm = nvxx_therm(&drm->client.device); - return snprintf(buf, PAGE_SIZE, "%d\n", + return sysfs_emit(buf, "%d\n", therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000); } static ssize_t -- 2.25.1
[PATCH v2] drm/panel: panel-dsi-cm: convert sysfs snprintf to sysfs_emit
From: Xuezhi Zhang Fix the following coccicheck warning: drivers/gpu/drm//panel/panel-dsi-cm.c:271:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm//panel/panel-dsi-cm.c:251:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Xuezhi Zhang --- v2: change snprint to snprintf in subject. --- drivers/gpu/drm/panel/panel-dsi-cm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c index 5fbfb71ca3d9..a8efb06cca64 100644 --- a/drivers/gpu/drm/panel/panel-dsi-cm.c +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c @@ -248,7 +248,7 @@ static ssize_t num_dsi_errors_show(struct device *dev, if (r) return r; - return snprintf(buf, PAGE_SIZE, "%d\n", errors); + return sysfs_emit(buf, "%d\n", errors); } static ssize_t hw_revision_show(struct device *dev, @@ -268,7 +268,7 @@ static ssize_t hw_revision_show(struct device *dev, if (r) return r; - return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3); + return sysfs_emit(buf, "%02x.%02x.%02x\n", id1, id2, id3); } static DEVICE_ATTR_RO(num_dsi_errors); -- 2.25.1
[PATCH] drm/panel: panel-dsi-cm: convert sysfs snprint to sysfs_emit
From: Xuezhi Zhang Fix the following coccicheck warning: drivers/gpu/drm//panel/panel-dsi-cm.c:271:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm//panel/panel-dsi-cm.c:251:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Xuezhi Zhang --- drivers/gpu/drm/panel/panel-dsi-cm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c index 5fbfb71ca3d9..a8efb06cca64 100644 --- a/drivers/gpu/drm/panel/panel-dsi-cm.c +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c @@ -248,7 +248,7 @@ static ssize_t num_dsi_errors_show(struct device *dev, if (r) return r; - return snprintf(buf, PAGE_SIZE, "%d\n", errors); + return sysfs_emit(buf, "%d\n", errors); } static ssize_t hw_revision_show(struct device *dev, @@ -268,7 +268,7 @@ static ssize_t hw_revision_show(struct device *dev, if (r) return r; - return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3); + return sysfs_emit(buf, "%02x.%02x.%02x\n", id1, id2, id3); } static DEVICE_ATTR_RO(num_dsi_errors); -- 2.25.1
[PATCH] drm/panel: tpo-td043mtea1: convert sysfs snprintf to sysfs_emit
From: Xuezhi Zhang Fix the following coccicheck warning: drivers/gpu/drm//panel/panel-tpo-td043mtea1.c:217:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm//panel/panel-tpo-td043mtea1.c:189:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Xuezhi Zhang --- drivers/gpu/drm/panel/panel-tpo-td043mtea1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c b/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c index 49e6c9386258..bacaf1b7fb70 100644 --- a/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c @@ -186,7 +186,7 @@ static ssize_t vmirror_show(struct device *dev, struct device_attribute *attr, { struct td043mtea1_panel *lcd = dev_get_drvdata(dev); - return snprintf(buf, PAGE_SIZE, "%d\n", lcd->vmirror); + return sysfs_emit(buf, "%d\n", lcd->vmirror); } static ssize_t vmirror_store(struct device *dev, struct device_attribute *attr, @@ -214,7 +214,7 @@ static ssize_t mode_show(struct device *dev, struct device_attribute *attr, { struct td043mtea1_panel *lcd = dev_get_drvdata(dev); - return snprintf(buf, PAGE_SIZE, "%d\n", lcd->mode); + return sysfs_emit(buf, "%d\n", lcd->mode); } static ssize_t mode_store(struct device *dev, struct device_attribute *attr, -- 2.25.1
Re: [PATCH] drm/amd/pm: convert sysfs snprintf to sysfs_emit
On Wed, 7 Apr 2021 16:30:01 -0400 Alex Deucher wrote: > On Tue, Apr 6, 2021 at 10:13 AM Carlis wrote: > > > > From: Xuezhi Zhang > > > > Fix the following coccicheck warning: > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:1940:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:1978:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2022:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:294:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:154:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:496:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:512:9-17: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:1740:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:1667:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2074:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2047:9-17: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2768:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2738:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2442:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:3246:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:3253:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2458:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:3047:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:3133:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:3209:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:3216:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2410:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2496:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2470:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2426:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2965:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:2972:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:3006:8-16: > > WARNING: use scnprintf or sprintf > > drivers/gpu/drm/amd/pm//amdgpu_pm.c:3013:8-16: > > WARNING: use scnprintf or sprintf > > > > Signed-off-by: Xuezhi Zhang > > I already applied a similar patch last week. > > Thanks, > > Alex > OK. Thanks, Xuezhi Zhang > > > --- > > drivers/gpu/drm/amd/pm/amdgpu_pm.c | 58 > > +++--- 1 file changed, 29 insertions(+), 29 > > deletions(-) > > > > diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c > > b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index > > 5fa65f191a37..2777966ec1ca 100644 --- > > a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ > > b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -151,7 +151,7 @@ static > > ssize_t amdgpu_get_power_dpm_state(struct device *dev, > > pm_runtime_mark_last_busy(ddev->dev); > > pm_runtime_put_autosuspend(ddev->dev); > > > > - return snprintf(buf, PAGE_SIZE, "%s\n", > > + return sysfs_emit(buf, "%s\n", > > (pm == POWER_STATE_TYPE_BATTERY) ? > > "battery" : (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : > > "performance"); } > > @@ -291,7 +291,7 @@ static ssize_t > > amdgpu_get_power_dpm_force_performance_level(struct device *dev, > > pm_runtime_mark_last_busy(ddev->dev); > > pm_runtime_put_autosuspend(ddev->dev); > > > > - return snprintf(buf, PAGE_SIZE, "%s\n", > > + return sysfs_emit(buf, "%s\n", > > (level == AMD_DPM_FORCED_LEVEL_AUTO) ? > > "auto" : (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : > > (level == AMD_DPM_FORCED_LEVEL_HIGH) ? > > "high" : @@ -493,7 +493,7 @@ static ssize_t > > amdgpu_get_pp_cur_state(struct device *dev, if (i =
[PATCH] drm/amd/pm: convert sysfs snprintf to sysfs_emit
From: Xuezhi Zhang Fix the following coccicheck warning: drivers/gpu/drm/amd/pm//amdgpu_pm.c:1940:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:1978:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2022:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:294:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:154:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:496:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:512:9-17: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:1740:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:1667:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2074:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2047:9-17: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2768:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2738:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2442:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:3246:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:3253:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2458:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:3047:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:3133:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:3209:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:3216:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2410:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2496:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2470:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2426:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2965:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:2972:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:3006:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/amd/pm//amdgpu_pm.c:3013:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Xuezhi Zhang --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 58 +++--- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 5fa65f191a37..2777966ec1ca 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -151,7 +151,7 @@ static ssize_t amdgpu_get_power_dpm_state(struct device *dev, pm_runtime_mark_last_busy(ddev->dev); pm_runtime_put_autosuspend(ddev->dev); - return snprintf(buf, PAGE_SIZE, "%s\n", + return sysfs_emit(buf, "%s\n", (pm == POWER_STATE_TYPE_BATTERY) ? "battery" : (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); } @@ -291,7 +291,7 @@ static ssize_t amdgpu_get_power_dpm_force_performance_level(struct device *dev, pm_runtime_mark_last_busy(ddev->dev); pm_runtime_put_autosuspend(ddev->dev); - return snprintf(buf, PAGE_SIZE, "%s\n", + return sysfs_emit(buf, "%s\n", (level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" : (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : (level == AMD_DPM_FORCED_LEVEL_HIGH) ? "high" : @@ -493,7 +493,7 @@ static ssize_t amdgpu_get_pp_cur_state(struct device *dev, if (i == data.nums) i = -EINVAL; - return snprintf(buf, PAGE_SIZE, "%d\n", i); + return sysfs_emit(buf, "%d\n", i); } static ssize_t amdgpu_get_pp_force_state(struct device *dev, @@ -509,7 +509,7 @@ static ssize_t amdgpu_get_pp_force_state(struct device *dev, if (adev->pp_force_state_enabled) return amdgpu_get_pp_cur_state(dev, attr, buf); else - return snprintf(buf, PAGE_SIZE, "\n"); + return sysfs_emit(buf, "\n"); } static ssize_t amdgpu_set_pp_force_state(struct device *dev, @@ -1664,7 +1664,7 @@ static ssize_t amdgpu_get_pp_sclk_od(struct device *dev, pm_runtime_mark_last_busy(ddev->dev); pm_runtime_put_autosuspend(ddev->dev); - return snprintf(buf, PAGE_SIZE, "%d\n", value); + return sysfs_emit(buf, "%d\n", value); } static ssize_t amdgpu_set_pp_sclk_od(struct device *dev, @@ -1737,7 +1737,7 @@ static ssize_t amdgpu_get_pp_mclk_od(struct device *dev, pm_runtime_mark_last_busy(ddev->dev); pm_runtime_put_autosuspend(ddev->dev); - return snprintf(buf, PAGE_SIZE, "%d\n", value); + return sysfs_emit(buf, "%d\n
[PATCH] drm/i915/sysfs: convert snprintf to sysfs_emit
From: Xuezhi Zhang Fix the following coccicheck warning: drivers/gpu/drm/i915//i915_sysfs.c:266:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:285:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:276:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:335:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:390:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:465:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:107:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:75:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:83:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:91:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:99:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/i915//i915_sysfs.c:326:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Xuezhi Zhang --- drivers/gpu/drm/i915/i915_sysfs.c | 30 -- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 45d32ef42787..4c6b5d52b5ca 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -72,7 +72,7 @@ show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf) if (HAS_RC6pp(dev_priv)) mask |= BIT(2); - return snprintf(buf, PAGE_SIZE, "%x\n", mask); + return sysfs_emit(buf, "%x\n", mask); } static ssize_t @@ -80,7 +80,7 @@ show_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); u32 rc6_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6); - return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency); + return sysfs_emit(buf, "%u\n", rc6_residency); } static ssize_t @@ -88,7 +88,7 @@ show_rc6p_ms(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); u32 rc6p_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6p); - return snprintf(buf, PAGE_SIZE, "%u\n", rc6p_residency); + return sysfs_emit(buf, "%u\n", rc6p_residency); } static ssize_t @@ -96,7 +96,7 @@ show_rc6pp_ms(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); u32 rc6pp_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6pp); - return snprintf(buf, PAGE_SIZE, "%u\n", rc6pp_residency); + return sysfs_emit(buf, "%u\n", rc6pp_residency); } static ssize_t @@ -104,7 +104,7 @@ show_media_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); u32 rc6_residency = calc_residency(dev_priv, VLV_GT_MEDIA_RC6); - return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency); + return sysfs_emit(buf, "%u\n", rc6_residency); } static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL); @@ -263,8 +263,7 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev, struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); struct intel_rps *rps = &i915->gt.rps; - return snprintf(buf, PAGE_SIZE, "%d\n", - intel_rps_read_actual_frequency(rps)); + return sysfs_emit(buf, "%d\n", intel_rps_read_actual_frequency(rps)); } static ssize_t gt_cur_freq_mhz_show(struct device *kdev, @@ -273,8 +272,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev, struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); struct intel_rps *rps = &i915->gt.rps; - return snprintf(buf, PAGE_SIZE, "%d\n", - intel_gpu_freq(rps, rps->cur_freq)); + return sysfs_emit(buf, "%d\n", intel_gpu_freq(rps, rps->cur_freq)); } static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) @@ -282,8 +280,7 @@ static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribu struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); struct intel_rps *rps = &i915->gt.rps; - return snprintf(buf, PAGE_SIZE, "%d\n", - intel_gpu_freq(rps, rps->boost_freq)); + return sysfs_emit(buf, "%d\n", intel_gpu_freq(rps, rps->boost_freq)); } static ssize_t gt_boost_freq_mhz_store(struct device *kdev, @@ -323,8 +320,7 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev, struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct intel_rps *rps = &dev_priv->gt.rps; - return snprintf(buf, PAGE_SIZE, "%d\n", - intel_gpu_freq(rps, rps->efficient_freq)); + return sysfs_emit(buf, "%d\n",
[PATCH] drm: sysfs: convert sysfs snprintf to sysfs_emit
From: Xuezhi Zhang Fix the following coccicheck warning: drivers/gpu/drm/drm_sysfs.c:172:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/drm_sysfs.c:185:8-16: WARNING: use scnprintf or sprintf drivers/gpu/drm/drm_sysfs.c:159:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Xuezhi Zhang --- drivers/gpu/drm/drm_sysfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index f0336c804..13142fd9d 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -156,7 +156,7 @@ static ssize_t status_show(struct device *device, status = READ_ONCE(connector->status); - return snprintf(buf, PAGE_SIZE, "%s\n", + return sysfs_emit(buf, "%s\n", drm_get_connector_status_name(status)); } @@ -169,7 +169,7 @@ static ssize_t dpms_show(struct device *device, dpms = READ_ONCE(connector->dpms); - return snprintf(buf, PAGE_SIZE, "%s\n", + return sysfs_emit(buf, "%s\n", drm_get_dpms_name(dpms)); } @@ -182,7 +182,7 @@ static ssize_t enabled_show(struct device *device, enabled = READ_ONCE(connector->encoder); - return snprintf(buf, PAGE_SIZE, enabled ? "enabled\n" : "disabled\n"); + return sysfs_emit(buf, enabled ? "enabled\n" : "disabled\n"); } static ssize_t edid_show(struct file *filp, struct kobject *kobj, -- 2.25.1
[PATCH] staging: fbtft: convert sysfs snprintf to sysfs_emit
From: Xuezhi Zhang Fix the following coccicheck warning: drivers/staging/fbtft//fbtft-sysfs.c:202:8-16: WARNING: use scnprintf or sprintf Signed-off-by: Xuezhi Zhang --- drivers/staging/fbtft/fbtft-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fbtft-sysfs.c b/drivers/staging/fbtft/fbtft-sysfs.c index 26e52cc2d..39e8d2806 100644 --- a/drivers/staging/fbtft/fbtft-sysfs.c +++ b/drivers/staging/fbtft/fbtft-sysfs.c @@ -199,7 +199,7 @@ static ssize_t show_debug(struct device *device, struct fb_info *fb_info = dev_get_drvdata(device); struct fbtft_par *par = fb_info->par; - return snprintf(buf, PAGE_SIZE, "%lu\n", par->debug); + return sysfs_emit(buf, "%lu\n", par->debug); } static struct device_attribute debug_device_attr = -- 2.25.1
[PATCH] staging: fbtft: change snprintf() to scnprintf()
From: Xuezhi Zhang show() must not use snprintf() when formatting the value to be returned to user space. Signed-off-by: Xuezhi Zhang --- drivers/staging/fbtft/fbtft-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fbtft-sysfs.c b/drivers/staging/fbtft/fbtft-sysfs.c index 26e52cc2de64..7df92db648d6 100644 --- a/drivers/staging/fbtft/fbtft-sysfs.c +++ b/drivers/staging/fbtft/fbtft-sysfs.c @@ -199,7 +199,7 @@ static ssize_t show_debug(struct device *device, struct fb_info *fb_info = dev_get_drvdata(device); struct fbtft_par *par = fb_info->par; - return snprintf(buf, PAGE_SIZE, "%lu\n", par->debug); + return scnprintf(buf, PAGE_SIZE, "%lu\n", par->debug); } static struct device_attribute debug_device_attr = -- 2.25.1
[PATCH v4 1/2] drm/tiny: add support for Waveshare 2inch LCD module
otation); + if (ret) + return ret; + + drm_mode_config_reset(drm); + + ret = drm_dev_register(drm, 0); + if (ret) + return ret; + + spi_set_drvdata(spi, drm); + + drm_fbdev_generic_setup(drm, 0); + + return 0; +} + +static int st7789v_remove(struct spi_device *spi) +{ + struct drm_device *drm = spi_get_drvdata(spi); + + drm_dev_unplug(drm); + drm_atomic_helper_shutdown(drm); + + return 0; +} + +static void st7789v_shutdown(struct spi_device *spi) +{ + drm_atomic_helper_shutdown(spi_get_drvdata(spi)); +} + +static struct spi_driver st7789v_spi_driver = { + .driver = { + .name = "st7789v-dbi", + .of_match_table = st7789v_of_match, + }, + .id_table = st7789v_id, + .probe = st7789v_probe, + .remove = st7789v_remove, + .shutdown = st7789v_shutdown, +}; +module_spi_driver(st7789v_spi_driver); + +MODULE_DESCRIPTION("Sitronix ST7789V DRM driver"); +MODULE_AUTHOR("Carlis "); +MODULE_LICENSE("GPL"); -- 2.25.1
[PATCH v4 2/2] dt-bindings: display: sitronix,st7789v-dbi: Add Waveshare 2inch LCD module
From: Xuezhi Zhang Document support for the Waveshare 2inch LCD module display, which is a 240x320 2" TFT display driven by a Sitronix ST7789V TFT Controller. Signed-off-by: Xuezhi Zhang --- v2:change compatible value. v3:change author name. v4:delete a maintainer. --- .../display/sitronix,st7789v-dbi.yaml | 72 +++ 1 file changed, 72 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml diff --git a/Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml b/Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml new file mode 100644 index ..79eb8f3fc25d --- /dev/null +++ b/Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/sitronix,st7789v-dbi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sitronix ST7789V Display Panels Device Tree Bindings + +maintainers: + - Xuezhi Zhang + +description: + This binding is for display panels using a Sitronix ST7789V + controller in SPI mode. + +allOf: + - $ref: panel/panel-common.yaml# + +properties: + compatible: +oneOf: + - description: + Waveshare 2" 240x320 Color TFT LCD +items: + - enum: + - waveshare,ws2inch + - const: sitronix,st7789v-dbi + + spi-max-frequency: +maximum: 3200 + + dc-gpios: +maxItems: 1 +description: Display data/command selection (D/CX) + + backlight: true + reg: true + reset-gpios: true + rotation: true + +required: + - compatible + - reg + - dc-gpios + - reset-gpios + +additionalProperties: false + +examples: + - | +#include + +backlight: backlight { +compatible = "gpio-backlight"; +gpios = <&gpio 18 GPIO_ACTIVE_HIGH>; +}; + +spi { +#address-cells = <1>; +#size-cells = <0>; + +display@0{ +compatible = "waveshare,ws2inch", "sitronix,st7789v-dbi"; +reg = <0>; +spi-max-frequency = <3200>; +dc-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; +reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; +rotation = <270>; +}; +}; + +... -- 2.25.1
[PATCH v4 0/2] add support for Waveshare 2inch LCD module
From: Xuezhi Zhang This patch add support for Waveshare 2inch LCD module. Xuezhi Zhang (2): drm/tiny: add support for Waveshare 2inch LCD module dt-bindings: display: sitronix,st7789v-dbi: Add Waveshare 2inch LCD module .../display/sitronix,st7789v-dbi.yaml | 72 + MAINTAINERS | 7 + drivers/gpu/drm/tiny/Kconfig | 14 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7789v.c| 269 ++ 5 files changed, 363 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml create mode 100644 drivers/gpu/drm/tiny/st7789v.c -- 2.25.1
Re: [PATCH v3 0/1] drm/tiny: add support for Waveshare 2inch LCD module
On Tue, 30 Mar 2021 09:17:19 -0500 David Lechner wrote: > On 3/30/21 3:08 AM, Carlis wrote: > > From: Xuezhi Zhang > > > > This adds a new module for the ST7789V controller with parameters > > for the Waveshare 2inch LCD module. > > > > Signed-off-by: Xuezhi Zhang > > --- > > v2:change compatible value. > > v3:change author name. > > --- > > MAINTAINERS| 8 + > > drivers/gpu/drm/tiny/Kconfig | 14 ++ > > drivers/gpu/drm/tiny/Makefile | 1 + > > drivers/gpu/drm/tiny/st7789v.c | 269 > > + 4 files changed, 292 insertions(+) > > create mode 100644 drivers/gpu/drm/tiny/st7789v.c > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > index d92f85ca831d..df25e8e0deb1 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -5769,6 +5769,14 @@ T: git > > git://anongit.freedesktop.org/drm/drm-misc F: > > Documentation/devicetree/bindings/display/sitronix,st7735r.yaml > > F: drivers/gpu/drm/tiny/st7735r.c > > +DRM DRIVER FOR SITRONIX ST7789V PANELS > > +M: David Lechner > OK, i will remove this in the next patch. > I should not be added here. I don't have one of these displays. > > > +M: Xuezhi Zhang > > +S: Maintained > > +T: git git://anongit.freedesktop.org/drm/drm-misc > > +F: > > Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml > > +F: drivers/gpu/drm/tiny/st7789v.c + > > DRM DRIVER FOR SONY ACX424AKP PANELS > > M:Linus Walleij > > S:Maintained thanks, Xuezhi Zhang
[PATCH v3 1/1] dt-bindings: display: sitronix,st7789v-dbi: Add Waveshare 2inch LCD module
From: "Xuezhi Zhang" Document support for the Waveshare 2inch LCD module display, which is a 240x320 2" TFT display driven by a Sitronix ST7789V TFT Controller. Signed-off-by: Xuezhi Zhang --- v2:change compatible name. v3:change auther name. --- .../display/sitronix,st7789v-dbi.yaml | 72 +++ 1 file changed, 72 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml diff --git a/Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml b/Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml new file mode 100644 index ..6abf82966230 --- /dev/null +++ b/Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/sitronix,st7789v-dbi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sitronix ST7789V Display Panels Device Tree Bindings + +maintainers: + - Carlis + +description: + This binding is for display panels using a Sitronix ST7789V + controller in SPI mode. + +allOf: + - $ref: panel/panel-common.yaml# + +properties: + compatible: +oneOf: + - description: + Waveshare 2" 240x320 Color TFT LCD +items: + - enum: + - waveshare,ws2inch + - const: sitronix,st7789v-dbi + + spi-max-frequency: +maximum: 3200 + + dc-gpios: +maxItems: 1 +description: Display data/command selection (D/CX) + + backlight: true + reg: true + reset-gpios: true + rotation: true + +required: + - compatible + - reg + - dc-gpios + - reset-gpios + +additionalProperties: false + +examples: + - | +#include + +backlight: backlight { +compatible = "gpio-backlight"; +gpios = <&gpio 18 GPIO_ACTIVE_HIGH>; +}; + +spi { +#address-cells = <1>; +#size-cells = <0>; + +display@0{ +compatible = "waveshare,ws2inch", "sitronix,st7789v-dbi"; +reg = <0>; +spi-max-frequency = <3200>; +dc-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; +reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; +rotation = <270>; +}; +}; + +... -- 2.25.1
[PATCH v3 0/1] drm/tiny: add support for Waveshare 2inch LCD module
otation); + if (ret) + return ret; + + drm_mode_config_reset(drm); + + ret = drm_dev_register(drm, 0); + if (ret) + return ret; + + spi_set_drvdata(spi, drm); + + drm_fbdev_generic_setup(drm, 0); + + return 0; +} + +static int st7789v_remove(struct spi_device *spi) +{ + struct drm_device *drm = spi_get_drvdata(spi); + + drm_dev_unplug(drm); + drm_atomic_helper_shutdown(drm); + + return 0; +} + +static void st7789v_shutdown(struct spi_device *spi) +{ + drm_atomic_helper_shutdown(spi_get_drvdata(spi)); +} + +static struct spi_driver st7789v_spi_driver = { + .driver = { + .name = "st7789v-dbi", + .of_match_table = st7789v_of_match, + }, + .id_table = st7789v_id, + .probe = st7789v_probe, + .remove = st7789v_remove, + .shutdown = st7789v_shutdown, +}; +module_spi_driver(st7789v_spi_driver); + +MODULE_DESCRIPTION("Sitronix ST7789V DRM driver"); +MODULE_AUTHOR("Carlis "); +MODULE_LICENSE("GPL"); -- 2.25.1
Re: [PATCH] staging: fbtft: change '16 bit' to '16-bit'
On Fri, 26 Mar 2021 15:12:07 +0100 Greg KH wrote: > On Fri, Mar 26, 2021 at 10:09:30PM +0800, Carlis wrote: > > From: "carlis.zhang_cp" > > > > Change '16 bit' to '16-bit' for a same style. > > Why? This is up to the author. > > > > > Signed-off-by: carlis.zhang_cp > > Please use a real name, not an email-alias as a name. > > thanks, > > greg k-h OK, i will undo this patch thanks, Xuezhi Zhang
Re: [PATCH v2] staging: fbtft: fix a typo
On Fri, 26 Mar 2021 14:03:34 +0100 Greg KH wrote: > On Fri, Mar 26, 2021 at 08:55:51PM +0800, Carlis wrote: > > From: Xuezhi Zhang > > > > Change 'tft' to 'TFT' > > That says what you did, but not _why_ you did it. > > And this is not a "typo", as it is not misspelled and really is just > fine as-is. > > thanks, > > greg k-h Ok,i will undo this patch. thanks, Xuezhi Zhang
[PATCH] staging: fbtft: change '16 bit' to '16-bit'
From: "carlis.zhang_cp" Change '16 bit' to '16-bit' for a same style. Signed-off-by: carlis.zhang_cp --- drivers/staging/fbtft/fbtft-bus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c index 63c65dd..7040131 100644 --- a/drivers/staging/fbtft/fbtft-bus.c +++ b/drivers/staging/fbtft/fbtft-bus.c @@ -117,7 +117,7 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...) * */ -/* 16 bit pixel over 8-bit databus */ +/* 16-bit pixel over 8-bit databus */ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) { u16 *vmem16; @@ -172,7 +172,7 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) } EXPORT_SYMBOL(fbtft_write_vmem16_bus8); -/* 16 bit pixel over 9-bit SPI bus: dc + high byte, dc + low byte */ +/* 16-bit pixel over 9-bit SPI bus: dc + high byte, dc + low byte */ int fbtft_write_vmem16_bus9(struct fbtft_par *par, size_t offset, size_t len) { u8 *vmem8; @@ -228,7 +228,7 @@ int fbtft_write_vmem8_bus8(struct fbtft_par *par, size_t offset, size_t len) } EXPORT_SYMBOL(fbtft_write_vmem8_bus8); -/* 16 bit pixel over 16-bit databus */ +/* 16-bit pixel over 16-bit databus */ int fbtft_write_vmem16_bus16(struct fbtft_par *par, size_t offset, size_t len) { u16 *vmem16; -- 1.9.1
[PATCH v2] staging: fbtft: fix a typo
From: Xuezhi Zhang Change 'tft' to 'TFT' Signed-off-by: Xuezhi Zhang --- v2: use full name. drivers/staging/fbtft/fbtft-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 4f362da..44e7acb 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -775,7 +775,7 @@ void fbtft_framebuffer_release(struct fb_info *info) EXPORT_SYMBOL(fbtft_framebuffer_release); /** - * fbtft_register_framebuffer - registers a tft frame buffer device + * fbtft_register_framebuffer - registers a TFT frame buffer device * @fb_info: frame buffer info structure * * Sets SPI driverdata if needed @@ -873,7 +873,7 @@ int fbtft_register_framebuffer(struct fb_info *fb_info) EXPORT_SYMBOL(fbtft_register_framebuffer); /** - * fbtft_unregister_framebuffer - releases a tft frame buffer device + * fbtft_unregister_framebuffer - releases a TFT frame buffer device * @fb_info: frame buffer info structure * * Frees SPI driverdata if needed -- 1.9.1
Re: [PATCH] staging: fbtft: fix a typo
On Fri, 26 Mar 2021 10:33:57 +0100 Greg KH wrote: > On Fri, Mar 26, 2021 at 05:16:34PM +0800, carlis wrote: > > On Fri, 26 Mar 2021 09:37:48 +0100 > > Greg KH wrote: > > > > > On Fri, Mar 26, 2021 at 04:05:15PM +0800, Carlis wrote: > > > > From: "Carlis" > > > > > > > > Change 'tft' to 'TFT' > > > > > > Why? What is wrong with "tft"? > > > > > I think abbreviations should be capitalized. > > Why? What requires this? Many people use capital letters for abbreviations in comments, which I think is a good practice > > thanks, > > greg k-h thanks, Xuezhi Zhang
Re: [PATCH] staging: fbtft: fix a typo
On Fri, 26 Mar 2021 09:37:48 +0100 Greg KH wrote: > On Fri, Mar 26, 2021 at 04:05:15PM +0800, Carlis wrote: > > From: "Carlis" > > > > Change 'tft' to 'TFT' > > Why? What is wrong with "tft"? > I think abbreviations should be capitalized. > > > > Signed-off-by: Carlis > > Full name please. > OK, i will use my full name next patch > thanks, > > greg k-h
[PATCH] staging: fbtft: fix a typo
From: "Carlis" Change 'tft' to 'TFT' Signed-off-by: Carlis --- drivers/staging/fbtft/fbtft-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 4f362da..44e7acb 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -775,7 +775,7 @@ void fbtft_framebuffer_release(struct fb_info *info) EXPORT_SYMBOL(fbtft_framebuffer_release); /** - * fbtft_register_framebuffer - registers a tft frame buffer device + * fbtft_register_framebuffer - registers a TFT frame buffer device * @fb_info: frame buffer info structure * * Sets SPI driverdata if needed @@ -873,7 +873,7 @@ int fbtft_register_framebuffer(struct fb_info *fb_info) EXPORT_SYMBOL(fbtft_register_framebuffer); /** - * fbtft_unregister_framebuffer - releases a tft frame buffer device + * fbtft_unregister_framebuffer - releases a TFT frame buffer device * @fb_info: frame buffer info structure * * Frees SPI driverdata if needed -- 1.9.1
[PATCH v2] drm/tiny: add support for Waveshare 2inch LCD module
From: "Carlis" This adds a new module for the ST7789V controller with parameters for the Waveshare 2inch LCD module. Signed-off-by: Carlis --- v2:change compatible value. --- MAINTAINERS| 7 + drivers/gpu/drm/tiny/Kconfig | 14 ++ drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7789v.c | 269 + 4 files changed, 291 insertions(+) create mode 100644 drivers/gpu/drm/tiny/st7789v.c diff --git a/MAINTAINERS b/MAINTAINERS index d92f85ca831d..25c4ae12cecf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5769,6 +5769,13 @@ T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/sitronix,st7735r.yaml F: drivers/gpu/drm/tiny/st7735r.c +DRM DRIVER FOR SITRONIX ST7789V PANELS +M: Carlis +S: Maintained +T: git git://anongit.freedesktop.org/drm/drm-misc +F: Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml +F: drivers/gpu/drm/tiny/st7789v.c + DRM DRIVER FOR SONY ACX424AKP PANELS M: Linus Walleij S: Maintained diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 2b6414f0fa75..ac2c7fb702f0 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -131,3 +131,17 @@ config TINYDRM_ST7735R * Okaya RH128128T 1.44" 128x128 TFT If M is selected the module will be called st7735r. + +config TINYDRM_ST7789V + tristate "DRM support for Sitronix ST7789V display panels" + depends on DRM && SPI + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select DRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE + help + DRM driver for Sitronix ST7789V with one of the following + LCDs: + * Waveshare 2inch lcd module 240x320 TFT + + If M is selected the module will be called st7789v. diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile index 6ae4e9e5a35f..aa0caa2b6c16 100644 --- a/drivers/gpu/drm/tiny/Makefile +++ b/drivers/gpu/drm/tiny/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_TINYDRM_MI0283QT)+= mi0283qt.o obj-$(CONFIG_TINYDRM_REPAPER) += repaper.o obj-$(CONFIG_TINYDRM_ST7586) += st7586.o obj-$(CONFIG_TINYDRM_ST7735R) += st7735r.o +obj-$(CONFIG_TINYDRM_ST7789V) += st7789v.o diff --git a/drivers/gpu/drm/tiny/st7789v.c b/drivers/gpu/drm/tiny/st7789v.c new file mode 100644 index ..9b4bb9edba40 --- /dev/null +++ b/drivers/gpu/drm/tiny/st7789v.c @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * DRM driver for display panels connected to a Sitronix ST7789V + * display controller in SPI mode. + * + * Copyright 2017 David Lechner + * Copyright (C) 2019 Glider bvba + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define ST7789V_PORCTRL 0xb2 +#define ST7789V_GCTRL 0xb7 +#define ST7789V_VCOMS 0xbb +#define ST7789V_LCMCTRL 0xc0 +#define ST7789V_VDVVRHEN0xc2 +#define ST7789V_VRHS0xc3 +#define ST7789V_VDVS0xc4 +#define ST7789V_FRCTRL2 0xc6 +#define ST7789V_PWCTRL1 0xd0 +#define ST7789V_PVGAMCTRL 0xe0 +#define ST7789V_NVGAMCTRL 0xe1 + +#define ST7789V_MY BIT(7) +#define ST7789V_MX BIT(6) +#define ST7789V_MV BIT(5) +#define ST7789V_RGBBIT(3) + +struct st7789v_cfg { + const struct drm_display_mode mode; + unsigned int left_offset; + unsigned int top_offset; + unsigned int write_only:1; + unsigned int rgb:1; /* RGB (vs. BGR) */ +}; + +struct st7789v_priv { + struct mipi_dbi_dev dbidev; /* Must be first for .release() */ + const struct st7789v_cfg *cfg; +}; + +static void st7789v_pipe_enable(struct drm_simple_display_pipe *pipe, + struct drm_crtc_state *crtc_state, + struct drm_plane_state *plane_state) +{ + struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); + struct st7789v_priv *priv = container_of(dbidev, struct st7789v_priv, +dbidev); + struct mipi_dbi *dbi = &dbidev->dbi; + int ret, idx; + u8 addr_mode; + + if (!drm_dev_enter(pipe->crtc.dev, &idx)) + return; + + DRM_DEBUG_KMS("\n"); + + ret = mipi_dbi_poweron_reset(dbidev); + if (ret) + goto out_exit; + + msleep(150); + + mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); + msleep(100); + + + switch (dbidev->rotation) { + default: + addr_mode = 0; + break; + case 90: + addr_mode = ST7789V_MY | ST7789V_MV; + break; + case 180: + addr_mode = S
[PATCH v2] dt-bindings: display: sitronix,st7789v-dbi: Add Waveshare 2inch LCD module
From: "Carlis" Document support for the Waveshare 2inch LCD module display, which is a 240x320 2" TFT display driven by a Sitronix ST7789V TFT Controller. Signed-off-by: Carlis --- v2:change compatible name. --- .../display/sitronix,st7789v-dbi.yaml | 72 +++ 1 file changed, 72 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml diff --git a/Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml b/Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml new file mode 100644 index ..6abf82966230 --- /dev/null +++ b/Documentation/devicetree/bindings/display/sitronix,st7789v-dbi.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/sitronix,st7789v-dbi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sitronix ST7789V Display Panels Device Tree Bindings + +maintainers: + - Carlis + +description: + This binding is for display panels using a Sitronix ST7789V + controller in SPI mode. + +allOf: + - $ref: panel/panel-common.yaml# + +properties: + compatible: +oneOf: + - description: + Waveshare 2" 240x320 Color TFT LCD +items: + - enum: + - waveshare,ws2inch + - const: sitronix,st7789v-dbi + + spi-max-frequency: +maximum: 3200 + + dc-gpios: +maxItems: 1 +description: Display data/command selection (D/CX) + + backlight: true + reg: true + reset-gpios: true + rotation: true + +required: + - compatible + - reg + - dc-gpios + - reset-gpios + +additionalProperties: false + +examples: + - | +#include + +backlight: backlight { +compatible = "gpio-backlight"; +gpios = <&gpio 18 GPIO_ACTIVE_HIGH>; +}; + +spi { +#address-cells = <1>; +#size-cells = <0>; + +display@0{ +compatible = "waveshare,ws2inch", "sitronix,st7789v-dbi"; +reg = <0>; +spi-max-frequency = <3200>; +dc-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; +reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; +rotation = <270>; +}; +}; + +... -- 2.25.1
[PATCH] dt-bindings: display: sitronix,st7789v: Add Waveshare 2inch LCD module
From: "Carlis" Document support for the Waveshare 2inch LCD module display, which is a 240x320 2" TFT display driven by a Sitronix ST7789V TFT Controller. Signed-off-by: Carlis --- .../bindings/display/sitronix,st7789v.yaml | 72 ++ 1 file changed, 72 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/sitronix,st7789v.yaml diff --git a/Documentation/devicetree/bindings/display/sitronix,st7789v.yaml b/Documentation/devicetree/bindings/display/sitronix,st7789v.yaml new file mode 100644 index 000..8a0f21a --- /dev/null +++ b/Documentation/devicetree/bindings/display/sitronix,st7789v.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/sitronix,st7789v.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sitronix ST7789V Display Panels Device Tree Bindings + +maintainers: + - Carlis + +description: + This binding is for display panels using a Sitronix ST7789V + controller in SPI mode. + +allOf: + - $ref: panel/panel-common.yaml# + +properties: + compatible: +oneOf: + - description: + Waveshare 2" 240x320 Color TFT LCD +items: + - enum: + - waveshare,ws-2inch-lcd + - const: sitronix,st7789v + + spi-max-frequency: +maximum: 3200 + + dc-gpios: +maxItems: 1 +description: Display data/command selection (D/CX) + + backlight: true + reg: true + reset-gpios: true + rotation: true + +required: + - compatible + - reg + - dc-gpios + - reset-gpios + +additionalProperties: false + +examples: + - | +#include + +backlight: backlight { +compatible = "gpio-backlight"; +gpios = <&gpio 18 GPIO_ACTIVE_HIGH>; +}; + +spi { +#address-cells = <1>; +#size-cells = <0>; + +display@0{ +compatible = "waveshare,ws-2inch-lcd", "sitronix,st7789v"; +reg = <0>; +spi-max-frequency = <3200>; +dc-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; +reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; +rotation = <270>; +}; +}; + +... -- 1.9.1
[PATCH] drm/tiny: add support for Waveshare 2inch LCD module
From: "Carlis" This adds a new module for the ST7789V controller with parameters for the Waveshare 2inch LCD module. Signed-off-by: Carlis --- MAINTAINERS| 7 ++ drivers/gpu/drm/tiny/Kconfig | 14 +++ drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7789v.c | 269 + 4 files changed, 291 insertions(+) create mode 100644 drivers/gpu/drm/tiny/st7789v.c diff --git a/MAINTAINERS b/MAINTAINERS index d92f85c..10161be 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5769,6 +5769,13 @@ T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/sitronix,st7735r.yaml F: drivers/gpu/drm/tiny/st7735r.c +DRM DRIVER FOR SITRONIX ST7789V PANELS +M: Carlis +S: Maintained +T: git git://anongit.freedesktop.org/drm/drm-misc +F: Documentation/devicetree/bindings/display/sitronix,st7789v.yaml +F: drivers/gpu/drm/tiny/st7789v.c + DRM DRIVER FOR SONY ACX424AKP PANELS M: Linus Walleij S: Maintained diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 2b6414f..ac2c7fb 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -131,3 +131,17 @@ config TINYDRM_ST7735R * Okaya RH128128T 1.44" 128x128 TFT If M is selected the module will be called st7735r. + +config TINYDRM_ST7789V + tristate "DRM support for Sitronix ST7789V display panels" + depends on DRM && SPI + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select DRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE + help + DRM driver for Sitronix ST7789V with one of the following + LCDs: + * Waveshare 2inch lcd module 240x320 TFT + + If M is selected the module will be called st7789v. diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile index 6ae4e9e5..aa0caa2 100644 --- a/drivers/gpu/drm/tiny/Makefile +++ b/drivers/gpu/drm/tiny/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_TINYDRM_MI0283QT)+= mi0283qt.o obj-$(CONFIG_TINYDRM_REPAPER) += repaper.o obj-$(CONFIG_TINYDRM_ST7586) += st7586.o obj-$(CONFIG_TINYDRM_ST7735R) += st7735r.o +obj-$(CONFIG_TINYDRM_ST7789V) += st7789v.o diff --git a/drivers/gpu/drm/tiny/st7789v.c b/drivers/gpu/drm/tiny/st7789v.c new file mode 100644 index 000..b641857 --- /dev/null +++ b/drivers/gpu/drm/tiny/st7789v.c @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * DRM driver for display panels connected to a Sitronix ST7789V + * display controller in SPI mode. + * + * Copyright 2017 David Lechner + * Copyright (C) 2019 Glider bvba + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define ST7789V_PORCTRL 0xb2 +#define ST7789V_GCTRL 0xb7 +#define ST7789V_VCOMS 0xbb +#define ST7789V_LCMCTRL 0xc0 +#define ST7789V_VDVVRHEN0xc2 +#define ST7789V_VRHS0xc3 +#define ST7789V_VDVS0xc4 +#define ST7789V_FRCTRL2 0xc6 +#define ST7789V_PWCTRL1 0xd0 +#define ST7789V_PVGAMCTRL 0xe0 +#define ST7789V_NVGAMCTRL 0xe1 + +#define ST7789V_MY BIT(7) +#define ST7789V_MX BIT(6) +#define ST7789V_MV BIT(5) +#define ST7789V_RGBBIT(3) + +struct st7789v_cfg { + const struct drm_display_mode mode; + unsigned int left_offset; + unsigned int top_offset; + unsigned int write_only:1; + unsigned int rgb:1; /* RGB (vs. BGR) */ +}; + +struct st7789v_priv { + struct mipi_dbi_dev dbidev; /* Must be first for .release() */ + const struct st7789v_cfg *cfg; +}; + +static void st7789v_pipe_enable(struct drm_simple_display_pipe *pipe, + struct drm_crtc_state *crtc_state, + struct drm_plane_state *plane_state) +{ + struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); + struct st7789v_priv *priv = container_of(dbidev, struct st7789v_priv, +dbidev); + struct mipi_dbi *dbi = &dbidev->dbi; + int ret, idx; + u8 addr_mode; + + if (!drm_dev_enter(pipe->crtc.dev, &idx)) + return; + + DRM_DEBUG_KMS("\n"); + + ret = mipi_dbi_poweron_reset(dbidev); + if (ret) + goto out_exit; + + msleep(150); + + mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); + msleep(100); + + + switch (dbidev->rotation) { + default: + addr_mode = 0; + break; + case 90: + addr_mode = ST7789V_MY | ST7789V_MV; + break; + case 180: + addr_mode = ST7789V_MX | ST7789V_MY; + break; + case 270: +
[PATCH v15] staging: fbtft: add tearing signal detect
From: Carlis For st7789v IC, when we need continuous full screen refresh, it is best to wait for the tearing effect line signal to arrive to avoid screen tearing. Signed-off-by: Carlis --- v15: change ret value return logic in write_vmem. v14: change to define TE completion and TE irq only in st7789v. v13: change TE completion to par data struct member and add a new function to deal te gpio request, add new write_vmem function. v12: change dev_err to dev_err_probe and add space in comments start, and delete te_mutex, change te wait logic. v11: remove devm_gpio_put and change a dev_err to dev_info. v10: additional notes. v9: change pr_* to dev_*. v8: delete a log line. v7: return error value when request fail. v6: add te gpio request fail deal logic. v5: fix log print. v4: modify some code style and change te irq set function name. v3: modify author and signed-off-by name. v2: add release te gpio after irq request fail. --- drivers/staging/fbtft/fb_st7789v.c | 115 + 1 file changed, 115 insertions(+) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..abe9395 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -7,9 +7,13 @@ #include #include +#include #include #include +#include +#include #include + #include #include "fbtft.h" @@ -66,6 +70,62 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +/* 60Hz for 16.6ms, configured as 2*16.6ms */ +#define PANEL_TE_TIMEOUT_MS 33 + +static struct completion panel_te; /* completion for panel TE line */ +static int irq_te; /* Linux IRQ for LCD TE line */ + +static irqreturn_t panel_te_handler(int irq, void *data) +{ + complete(&panel_te); + return IRQ_HANDLED; +} + +/* + * init_tearing_effect_line() - init tearing effect line. + * @par: FBTFT parameter object. + * + * Return: 0 on success, or a negative error code otherwise. + */ +static int init_tearing_effect_line(struct fbtft_par *par) +{ + struct device *dev = par->info->device; + struct gpio_desc *te; + int rc, irq; + + te = gpiod_get_optional(dev, "te", GPIOD_IN); + if (IS_ERR(te)) + return dev_err_probe(dev, PTR_ERR(te), "Failed to request te GPIO\n"); + + /* if te is NULL, indicating no configuration, directly return success */ + if (!te) { + irq_te = 0; + return 0; + } + + irq = gpiod_to_irq(te); + + /* GPIO is locked as an IRQ, we may drop the reference */ + gpiod_put(te); + + if (irq < 0) + return irq; + + irq_te = irq; + init_completion(&panel_te); + + /* The effective state is high and lasts no more than 1000 microseconds */ + rc = devm_request_irq(dev, irq_te, panel_te_handler, + IRQF_TRIGGER_RISING, "TE_GPIO", par); + if (rc) + return dev_err_probe(dev, rc, "TE IRQ request failed.\n"); + + disable_irq_nosync(irq_te); + + return 0; +} + /** * init_display() - initialize the display controller * @@ -82,6 +142,12 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + + rc = init_tearing_effect_line(par); + if (rc) + return rc; + /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +203,10 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); + /* TE line output is off by default when powering on */ + if (irq_te) + write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00); + write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +215,50 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * write_vmem() - write data to display. + * @par: FBTFT parameter object. + * @offset: offset from screen_buffer. + * @len: the length of data to be writte. + * + * Return: 0 on success, or a negative error code otherwise. + */ +static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) +{ + struct device *dev = par->info->device; + int ret; + + if (irq_te) { + enable_irq(irq_te); + reinit_completion(&panel_te); + ret = wait_for_completion_timeout(&panel_te, + msecs_to_jiffies(PANEL_TE_TIMEOUT_MS)); + if (ret == 0) + dev_err(dev, "wait panel TE timeout\n"); + + disable_irq(irq_te); + } + + switch (par->pdata->display.buswidth) { + case 8: + ret = fbtft_write_vmem16_bus8(par, offset, len);
[PATCH v14] staging: fbtft: add tearing signal detect
From: Carlis For st7789v IC, when we need continuous full screen refresh, it is best to wait for the tearing effect line signal to arrive to avoid screen tearing. Signed-off-by: Carlis --- v14: change to define TE completion and TE irq only in st7789v. v13: change TE completion to par data struct member and add a new function to deal te gpio request, add new write_vmem function. v12: change dev_err to dev_err_probe and add space in comments start, and delete te_mutex, change te wait logic. v11: remove devm_gpio_put and change a dev_err to dev_info. v10: additional notes. v9: change pr_* to dev_*. v8: delete a log line. v7: return error value when request fail. v6: add te gpio request fail deal logic. v5: fix log print. v4: modify some code style and change te irq set function name. v3: modify author and signed-off-by name. v2: add release te gpio after irq request fail. --- drivers/staging/fbtft/fb_st7789v.c | 115 + 1 file changed, 115 insertions(+) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..ee8866d 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -7,9 +7,13 @@ #include #include +#include #include #include +#include +#include #include + #include #include "fbtft.h" @@ -66,6 +70,62 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +/* 60Hz for 16.6ms, configured as 2*16.6ms */ +#define PANEL_TE_TIMEOUT_MS 33 + +static struct completion panel_te; /* completion for panel TE line */ +static int irq_te; /* Linux IRQ for LCD TE line */ + +static irqreturn_t panel_te_handler(int irq, void *data) +{ + complete(&panel_te); + return IRQ_HANDLED; +} + +/* + * init_tearing_effect_line() - init tearing effect line. + * @par: FBTFT parameter object. + * + * Return: 0 on success, or a negative error code otherwise. + */ +static int init_tearing_effect_line(struct fbtft_par *par) +{ + struct device *dev = par->info->device; + struct gpio_desc *te; + int rc, irq; + + te = gpiod_get_optional(dev, "te", GPIOD_IN); + if (IS_ERR(te)) + return dev_err_probe(dev, PTR_ERR(te), "Failed to request te GPIO\n"); + + /* if te is NULL, indicating no configuration, directly return success */ + if (!te) { + irq_te = 0; + return 0; + } + + irq = gpiod_to_irq(te); + + /* GPIO is locked as an IRQ, we may drop the reference */ + gpiod_put(te); + + if (irq < 0) + return irq; + + irq_te = irq; + init_completion(&panel_te); + + /* The effective state is high and lasts no more than 1000 microseconds */ + rc = devm_request_irq(dev, irq_te, panel_te_handler, + IRQF_TRIGGER_RISING, "TE_GPIO", par); + if (rc) + return dev_err_probe(dev, rc, "TE IRQ request failed.\n"); + + disable_irq_nosync(irq_te); + + return 0; +} + /** * init_display() - initialize the display controller * @@ -82,6 +142,12 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + + rc = init_tearing_effect_line(par); + if (rc) + return rc; + /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +203,10 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); + /* TE line output is off by default when powering on */ + if (irq_te) + write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00); + write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +215,50 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * write_vmem() - write data to display. + * @par: FBTFT parameter object. + * @offset: offset from screen_buffer. + * @len: the length of data to be writte. + * + * Return: 0 on success, or a negative error code otherwise. + */ +static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) +{ + struct device *dev = par->info->device; + int ret; + + if (irq_te) { + enable_irq(irq_te); + reinit_completion(&panel_te); + ret = wait_for_completion_timeout(&panel_te, + msecs_to_jiffies(PANEL_TE_TIMEOUT_MS)); + if (ret == 0) + dev_err(dev, "wait panel TE timeout\n"); + + disable_irq(irq_te); + } + + ret = 0; + switch (par->pdata->display.buswidth) { + case 8: + ret = fbtft_write_vmem16_bus8(par, offset, len); + break; +
Re: [PATCH v12] staging: fbtft: add tearing signal detect
On Mon, 1 Feb 2021 19:40:21 +0200 Andy Shevchenko wrote: > On Sat, Jan 30, 2021 at 8:39 AM carlis wrote: > > On Fri, 29 Jan 2021 16:26:12 +0200 > > Andy Shevchenko wrote: > > > On Fri, Jan 29, 2021 at 3:56 PM carlis > > > wrote: > > > > On Fri, 29 Jan 2021 12:23:08 +0200 > > > > Andy Shevchenko wrote: > > ... > > > > > Hi, I apologize for what I said in the previous two emails. I > > > > missed one email you sent before, and now I probably understand > > > > what you meant. Here is a version I modified according to your > > > > suggestion: > > I have realized that you are mocking stuff in the generic fbtft > structure for all drivers while only a single one is going to use > that. Consider moving everything to the driver in question. > > hi, Do you mean that i define the TE completion and irq_te in the fb_st7789v.c as i did before?
[PATCH v13] staging: fbtft: add tearing signal detect
From: Carlis For st7789v IC, when we need continuous full screen refresh, it is best to wait for the tearing effect line signal to arrive to avoid screen tearing. Signed-off-by: Carlis --- v13: change TE completion to par data struct member and add a new function to deal te gpio request, move wait logic to fbtft_write_vmem16_bus8. v12: change dev_err to dev_err_probe and add space in comments start, and delete te_mutex, change te wait logic. v11: remove devm_gpio_put and change a dev_err to dev_info. v10: additional notes. v9: change pr_* to dev_*. v8: delete a log line. v7: return error value when request fail. v6: add te gpio request fail deal logic. v5: fix log print. v4: modify some code style and change te irq set function name. v3: modify author and signed-off-by name. v2: add release te gpio after irq request fail. --- drivers/staging/fbtft/fb_st7789v.c | 112 + drivers/staging/fbtft/fbtft.h | 5 ++ 2 files changed, 117 insertions(+) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..7b41bad 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -7,9 +7,13 @@ #include #include +#include #include #include +#include +#include #include + #include #include "fbtft.h" @@ -66,6 +70,59 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +/* 60Hz for 16.6ms, configured as 2*16.6ms */ +#define PANEL_TE_TIMEOUT_MS 33 + +static irqreturn_t panel_te_handler(int irq, void *data) +{ + struct fbtft_par *par = (struct fbtft_par *)data; + + complete(&par->panel_te); + return IRQ_HANDLED; +} + +/* + * init_tearing_effect_line() - init tearing effect line. + * @par: FBTFT parameter object. + * + * Return: 0 on success, or a negative error code otherwise. + */ +static int init_tearing_effect_line(struct fbtft_par *par) +{ + struct device *dev = par->info->device; + struct gpio_desc *te; + int rc, irq; + + te = gpiod_get_optional(dev, "te", GPIOD_IN); + if (IS_ERR(te)) + return dev_err_probe(dev, PTR_ERR(te), "Failed to request te GPIO\n"); + + /* if te is NULL, indicating no configuration, directly return success */ + if (!te) + return 0; + + irq = gpiod_to_irq(te); + + /* GPIO is locked as an IRQ, we may drop the reference */ + gpiod_put(te); + + if (irq < 0) + return irq; + + par->irq_te = irq; + init_completion(&par->panel_te); + + /* The effective state is high and lasts no more than 1000 microseconds */ + rc = devm_request_irq(dev, par->irq_te, panel_te_handler, + IRQF_TRIGGER_RISING, "TE_GPIO", par); + if (rc) + return dev_err_probe(dev, rc, "TE IRQ request failed.\n"); + + disable_irq_nosync(par->irq_te); + + return 0; +} + /** * init_display() - initialize the display controller * @@ -82,6 +139,12 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + + rc = init_tearing_effect_line(par); + if (rc) + return rc; + /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +200,10 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); + /* TE line output is off by default when powering on */ + if (par->irq_te) + write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00); + write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +212,50 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * write_vmem() - write data to display. + * @par: FBTFT parameter object. + * @offset: offset from screen_buffer. + * @len: the length of data to be writte. + * + * Return: 0 on success, or a negative error code otherwise. + */ +static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) +{ + struct device *dev = par->info->device; + int ret; + + if (par->irq_te) { + enable_irq(par->irq_te); + reinit_completion(&par->panel_te); + ret = wait_for_completion_timeout(&par->panel_te, + msecs_to_jiffies(PANEL_TE_TIMEOUT_MS)); + if (ret == 0) + dev_err(dev, "wait panel TE timeout\n"); + + disable_irq(par->irq_te); + } + + ret = 0; + switch (par->pdata->display.buswidth) { + case 8: + ret = fbtft_write_vmem16_bus8(par, offset, len); + break; + ca
Re: [PATCH v12] staging: fbtft: add tearing signal detect
On Fri, 29 Jan 2021 16:26:12 +0200 Andy Shevchenko wrote: > On Fri, Jan 29, 2021 at 3:56 PM carlis wrote: > > On Fri, 29 Jan 2021 12:23:08 +0200 > > Andy Shevchenko wrote: > > We are almost there, I have no idea what Noralf or others are going to > say though. > > ... > > > Hi, I apologize for what I said in the previous two emails. I missed > > one email you sent before, and now I probably understand what you > > meant. Here is a version I modified according to your suggestion: > > > > From 399e7fb91d1dcba4924cd38cc8283393c80b97e4 Mon Sep 17 00:00:00 > > 2001 From: Carlis > > Date: Sun, 24 Jan 2021 22:43:21 +0800 > > Subject: [PATCH v13] staging: fbtft: add tearing signal detect > > > > For st7789v IC,when we need continuous full screen refresh, it is > > best > > Missed space after comma. > > > to wait for the tearing effect line signal arrive to avoid screen > > to arrive > > > tearing. > > ... > > > +#define PANEL_TE_TIMEOUT_MS 34 /* 60Hz for 16.6ms, configured as > > 2*16.6ms */ + > > Move comment before the definition > /* comment */ > #define DEFINITION > > Also consider to use 33 ms as closest to what you mentioned in the > comment. Or leave it with mention that you are using ceil() value. > > ... > > > +/** > > + * init_tearing_effect_line() - init tearing effect line > > > + * > > As per a few previous reviews. > Okay, I have noticed that the existing kernel-doc is written like > this, but it doesn't prevent you from avoiding this little mistake. > > > + * @par: FBTFT parameter object > > + * > > + * Return: 0 on success, or a negative error code otherwise. > > + */ > > +static int init_tearing_effect_line(struct fbtft_par *par) > > +{ > > + struct device *dev = par->info->device; > > + struct gpio_desc *te; > > + int rc; > > + > > + te = gpiod_get_optional(dev, "te", GPIOD_IN); > > + if (IS_ERR(te)) > > + return dev_err_probe(dev, PTR_ERR(te), "Failed to > > request te GPIO\n"); + > > Below is okay, but needs a comment explaining why we return a success. > > > + if (!te) > > + return 0; > > + > > + par->irq_te = gpiod_to_irq(te); > > + > > + /* GPIO is locked as an IRQ, we may drop the reference */ > > + gpiod_put(te); > > + > > + if (par->irq_te < 0) > > + return par->irq_te; > > I recommend using a temporary variable. In such a case you won't need > to specifically check for negative error code. So, something like > > int irq; > > irq = ... > > if (irq < 0) > return irq; > > ->irq_te = irq; > > > + init_completion(&par->panel_te); > > + rc = devm_request_irq(dev, par->irq_te, panel_te_handler, > > + IRQF_TRIGGER_RISING, "TE_GPIO", par); > > > > Right. Now it needs a comment explaining the choice of rising edge > type of IRQ. > > > + if (rc) > > + return dev_err_probe(dev, rc, "TE IRQ request > > failed.\n"); + > > + disable_irq_nosync(par->irq_te); > > + > > + return 0; > > +} > > ... > > > + rc = init_tearing_effect_line(par); > > > + if (rc < 0) > > Here is no need to specifically check against less than 0, > if (ret) > will work nicely. > > > + return rc; > > ... > > > + if (par->irq_te) > > + write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00); > > Do you need to call MIPI_DCS_SET_TEAR_SCANLINE in this case? > Hi, TE line output is off by default when powering on, and I use Qualcomm SDX55 chip, SPI top speed is only 50MHz, its data transmission speed( It takes about 24ms to transmit a frame) is slower than 60Hz refresh(a frame only need 16.6ms), so i think there is no need to call MIPI_DCS_SET_TEAR_SCANLINE > Alos, when there is no IRQ, shouldn't we explicitly call >write_reg(par, MIPI_DCS_SET_TEAR_OFF); > ? > > ... > > > /** > > + * st7789v_write_vmem16_bus8() - write data to display > > > + * > > Redundant. > > > + * @par: FBTFT parameter object > > + * @offset: offset from screen_buffer > > + * @len: the length of data to be written > > + * > > > + * 16 bit pixel over 8-bit databus > > Write 16-bit pi
Re: [PATCH v12] staging: fbtft: add tearing signal detect
On Thu, 28 Jan 2021 16:33:02 +0200 Andy Shevchenko wrote: > On Thu, Jan 28, 2021 at 2:58 PM Carlis wrote: > > Thanks for your contribution, my comments below. > > > From: zhangxuezhi > > You probably have to configure your Git to use the same account for > author and committer. hi,you mean like below: Carlis ? > > > For st7789v ic,when we need continuous full screen refresh, it is > > best to > > 'ic,when' -> 'IC, when' > > > wait for the TE signal arrive to avoid screen tearing > > Decode TE for people who are not familiar with the abbreviation. > > Missed period at the end of sentence. > > ... > > > #include > > #include > > #include > > +#include > > +#include > > #include > > +#include > > + > > Good, but I would rather squeeze it above to be more or less ordered, > like just after delay.h inclusion. > > > #include > > ... > > > +#define SPI_PANEL_TE_TIMEOUT 400 /* msecs */ > > Useless comment. Instead use _MS suffix in the name of constant. > Besides that please add a comment explaining why this value has been > chosen. > > ... > > > +static struct completion spi_panel_te; > > As Greg said. > > ... > > > static int init_display(struct fbtft_par *par) > > { > > + int rc; > > + struct device *dev = par->info->device; > > Keep reversed xmas tree order: > >struct device *dev = par->info->device; >int rc; > > ... > > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > > GPIOD_IN); > > No need to have it requested for all time since you use it as an IRQ > later on. The IRQ chip will call the GPIO library framework to lock a > pin as IRQ anyway. > > > + if (IS_ERR(par->gpio.te)) > > + return dev_err_probe(par->info->device, > > PTR_ERR(par->gpio.te), > > +"Failed to request te > > gpio\n"); > > > + if (par->gpio.te) { > > Instead you should probably do the following: > > int irq; > > irq = gpiod_to_irq(...); > if (irq > 0) > > > + init_completion(&spi_panel_te); > > + rc = devm_request_irq(dev, > > > + gpiod_to_irq(par->gpio.te), > > ...and here simply use irq. > > > +spi_panel_te_handler, > > IRQF_TRIGGER_RISING, > > +"TE_GPIO", par); > > > + if (IS_ERR(rc)) > > This is wrong. rc is integer no IS_ERR() is required. Ditto for > PTR_ERR(). Have you even looked for these macros implementations? > > > + return dev_err_probe(par->info->device, > > PTR_ERR(rc), > > Use your temporary variable and move... > > > +"TE request_irq > > failed.\n"); > > ...this on the previous line. > > > + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); > > Why do you call gpio_to_irq() twice? > > > > + } else { > > + dev_info(par->info->device, "%s:%d, TE gpio not > > specified\n", > > +__func__, __LINE__); > > Remove this noise (besides the fact that we don't use __file__ and > __LINE__ in messages like this. > > > + } > > Taking all together you probably need to create a helper and use it > inside init_display(), like > > static int init_tearing_effect_line(struct fbtft_par *par) > { > struct device *dev = par->info->device; > struct gpio_desc *te; > int irq, rc; > > te = gpiod_get_optional(dev, "te", GPIOD_IN); > if (IS_ERR(te)) >return dev_err_probe(dev, PTR_ERR(te), "Failed to request > te GPIO\n"); > > irq = gpiod_to_irq(te); // this value you have to save in the > driver's (per device) data structure. > > /* GPIO is locked as an IRQ, we may drop the reference */ > gpiod_put(te); > > init_completion(&spi_panel_te); // should be in the (per device) > data structure > rc = devm_request_irq(dev, irq, spi_panel_te_handler, > IRQF_TRIGGER_RISING, "TE_GPIO", par); > if (rc) > return dev_err_probe(dev, rc, "TE IRQ request > failed.\n"); disable_irq_nosync(irq); > return irq; > } > h
[PATCH v12] staging: fbtft: add tearing signal detect
From: zhangxuezhi For st7789v ic,when we need continuous full screen refresh, it is best to wait for the TE signal arrive to avoid screen tearing Signed-off-by: zhangxuezhi --- v12: change dev_err to dev_err_probe and add space in comments start, and delete te_mutex, change te wait logic v11: remove devm_gpio_put and change a dev_err to dev_info v10: additional notes v9: change pr_* to dev_* v8: delete a log line v7: return error value when request fail v6: add te gpio request fail deal logic v5: fix log print v4: modify some code style and change te irq set function name v3: modify author and signed-off-by name v2: add release te gpio after irq request fail --- drivers/staging/fbtft/fb_st7789v.c | 116 + drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 117 insertions(+) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..f08e9da 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,7 +9,11 @@ #include #include #include +#include +#include #include +#include + #include #include "fbtft.h" @@ -66,6 +70,15 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 /* msecs */ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + /** * init_display() - initialize the display controller * @@ -82,6 +95,29 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (IS_ERR(par->gpio.te)) + return dev_err_probe(par->info->device, PTR_ERR(par->gpio.te), +"Failed to request te gpio\n"); + + if (par->gpio.te) { + init_completion(&spi_panel_te); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (IS_ERR(rc)) + return dev_err_probe(par->info->device, PTR_ERR(rc), +"TE request_irq failed.\n"); + + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + } else { + dev_info(par->info->device, "%s:%d, TE gpio not specified\n", +__func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +173,10 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); + /* tearing effect line on */ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); + write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -146,6 +186,81 @@ static int init_display(struct fbtft_par *par) } /** + * st7789v_write_vmem16_bus8() - write data to display + * + * @par: FBTFT parameter object + * @offset: offset from screen_buffer + * @len: the length of data to be written + * + * 16 bit pixel over 8-bit databus + * + * Return: 0 on success, < 0 if error occurred. + */ + +static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + if (par->gpio.te) { + enable_irq(gpiod_to_irq(par->gpio.te)); + reinit_completion(&spi_panel_te); + ret = wait_for_completion_timeout(&spi_panel_te, + msecs_to_jiffies(SPI_PANEL_TE_TIMEOUT)); + if (ret == 0) + dev_err(par->info->device, "wait panel TE time out\n"); + + disable_irq(gpiod_to_irq(par->gpio.te)); + } + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; +
Re: [PATCH v10] staging: fbtft: add tearing signal detect
On Thu, 28 Jan 2021 12:15:28 +0100 Geert Uytterhoeven wrote: > Hi Carlis, > > On Thu, Jan 28, 2021 at 12:03 PM carlis > wrote: > > On Thu, 28 Jan 2021 10:42:54 +0100 > > Geert Uytterhoeven wrote: > > > On Thu, Jan 28, 2021 at 7:53 AM Kari Argillander > > > wrote: > > > > On Thu, Jan 28, 2021 at 09:42:58AM +0800, carlis wrote: > > > > > On Thu, 28 Jan 2021 00:32:22 +0200 > > > > > Kari Argillander wrote: > > > > > > > #include "fbtft.h" > > > > > > > > > > > > > > #define DRVNAME "fb_st7789v" > > > > > > > @@ -66,6 +69,32 @@ enum st7789v_command { > > > > > > > #define MADCTL_MX BIT(6) /* bitmask for column address > > > > > > > order */ #define MADCTL_MY BIT(7) /* bitmask for page > > > > > > > address order */ > > > > > > > > > > > > > > +#define SPI_PANEL_TE_TIMEOUT 400 /* msecs */ > > > > > > > +static struct mutex te_mutex;/* mutex for set te gpio irq > > > > > > > status */ > > > > > > > > > > > > Space after ; > > > > > hi, i have fix it in the patch v11 > > > > > > > > > > > > > > Yeah sorry. I accidentally review wrong patch. But mostly stuff > > > > are still relevant. > > > > > > > > > > > @@ -82,6 +111,33 @@ enum st7789v_command { > > > > > > > */ > > > > > > > static int init_display(struct fbtft_par *par) > > > > > > > { > > > > > > > + int rc; > > > > > > > + struct device *dev = par->info->device; > > > > > > > + > > > > > > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", > > > > > > > 0, GPIOD_IN); > > > > > > > + if (IS_ERR(par->gpio.te)) { > > > > > > > + rc = PTR_ERR(par->gpio.te); > > > > > > > + dev_err(par->info->device, "Failed to request te > > > > > > > gpio: %d\n", rc); > > > > > > > + return rc; > > > > > > > + } > > > > > > > > > > > > You request with optinal and you still want to error out? We > > > > > > could just continue and not care about that error. User > > > > > > will be happier if device still works somehow. > > > > > > devm_gpiod_get_index_optional() returns NULL, not an error, if the > > > GPIO is not found. So if IS_ERR() is the right check. > > > > > > And checks for -EPROBE_DEFER can be handled automatically > > > by using dev_err_probe() instead of dev_err(). > > > > > hi, i fix it like below!? > > par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > > GPIOD_IN); if (IS_ERR(par->gpio.te)) { > > rc = PTR_ERR(par->gpio.te); > > dev_err_probe(par->info->device, rc, "Failed to > > request te gpio\n"); return rc; > > } > > if (par->gpio.te) { > > init_completion(&spi_panel_te); > > rc = devm_request_irq(dev, > > gpiod_to_irq(par->gpio.te), > > spi_panel_te_handler, > > IRQF_TRIGGER_RISING, "TE_GPIO", par); > > if (rc) { > > dev_err(par->info->device, "TE request_irq > > failed.\n"); return rc; > > dev_err_probe() > > > } > > > > disable_irq_nosync(gpiod_to_irq(par->gpio.te)); > > } else { > > dev_info(par->info->device, "%s:%d, TE gpio not > > specified\n", __func__, __LINE__); > > } > > Gr{oetje,eeting}s, > > Geert > hi,i will fix it like below: par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); if (IS_ERR(par->gpio.te)) return dev_err_probe(par->info->device, PTR_ERR(par->gpio.te), "Failed to request te gpio\n"); if (par->gpio.te) { init_completion(&spi_panel_te); rc = devm_request_irq(dev, gpiod_to_irq(par->gpio.te), spi_panel_te_handler, IRQF_TRIGGER_RISING, "TE_GPIO", par); if (IS_ERR(rc)) return dev_err_probe(par->info->device, PTR_ERR(rc), "TE request_irq failed.\n"); disable_irq_nosync(gpiod_to_irq(par->gpio.te)); } else { dev_info(par->info->device, "%s:%d, TE gpio not specified\n", __func__, __LINE__); } regards, zhangxuezhi
Re: [PATCH v10] staging: fbtft: add tearing signal detect
On Thu, 28 Jan 2021 10:42:54 +0100 Geert Uytterhoeven wrote: > Hi Kari, > > On Thu, Jan 28, 2021 at 7:53 AM Kari Argillander > wrote: > > On Thu, Jan 28, 2021 at 09:42:58AM +0800, carlis wrote: > > > On Thu, 28 Jan 2021 00:32:22 +0200 > > > Kari Argillander wrote: > > > > > #include "fbtft.h" > > > > > > > > > > #define DRVNAME "fb_st7789v" > > > > > @@ -66,6 +69,32 @@ enum st7789v_command { > > > > > #define MADCTL_MX BIT(6) /* bitmask for column address order > > > > > */ #define MADCTL_MY BIT(7) /* bitmask for page address order > > > > > */ > > > > > > > > > > +#define SPI_PANEL_TE_TIMEOUT 400 /* msecs */ > > > > > +static struct mutex te_mutex;/* mutex for set te gpio irq > > > > > status */ > > > > > > > > Space after ; > > > hi, i have fix it in the patch v11 > > > > > > > > Yeah sorry. I accidentally review wrong patch. But mostly stuff are > > still relevant. > > > > > > > @@ -82,6 +111,33 @@ enum st7789v_command { > > > > > */ > > > > > static int init_display(struct fbtft_par *par) > > > > > { > > > > > + int rc; > > > > > + struct device *dev = par->info->device; > > > > > + > > > > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > > > > > GPIOD_IN); > > > > > + if (IS_ERR(par->gpio.te)) { > > > > > + rc = PTR_ERR(par->gpio.te); > > > > > + dev_err(par->info->device, "Failed to request te > > > > > gpio: %d\n", rc); > > > > > + return rc; > > > > > + } > > > > > > > > You request with optinal and you still want to error out? We > > > > could just continue and not care about that error. User will be > > > > happier if device still works somehow. > > devm_gpiod_get_index_optional() returns NULL, not an error, if the > GPIO is not found. So if IS_ERR() is the right check. > > And checks for -EPROBE_DEFER can be handled automatically > by using dev_err_probe() instead of dev_err(). > hi, i fix it like below!? par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); if (IS_ERR(par->gpio.te)) { rc = PTR_ERR(par->gpio.te); dev_err_probe(par->info->device, rc, "Failed to request te gpio\n"); return rc; } if (par->gpio.te) { init_completion(&spi_panel_te); rc = devm_request_irq(dev, gpiod_to_irq(par->gpio.te), spi_panel_te_handler, IRQF_TRIGGER_RISING, "TE_GPIO", par); if (rc) { dev_err(par->info->device, "TE request_irq failed.\n"); return rc; } disable_irq_nosync(gpiod_to_irq(par->gpio.te)); } else { dev_info(par->info->device, "%s:%d, TE gpio not specified\n", __func__, __LINE__); } > > > You mean i just delete this dev_err print ?! > > > like this: > > > par->gpio.te = devm_gpiod_get_index_optional(dev, "te", > > > 0,GPIOD_IN); > > > if (IS_ERR(par->gpio.te)) > > > return PTR_ERR(par->gpio.te); > > > > Not exactly. I'm suggesting something like this. > > > > if (IS_ERR(par->gpio.te) == -EPROBE_DEFER) { > > return -EPROBE_DEFER; > > > > if (IS_ERR(par->gpio.te)) > > par-gpio.te = NULL; > > > > This like beginning of your patch series but the difference is that > > if EPROBE_DEFER then we will try again later. Any other error and > > we will just ignore TE gpio. But this is up to you what you want to > > do. To me this just seems place where this kind of logic can work. > > Gr{oetje,eeting}s, > > Geert > regards, zhangxuezhi
Re: [PATCH v10] staging: fbtft: add tearing signal detect
On Thu, 28 Jan 2021 08:52:33 +0200 Kari Argillander wrote: > On Thu, Jan 28, 2021 at 09:42:58AM +0800, carlis wrote: > > On Thu, 28 Jan 2021 00:32:22 +0200 > > Kari Argillander wrote: > > > > #include "fbtft.h" > > > > > > > > #define DRVNAME "fb_st7789v" > > > > @@ -66,6 +69,32 @@ enum st7789v_command { > > > > #define MADCTL_MX BIT(6) /* bitmask for column address order */ > > > > #define MADCTL_MY BIT(7) /* bitmask for page address order */ > > > > > > > > +#define SPI_PANEL_TE_TIMEOUT 400 /* msecs */ > > > > +static struct mutex te_mutex;/* mutex for set te gpio irq > > > > status */ > > > > > > Space after ; > > hi, i have fix it in the patch v11 > > > > > Yeah sorry. I accidentally review wrong patch. But mostly stuff are > still relevant. > > > > > @@ -82,6 +111,33 @@ enum st7789v_command { > > > > */ > > > > static int init_display(struct fbtft_par *par) > > > > { > > > > + int rc; > > > > + struct device *dev = par->info->device; > > > > + > > > > + par->gpio.te = devm_gpiod_get_index_optional(dev, > > > > "te", 0, GPIOD_IN); > > > > + if (IS_ERR(par->gpio.te)) { > > > > + rc = PTR_ERR(par->gpio.te); > > > > + dev_err(par->info->device, "Failed to request > > > > te gpio: %d\n", rc); > > > > + return rc; > > > > + } > > > > > > You request with optinal and you still want to error out? We could > > > just continue and not care about that error. User will be happier > > > if device still works somehow. > > You mean i just delete this dev_err print ?! > > like this: > > par->gpio.te = devm_gpiod_get_index_optional(dev, "te", > > 0,GPIOD_IN); > > if (IS_ERR(par->gpio.te)) > > return PTR_ERR(par->gpio.te); > > Not exactly. I'm suggesting something like this. > > if (IS_ERR(par->gpio.te) == -EPROBE_DEFER) { > return -EPROBE_DEFER; > > if (IS_ERR(par->gpio.te)) > par-gpio.te = NULL; > > This like beginning of your patch series but the difference is that if > EPROBE_DEFER then we will try again later. Any other error and we will > just ignore TE gpio. But this is up to you what you want to do. To me > this just seems place where this kind of logic can work. > > > > > + if (par->gpio.te) { > > > > + set_spi_panel_te_irq_status(par, true); > > > > + reinit_completion(&spi_panel_te); > > > > + ret = > > > > wait_for_completion_timeout(&spi_panel_te, > > > > + > > > > msecs_to_jiffies(SPI_PANEL_TE_TIMEOUT)); > > > > + if (ret == 0) > > > > > > !ret > > > > > > > + dev_err(par->info->device, > > > > "wait panel TE time out\n"); > > > > + } > > > > + ret = par->fbtftops.write(par, par->txbuf.buf, > > > > +startbyte_size + > > > > to_copy > > > > * 2); > > > > + if (par->gpio.te) > > > > + set_spi_panel_te_irq_status(par, > > > > false); > > > > + if (ret < 0) > > > > + return ret; > > > > + remain -= to_copy; > > > > + } > > > > + > > > > + return ret; > > > > > > Do we want to return something over 0? If not then this can be > > > return 0. And then you do not need to even init ret value at the > > > beginning. > > > > > > Also wait little bit like Greg sayd before sending new version. > > > Someone might nack about what I say or say something more. > > > > > hi, i copy fbtft_write_vmem16_bus8 from file fbtft_bus.c and modify > > it ,just add te wait logic, i will take more time to check this > > original function. > > It might be ok or not. You should still check. hi, i will check more carefully, now i have a new problem, Is there a way to clear the interrupt pending state before opening it again?
Re: [PATCH v10] staging: fbtft: add tearing signal detect
On Thu, 28 Jan 2021 00:32:22 +0200 Kari Argillander wrote: > On Wed, Jan 27, 2021 at 09:42:52PM +0800, Carlis wrote: > > For st7789v ic,when we need continuous full screen refresh, it is > > best to wait for the TE signal arrive to avoid screen tearing > > > diff --git a/drivers/staging/fbtft/fb_st7789v.c > > b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..cba08a8 100644 > > --- a/drivers/staging/fbtft/fb_st7789v.c > > +++ b/drivers/staging/fbtft/fb_st7789v.c > > @@ -9,9 +9,12 @@ > > #include > > #include > > #include > > +#include > > +#include > > +#include > > #include > > #include > > - > > +#include > > Space after local headers. Also this should one up so all Linux > headers are group together. You agreed? > OK,i will fix it in patch v12 tomorrow > > #include "fbtft.h" > > > > #define DRVNAME "fb_st7789v" > > @@ -66,6 +69,32 @@ enum st7789v_command { > > #define MADCTL_MX BIT(6) /* bitmask for column address order */ > > #define MADCTL_MY BIT(7) /* bitmask for page address order */ > > > > +#define SPI_PANEL_TE_TIMEOUT 400 /* msecs */ > > +static struct mutex te_mutex;/* mutex for set te gpio irq status > > */ > > Space after ; hi, i have fix it in the patch v11 > > > +static struct completion spi_panel_te; > > What if multiple displays? Is this possible for user? I will check it carefully again about this logic. > > > + > > +static irqreturn_t spi_panel_te_handler(int irq, void *data) > > +{ > > + complete(&spi_panel_te); > > + return IRQ_HANDLED; > > +} > > + > > +static void set_spi_panel_te_irq_status(struct fbtft_par *par, > > bool enable) +{ > > + static int te_irq_count; > > Same here. Maybe you can think better way and then this code would > also be cleaner. > > > + > > + mutex_lock(&te_mutex); > > So locking should be done if we really do action and not just in case. > > > + > > + if (enable) { > > + if (++te_irq_count == 1) > > + enable_irq(gpiod_to_irq(par->gpio.te)); > > + } else { > > + if (--te_irq_count == 0) > > + disable_irq(gpiod_to_irq(par->gpio.te)); > > + } > > + mutex_unlock(&te_mutex); > > +} > > + > > /** > > * init_display() - initialize the display controller > > * > > @@ -82,6 +111,33 @@ enum st7789v_command { > > */ > > static int init_display(struct fbtft_par *par) > > { > > + int rc; > > + struct device *dev = par->info->device; > > + > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > > GPIOD_IN); > > + if (IS_ERR(par->gpio.te)) { > > + rc = PTR_ERR(par->gpio.te); > > + dev_err(par->info->device, "Failed to request te > > gpio: %d\n", rc); > > + return rc; > > + } > > You request with optinal and you still want to error out? We could > just continue and not care about that error. User will be happier if > device still works somehow. You mean i just delete this dev_err print ?! like this: par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,GPIOD_IN); if (IS_ERR(par->gpio.te)) return PTR_ERR(par->gpio.te); > > > + if (par->gpio.te) { > > + init_completion(&spi_panel_te); > > + mutex_init(&te_mutex); > > + rc = devm_request_irq(dev, > > + gpiod_to_irq(par->gpio.te), > > +spi_panel_te_handler, > > IRQF_TRIGGER_RISING, > > +"TE_GPIO", par); > > + if (rc) { > > + dev_err(par->info->device, "TE request_irq > > failed.\n"); > > + devm_gpiod_put(dev, par->gpio.te); > > + return rc; > > + } > > + > > + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); > > + } else { > > + dev_info(par->info->device, "%s:%d, TE gpio not > > specified\n", > > +__func__, __LINE__); > > + } > > /* turn off sleep mode */ > > write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); > > mdelay(120); > > @@ -137,6 +193,9 @@ static int init_display(struct fbtft_par *par) > > */ > > write_reg(par, PWCTRL1, 0xA4, 0xA1); > > &
Re: [PATCH v10] staging: fbtft: add tearing signal detect
On Wed, 27 Jan 2021 16:02:35 +0100 Greg KH wrote: > On Wed, Jan 27, 2021 at 05:49:46PM +0300, Dan Carpenter wrote: > > On Wed, Jan 27, 2021 at 03:25:20PM +0100, Greg KH wrote: > > > On Wed, Jan 27, 2021 at 10:17:08PM +0800, carlis wrote: > > > > On Wed, 27 Jan 2021 15:13:05 +0100 > > > > Greg KH wrote: > > > > > > > > > On Wed, Jan 27, 2021 at 10:08:09PM +0800, carlis wrote: > > > > > > On Wed, 27 Jan 2021 14:51:55 +0100 > > > > > > Greg KH wrote: > > > > > > > > > > > > > On Wed, Jan 27, 2021 at 09:42:52PM +0800, Carlis wrote: > > > > > > > > > > > > > > > From: zhangxuezhi > > > > > > > > > > > > > > > > For st7789v ic,when we need continuous full screen > > > > > > > > refresh, it is best to wait for the TE signal arrive to > > > > > > > > avoid screen tearing > > > > > > > > > > > > > > > > Signed-off-by: zhangxuezhi > > > > > > > > > > > > > > > > > > > > > > Please slow down and wait at least a day between patch > > > > > > > submissions, there is no rush here. > > > > > > > > > > > > > > And also, ALWAYS run scripts/checkpatch.pl on your > > > > > > > submissions, so that you don't have a maintainer asking > > > > > > > you about basic problems, like are in this current patch > > > > > > > :( > > > > > > > > > > > > > > thanks, > > > > > > > > > > > > > > greg k-h > > > > > > > > > > > > hi, > > > > > > This is my first patch contribution to Linux, so some of > > > > > > the rules are not very clear .In addition, I can confirm > > > > > > that before sending patch, I check it with checkPatch.py > > > > > > every time.Thank you very much for your help > > > > > > > > > > Please read Documentation/SubmittingPatches which has a link > > > > > to the checklist and other documentation you should read. > > > > > > > > > > And I doubt you are running checkpatch on your submission, as > > > > > there is obvious coding style issues in it. If so, please > > > > > provide the output as it must be broken :( > > > > > > > > > > thanks, > > > > > > > > > > greg k-h > > > > hi, the patch v11 checkpatch.pl output is below: > > > > > > > > carlis@bf-rmsz-10:~/work/linux-kernel/linux$ > > > > ./scripts/checkpatch.pl > > > > 0001-staging-fbtft-add-tearing-signal-detect.patch total: 0 > > > > errors, 0 warnings, 0 checks, 176 lines checked > > > > > > > > 0001-staging-fbtft-add-tearing-signal-detect.patch has no > > > > obvious style problems and is ready for submission. > > > > > > Wow, my apologies! > > > > > > Andy and Joe, there's something wrong here that is missing the > > > fact that a line is being indented with spaces and not tabs in > > > the patch at > > > https://lore.kernel.org/r/1611754972-151016-1-git-send-email-zhangxuez...@gmail.com > > > > > > Any ideas what broke? > > > > > > > /*Tearing Effect Line On*/ > > > > Comments are the exception to the "no spaces at the start of a line" > > rule. I was expecting that the kbuild-bot would send a Smatch > > warning for inconsistent indenting, but comments are not counted > > there either. > > > > I'm sort of surprised that we don't have checkpatch rule about the > > missing space characters. It should be: "/* Tearing Effect Line On > > */". > > That was going to be my next question, lots of comments added in this > patch don't have spaces... > > thanks, > > greg k-h Ok,i will fix it in patch v12 tomorrow regards, zhangxuezhi
Re: [PATCH v10] staging: fbtft: add tearing signal detect
On Wed, 27 Jan 2021 15:13:05 +0100 Greg KH wrote: > On Wed, Jan 27, 2021 at 10:08:09PM +0800, carlis wrote: > > On Wed, 27 Jan 2021 14:51:55 +0100 > > Greg KH wrote: > > > > > On Wed, Jan 27, 2021 at 09:42:52PM +0800, Carlis wrote: > > > > From: zhangxuezhi > > > > > > > > For st7789v ic,when we need continuous full screen refresh, it > > > > is best to wait for the TE signal arrive to avoid screen tearing > > > > > > > > Signed-off-by: zhangxuezhi > > > > > > Please slow down and wait at least a day between patch > > > submissions, there is no rush here. > > > > > > And also, ALWAYS run scripts/checkpatch.pl on your submissions, so > > > that you don't have a maintainer asking you about basic problems, > > > like are in this current patch :( > > > > > > thanks, > > > > > > greg k-h > > > > hi, > > This is my first patch contribution to Linux, so some of the rules > > are not very clear .In addition, I can confirm that before sending > > patch, I check it with checkPatch.py every time.Thank you very much > > for your help > > Please read Documentation/SubmittingPatches which has a link to the > checklist and other documentation you should read. > > And I doubt you are running checkpatch on your submission, as there is > obvious coding style issues in it. If so, please provide the output > as it must be broken :( > > thanks, > > greg k-h hi, the patch v11 checkpatch.pl output is below: carlis@bf-rmsz-10:~/work/linux-kernel/linux$ ./scripts/checkpatch.pl 0001-staging-fbtft-add-tearing-signal-detect.patch total: 0 errors, 0 warnings, 0 checks, 176 lines checked 0001-staging-fbtft-add-tearing-signal-detect.patch has no obvious style problems and is ready for submission. regards zhangxuezhi
Re: [PATCH v10] staging: fbtft: add tearing signal detect
On Wed, 27 Jan 2021 14:51:55 +0100 Greg KH wrote: > On Wed, Jan 27, 2021 at 09:42:52PM +0800, Carlis wrote: > > From: zhangxuezhi > > > > For st7789v ic,when we need continuous full screen refresh, it is > > best to wait for the TE signal arrive to avoid screen tearing > > > > Signed-off-by: zhangxuezhi > > Please slow down and wait at least a day between patch submissions, > there is no rush here. > > And also, ALWAYS run scripts/checkpatch.pl on your submissions, so > that you don't have a maintainer asking you about basic problems, > like are in this current patch :( > > thanks, > > greg k-h hi, This is my first patch contribution to Linux, so some of the rules are not very clear .In addition, I can confirm that before sending patch, I check it with checkPatch.py every time.Thank you very much for your help regards zhangxuezhi
Re: [PATCH v9] staging: fbtft: add tearing signal detect
On Wed, 27 Jan 2021 14:47:04 +0100 Geert Uytterhoeven wrote: > Hi Carlis, > > On Wed, Jan 27, 2021 at 2:03 PM Carlis wrote: > > From: zhangxuezhi > > > > For st7789v ic,add tearing signal detect to avoid screen tearing > > > > Signed-off-by: zhangxuezhi > > --- > > v9: change pr_* to dev_* > > Thanks for the update! > > > --- a/drivers/staging/fbtft/fb_st7789v.c > > +++ b/drivers/staging/fbtft/fb_st7789v.c > > @@ -9,9 +9,12 @@ > > #include > > #include > > #include > > +#include > > +#include > > +#include > > #include > > #include > > - > > +#include > > #include "fbtft.h" > > > > #define DRVNAME "fb_st7789v" > > @@ -66,6 +69,32 @@ enum st7789v_command { > > #define MADCTL_MX BIT(6) /* bitmask for column address order */ > > #define MADCTL_MY BIT(7) /* bitmask for page address order */ > > > > +#define SPI_PANEL_TE_TIMEOUT 400 > > +static struct mutex te_mutex;/*mutex for tearing line*/ > > +static struct completion spi_panel_te; > > + > > +static irqreturn_t spi_panel_te_handler(int irq, void *data) > > +{ > > + complete(&spi_panel_te); > > + return IRQ_HANDLED; > > +} > > + > > +static void set_spi_panel_te_irq_status(struct fbtft_par *par, > > bool enable) +{ > > + static int te_irq_count; > > + > > + mutex_lock(&te_mutex); > > + > > + if (enable) { > > + if (++te_irq_count == 1) > > + enable_irq(gpiod_to_irq(par->gpio.te)); > > + } else { > > + if (--te_irq_count == 0) > > + disable_irq(gpiod_to_irq(par->gpio.te)); > > + } > > + mutex_unlock(&te_mutex); > > +} > > + > > /** > > * init_display() - initialize the display controller > > * > > @@ -82,6 +111,33 @@ enum st7789v_command { > > */ > > static int init_display(struct fbtft_par *par) > > { > > + int rc; > > + struct device *dev = par->info->device; > > + > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > > GPIOD_IN); > > + if (IS_ERR(par->gpio.te)) { > > + rc = PTR_ERR(par->gpio.te); > > + dev_err(par->info->device, "Failed to request te > > gpio: %d\n", rc); > > This also prints an error in case of -EPROBE_DEFER. > dev_err_probe()? > > > + return rc; > > + } > > + if (par->gpio.te) { > > + init_completion(&spi_panel_te); > > + mutex_init(&te_mutex); > > + rc = devm_request_irq(dev, > > + gpiod_to_irq(par->gpio.te), > > +spi_panel_te_handler, > > IRQF_TRIGGER_RISING, > > +"TE_GPIO", par); > > + if (rc) { > > + dev_err(par->info->device, "TE request_irq > > failed.\n"); > > + devm_gpiod_put(dev, par->gpio.te); > > No need to call devm_gpiod_put() here, as it's managed automatically. > > Gr{oetje,eeting}s, > > Geert > hi,i will fix in patch v11 regards zhangxuezhi1
[PATCH v11] staging: fbtft: add tearing signal detect
From: zhangxuezhi For st7789v ic,when we need continuous full screen refresh, it is best to wait for the TE signal arrive to avoid screen tearing Signed-off-by: zhangxuezhi --- v11: remove devm_gpio_put and change a dev_err to dev_info v10: additional notes v9: change pr_* to dev_* v8: delete a log line v7: return error value when request fail v6: add te gpio request fail deal logic v5: fix log print v4: modify some code style and change te irq set function name v3: modify author and signed-off-by name v2: add release te gpio after irq request fail --- drivers/staging/fbtft/fb_st7789v.c | 131 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 131 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..cfb54a4 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,32 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 /* msecs */ +static struct mutex te_mutex;/* mutex for set te gpio irq status */ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +111,32 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (IS_ERR(par->gpio.te)) { + rc = PTR_ERR(par->gpio.te); + dev_info(par->info->device, "Failed to request te gpio: %d\n", rc); + return rc; + } + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + dev_err(par->info->device, "TE request_irq failed.\n"); + return rc; + } + + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + } else { + dev_info(par->info->device, "%s:%d, TE gpio not specified\n", +__func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +192,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +203,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; +
Re: [PATCH v9] staging: fbtft: add tearing signal detect
On Wed, 27 Jan 2021 14:11:31 +0100 Greg KH wrote: > On Wed, Jan 27, 2021 at 08:57:37PM +0800, Carlis wrote: > > From: zhangxuezhi > > > > For st7789v ic,add tearing signal detect to avoid screen tearing > > I need a much better changelog description here please. > > > > > Signed-off-by: zhangxuezhi > > --- > > v9: change pr_* to dev_* > > --- > > What changed in all of your previous versions? All of them should be > listed here, right? > > > > > drivers/staging/fbtft/fb_st7789v.c | 132 > > - drivers/staging/fbtft/fbtft.h > > | 1 + 2 files changed, 132 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/staging/fbtft/fb_st7789v.c > > b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..9aa2f36 100644 > > --- a/drivers/staging/fbtft/fb_st7789v.c > > +++ b/drivers/staging/fbtft/fb_st7789v.c > > @@ -9,9 +9,12 @@ > > #include > > #include > > #include > > +#include > > +#include > > +#include > > #include > > #include > > - > > +#include > > #include "fbtft.h" > > > > #define DRVNAME "fb_st7789v" > > @@ -66,6 +69,32 @@ enum st7789v_command { > > #define MADCTL_MX BIT(6) /* bitmask for column address order */ > > #define MADCTL_MY BIT(7) /* bitmask for page address order */ > > > > +#define SPI_PANEL_TE_TIMEOUT 400 > > What is the units here? Where did this value come from? hi,the units is msecs,and i got this value from a qcom mdp spi drivers,and i will add the notes you need in the patch v10 > > > +static struct mutex te_mutex;/*mutex for tearing line*/ > > Does that look correct??? > > thanks, > > greg k-h
[PATCH v10] staging: fbtft: add tearing signal detect
From: zhangxuezhi For st7789v ic,when we need continuous full screen refresh, it is best to wait for the TE signal arrive to avoid screen tearing Signed-off-by: zhangxuezhi --- v10: additional notes v9: change pr_* to dev_* v8: delete a log line v7: return error value when request fail v6: add te gpio request fail deal logic v5: fix log print v4: modify some code style and change te irq set function name v3: modify author and signed-off-by name v2: add release te gpio after irq request fail --- drivers/staging/fbtft/fb_st7789v.c | 132 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 132 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..cba08a8 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,32 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 /* msecs */ +static struct mutex te_mutex;/* mutex for set te gpio irq status */ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +111,33 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (IS_ERR(par->gpio.te)) { + rc = PTR_ERR(par->gpio.te); + dev_err(par->info->device, "Failed to request te gpio: %d\n", rc); + return rc; + } + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + dev_err(par->info->device, "TE request_irq failed.\n"); + devm_gpiod_put(dev, par->gpio.te); + return rc; + } + + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + } else { + dev_info(par->info->device, "%s:%d, TE gpio not specified\n", +__func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +193,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +204,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; +
[PATCH v9] staging: fbtft: add tearing signal detect
From: zhangxuezhi For st7789v ic,add tearing signal detect to avoid screen tearing Signed-off-by: zhangxuezhi --- v9: change pr_* to dev_* --- drivers/staging/fbtft/fb_st7789v.c | 132 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 132 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..9aa2f36 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,32 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 +static struct mutex te_mutex;/*mutex for tearing line*/ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +111,33 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (IS_ERR(par->gpio.te)) { + rc = PTR_ERR(par->gpio.te); + dev_err(par->info->device, "Failed to request te gpio: %d\n", rc); + return rc; + } + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + dev_err(par->info->device, "TE request_irq failed.\n"); + devm_gpiod_put(dev, par->gpio.te); + return rc; + } + + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + } else { + dev_info(par->info->device, "%s:%d, TE gpio not specified\n", +__func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +193,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +204,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; + startbyte_size = 1; + } + + while (remain) { + to_copy = min(tx_array_size, remain); + dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", + to_copy, remain - to_copy); + + for (i = 0; i < to_copy; i++) + txbuf16[i] = cpu_to_be16(vmem16[i]); + + vm
[PATCH v8] fbtft: add tearing signal detect
From: zhangxuezhi For st7789v ic,add tearing signal detect to avoid screen tearing Signed-off-by: zhangxuezhi --- v8: delete a log line --- drivers/staging/fbtft/fb_st7789v.c | 132 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 132 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..de7460c 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,32 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 +static struct mutex te_mutex;/*mutex for tearing line*/ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +111,33 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (IS_ERR(par->gpio.te)) { + rc = PTR_ERR(par->gpio.te); + pr_err("Failed to request te gpio: %d\n", rc); + return rc; + } + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + pr_err("TE request_irq failed.\n"); + devm_gpiod_put(dev, par->gpio.te); + return rc; + } + + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + } else { + pr_info("%s:%d, TE gpio not specified\n", + __func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +193,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +204,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; + startbyte_size = 1; + } + + while (remain) { + to_copy = min(tx_array_size, remain); + dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", + to_copy, remain - to_copy); + + for (i = 0; i < to_copy; i++) + txbuf16[i] = cpu_to_be16(vmem16[i]); + + vmem16 = vmem16 + to_copy; + if (par->gpio.te) { +
Re: [PATCH v6] fbtft: add tearing signal detect
On Wed, 27 Jan 2021 11:59:51 +0300 Dan Carpenter wrote: > On Wed, Jan 27, 2021 at 03:28:22PM +0800, Carlis wrote: > > static int init_display(struct fbtft_par *par) > > { > > + int rc; > > + struct device *dev = par->info->device; > > + > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > > GPIOD_IN); > > + if (IS_ERR(par->gpio.te)) { > > + rc = PTR_ERR(par->gpio.te); > > + pr_err("Failed to request te gpio: %d\n", rc); > > + par->gpio.te = NULL; > > + } > > + if (par->gpio.te) { > > + init_completion(&spi_panel_te); > > + mutex_init(&te_mutex); > > + rc = devm_request_irq(dev, > > + gpiod_to_irq(par->gpio.te), > > +spi_panel_te_handler, > > IRQF_TRIGGER_RISING, > > +"TE_GPIO", par); > > + if (rc) { > > + pr_err("TE request_irq failed.\n"); > > + devm_gpiod_put(dev, par->gpio.te); > > + par->gpio.te = NULL; > > + } else { > > + > > disable_irq_nosync(gpiod_to_irq(par->gpio.te)); > > + pr_info("TE request_irq completion.\n"); > > #SadFaceEmoji > > > + } > > + } else { > > + pr_info("%s:%d, TE gpio not specified\n", > > + __func__, __LINE__); > > + } > > regards, > dan carpenter > Sorry,i will delete this log in patch v8 regards zhangxuezhi
[PATCH v7] fbtft: add tearing signal detect
From: zhangxuezhi For st7789v ic,add tearing signal detect to avoid screen tearing Signed-off-by: zhangxuezhi --- v7: request fail to return error value --- drivers/staging/fbtft/fb_st7789v.c | 133 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..c964cc1 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,32 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 +static struct mutex te_mutex;/*mutex for tearing line*/ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +111,34 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (IS_ERR(par->gpio.te)) { + rc = PTR_ERR(par->gpio.te); + pr_err("Failed to request te gpio: %d\n", rc); + return rc; + } + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + pr_err("TE request_irq failed.\n"); + devm_gpiod_put(dev, par->gpio.te); + return rc; + } + + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + pr_info("TE request_irq completion.\n"); + } else { + pr_info("%s:%d, TE gpio not specified\n", + __func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +194,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +205,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; + startbyte_size = 1; + } + + while (remain) { + to_copy = min(tx_array_size, remain); + dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", + to_copy, remain - to_copy); + + for (i = 0; i < to_copy; i++) + txbuf16[i] = cpu_to_be16(vmem16[i]); + +
Re: [PATCH v6] fbtft: add tearing signal detect
On Wed, 27 Jan 2021 10:00:13 +0100 Geert Uytterhoeven wrote: > Hi Carlis, > > On Wed, Jan 27, 2021 at 9:52 AM Carlis wrote: > > From: zhangxuezhi > > > > For st7789v ic,add tearing signal detect to avoid screen tearing > > > > Signed-off-by: zhangxuezhi > > Thanks for your patch! > > > --- a/drivers/staging/fbtft/fb_st7789v.c > > +++ b/drivers/staging/fbtft/fb_st7789v.c > > > @@ -82,6 +111,34 @@ enum st7789v_command { > > */ > > static int init_display(struct fbtft_par *par) > > { > > + int rc; > > + struct device *dev = par->info->device; > > + > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > > GPIOD_IN); > > + if (IS_ERR(par->gpio.te)) { > > + rc = PTR_ERR(par->gpio.te); > > + pr_err("Failed to request te gpio: %d\n", rc); > > + par->gpio.te = NULL; > > Errors (e.g. -EPROBE_DEFER) should be propagated upstream, > not ignored. > > > + } > > + if (par->gpio.te) { > > + init_completion(&spi_panel_te); > > + mutex_init(&te_mutex); > > + rc = devm_request_irq(dev, > > + gpiod_to_irq(par->gpio.te), > > +spi_panel_te_handler, > > IRQF_TRIGGER_RISING, > > +"TE_GPIO", par); > > + if (rc) { > > + pr_err("TE request_irq failed.\n"); > > + devm_gpiod_put(dev, par->gpio.te); > > + par->gpio.te = NULL; > > Errors (e.g. -EPROBE_DEFER) should be propagated upstream, > not ignored. > > > + } else { > > + > > disable_irq_nosync(gpiod_to_irq(par->gpio.te)); > > + pr_info("TE request_irq completion.\n"); > > + } > > + } else { > > + pr_info("%s:%d, TE gpio not specified\n", > > + __func__, __LINE__); > > + } > > /* turn off sleep mode */ > > write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); > > mdelay(120); > > Gr{oetje,eeting}s, > > Geert > hi,i will fix in the patch v7
[PATCH v6] fbtft: add tearing signal detect
From: zhangxuezhi For st7789v ic,add tearing signal detect to avoid screen tearing Signed-off-by: zhangxuezhi --- v6: add te gpio request fail deal logic --- drivers/staging/fbtft/fb_st7789v.c | 133 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..777391e 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,32 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 +static struct mutex te_mutex;/*mutex for tearing line*/ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +111,34 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (IS_ERR(par->gpio.te)) { + rc = PTR_ERR(par->gpio.te); + pr_err("Failed to request te gpio: %d\n", rc); + par->gpio.te = NULL; + } + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + pr_err("TE request_irq failed.\n"); + devm_gpiod_put(dev, par->gpio.te); + par->gpio.te = NULL; + } else { + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + pr_info("TE request_irq completion.\n"); + } + } else { + pr_info("%s:%d, TE gpio not specified\n", + __func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +194,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +205,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; + startbyte_size = 1; + } + + while (remain) { + to_copy = min(tx_array_size, remain); + dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", + to_copy, remain - to_copy); + + for (i = 0; i < to_copy; i++) +
Re: [PATCH v5] fbtft: add tearing signal detect
On Wed, 27 Jan 2021 08:45:23 +0300 Dan Carpenter wrote: > On Wed, Jan 27, 2021 at 09:32:20AM +0800, Carlis wrote: > > @@ -82,6 +111,29 @@ enum st7789v_command { > > */ > > static int init_display(struct fbtft_par *par) > > { > > + int rc; > > + struct device *dev = par->info->device; > > + > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > > GPIOD_IN); > > + if (par->gpio.te) { > > + init_completion(&spi_panel_te); > > + mutex_init(&te_mutex); > > + rc = devm_request_irq(dev, > > + gpiod_to_irq(par->gpio.te), > > +spi_panel_te_handler, > > IRQF_TRIGGER_RISING, > > +"TE_GPIO", par); > > + if (rc) { > > + pr_err("TE request_irq failed.\n"); > > + devm_gpiod_put(dev, par->gpio.te); > > + par->gpio.te = NULL; > > + } else { > > + > > disable_irq_nosync(gpiod_to_irq(par->gpio.te)); > > + pr_info("TE request_irq completion.\n"); > > + } > > + } else { > > + pr_info("%s:%d, TE gpio not specified\n", > > + __func__, __LINE__); > > + } > > I'm sorry that I was not clear before. This code will crash if > devm_gpiod_get_index_optional() returns an error. You *NEED* to check > for error pointers and return the error code. Write it exactly like > this: > > par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > GPIOD_IN); if (IS_ERR(par->gpio.te)) > return PTR_ERR(par->gpio.te); > > if (par->gpio.te) { > init_completion(&spi_panel_te); > > > regards, > dan carpenter > hi,i will fix it like below: par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); if (IS_ERR(par->gpio.te)) { rc = PTR_ERR(par->gpio.te); pr_err("Failed to request te gpio: %d\n", rc); par->gpio.te = NULL; } if (par->gpio.te) { init_completion(&spi_panel_te); mutex_init(&te_mutex); rc = devm_request_irq(dev, gpiod_to_irq(par->gpio.te), spi_panel_te_handler, IRQF_TRIGGER_RISING, "TE_GPIO", par); if (rc) { pr_err("TE request_irq failed.\n"); devm_gpiod_put(dev, par->gpio.te); par->gpio.te = NULL; } else { disable_irq_nosync(gpiod_to_irq(par->gpio.te)); pr_info("TE request_irq completion.\n"); } } else { pr_info("%s:%d, TE gpio not specified\n", __func__, __LINE__); } regards, zhangxuezhi
[PATCH v5] fbtft: add tearing signal detect
From: zhangxuezhi For st7789v ic,add tearing signal detect to avoid screen tearing Signed-off-by: zhangxuezhi --- v5:fix log print --- drivers/staging/fbtft/fb_st7789v.c | 128 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 128 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..ab10235 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,32 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 +static struct mutex te_mutex;/*mutex for tearing line*/ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +111,29 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + pr_err("TE request_irq failed.\n"); + devm_gpiod_put(dev, par->gpio.te); + par->gpio.te = NULL; + } else { + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + pr_info("TE request_irq completion.\n"); + } + } else { + pr_info("%s:%d, TE gpio not specified\n", + __func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +189,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +200,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; + startbyte_size = 1; + } + + while (remain) { + to_copy = min(tx_array_size, remain); + dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", + to_copy, remain - to_copy); + + for (i = 0; i < to_copy; i++) + txbuf16[i] = cpu_to_be16(vmem16[i]); + + vmem16 = vmem16 + to_copy; + if (par->gpio.te) { + set_spi_panel_te_irq_status(par, true); +
Re: [PATCH v4] fbtft: add tearing signal detect
On Tue, 26 Jan 2021 20:51:41 +0300 Dan Carpenter wrote: > On Tue, Jan 26, 2021 at 08:40:35PM +0800, Carlis wrote: > > @@ -82,6 +111,29 @@ enum st7789v_command { > > */ > > static int init_display(struct fbtft_par *par) > > { > > + int rc; > > + struct device *dev = par->info->device; > > + > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > > GPIOD_IN); > > + if (par->gpio.te) { > > I explained in my earlier review that devm_gpiod_get_index_optional() > can return error pointers... There was quite a bit of detail about > how to handle this correctly in my earlier review, but I think you > might not have noticed it. Please read it again. > > > + init_completion(&spi_panel_te); > > + mutex_init(&te_mutex); > > + rc = devm_request_irq(dev, > > + gpiod_to_irq(par->gpio.te), > > +spi_panel_te_handler, > > IRQF_TRIGGER_RISING, > > +"TE_GPIO", par); > > + if (rc) { > > + pr_err("TE request_irq failed.\n"); > > + devm_gpiod_put(dev, par->gpio.te); > > + par->gpio.te = NULL; > > + } else { > > + > > disable_irq_nosync(gpiod_to_irq(par->gpio.te)); > > + pr_info("TE request_irq completion.\n"); > > + } > > + } else { > > + pr_err("%s:%d, TE gpio not specified\n", > > + __func__, __LINE__); > > + } > > regards, > dan carpenter > Thank you for your correction,i will change pr_err to pr_info in next patch v5 regards, dan carpenter
Re: [PATCH] fbtft: add tearing signal detect
On Tue, 26 Jan 2021 10:54:41 +0300 Dan Carpenter wrote: > On Sun, Jan 24, 2021 at 11:35:37PM +0800, Carlis wrote: > > +static irqreturn_t spi_panel_te_handler(int irq, void *data) > > +{ > > + complete(&spi_panel_te); > > + return IRQ_HANDLED; > > +} > > + > > +static void enable_spi_panel_te_irq(struct fbtft_par *par, bool > > enable) > > It quite confused me that enable actually disables. I always feel > like it's clearer to write these as two separate functions. > > > +{ > > + static int te_irq_count; > > + > > + if (!par->gpio.te) { > > This is always checked in the caller. And it's when it's NULL that > means it's deliberate so don't print a message. > > > + pr_err("%s:%d,SPI panel TE GPIO not configured\n", > > + __func__, __LINE__); > > + return; > > + } > > + > > + mutex_lock(&te_mutex); > > + > > + if (enable) { > > + if (++te_irq_count == 1) > > + enable_irq(gpiod_to_irq(par->gpio.te)); > > + } else { > > + if (--te_irq_count == 0) > > + disable_irq(gpiod_to_irq(par->gpio.te)); > > + } > > + mutex_unlock(&te_mutex); > > +} > > + > > /** > > * init_display() - initialize the display controller > > * > > @@ -82,6 +117,28 @@ enum st7789v_command { > > */ > > static int init_display(struct fbtft_par *par) > > { > > + int rc; > > + struct device *dev = par->info->device; > > + > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > > GPIOD_IN); > > + if (par->gpio.te) { > > devm_gpiod_get_index_optional() can return NULL or error pointers. If > it returns NULL then don't print an error message. NULL reports are > deliberate. > > par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, > GPIOD_IN); if (IS_ERR(par->gpio.te)) { > pr_err("%s:%d, TE gpio not specified\n", __func__, > __LINE__); return PTR_ERR(par->gpio.te); > } > > if (par->gpio.te) { > > > > + init_completion(&spi_panel_te); > > + mutex_init(&te_mutex); > > + rc = devm_request_irq(dev, > > + gpiod_to_irq(par->gpio.te), > > +spi_panel_te_handler, > > IRQF_TRIGGER_RISING, > > +"TE_GPIO", par); > > + if (rc) { > > + pr_err("TE request_irq failed.\n"); > > + par->gpio.te = NULL; > > + } else { > > + > > disable_irq_nosync(gpiod_to_irq(par->gpio.te)); > > + pr_err("TE request_irq completion.\n"); > > Why is this printing an error message if devm_request_irq() succeeds? > > > + } > > + } else { > > + pr_err("%s:%d, TE gpio not specified\n", > > + __func__, __LINE__); > > + } > > /* turn off sleep mode */ > > write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); > > mdelay(120); > > @@ -137,6 +194,9 @@ static int init_display(struct fbtft_par *par) > > */ > > write_reg(par, PWCTRL1, 0xA4, 0xA1); > > > > +/*Tearing Effect Line On*/ > > + if (par->gpio.te) > > + write_reg(par, 0x35, 0x00); > > write_reg(par, MIPI_DCS_SET_DISPLAY_ON); > > > > if (HSD20_IPS) > > @@ -145,6 +205,76 @@ static int init_display(struct fbtft_par *par) > > return 0; > > } > > > > +/* > > + * > > + * int (*write_vmem)(struct fbtft_par *par); > > + * > > + > > */ > > + +/* 16 bit pixel over 8-bit databus */ > > +int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t > > offset, size_t len) +{ > > + u16 *vmem16; > > + __be16 *txbuf16 = par->txbuf.buf; > > + size_t remain; > > + size_t to_copy; > > + size_t tx_array_size; > > + int i; > > + int rc, ret = 0; > > Delete one of these "rc" or "rec" variables. > > > + size_t startbyte_size = 0; > > + > > + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v > > ---%s(offset=%zu, len=%zu)\n", > > +
Re: [PATCH v2] fbtft: add tearing signal detect
On Tue, 26 Jan 2021 11:17:45 +0300 Dan Carpenter wrote: > On Mon, Jan 25, 2021 at 04:44:12PM +0800, Carlis wrote: > > From: "carlis.zhang_cp" > > I was really expecting that you would fix this and Signed-off-by as > well. > > regards, > dan carpenter > I have fix this in patch v3 > regards, > zhangxuezhi
[PATCH v4] fbtft: add tearing signal detect
From: zhangxuezhi For st7789v ic,add tearing signal detect to avoid screen tearing Signed-off-by: zhangxuezhi --- v4:modify some code style and change te irq set function name --- drivers/staging/fbtft/fb_st7789v.c | 128 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 128 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..11a490de 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,32 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 +static struct mutex te_mutex;/*mutex for tearing line*/ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +111,29 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + pr_err("TE request_irq failed.\n"); + devm_gpiod_put(dev, par->gpio.te); + par->gpio.te = NULL; + } else { + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + pr_info("TE request_irq completion.\n"); + } + } else { + pr_err("%s:%d, TE gpio not specified\n", + __func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +189,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +200,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; + startbyte_size = 1; + } + + while (remain) { + to_copy = min(tx_array_size, remain); + dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", + to_copy, remain - to_copy); + + for (i = 0; i < to_copy; i++) + txbuf16[i] = cpu_to_be16(vmem16[i]); + + vmem16 = vmem16 + to_copy; + if (par->gpio.te) { + set_spi_panel_te_irq_st
[PATCH v3] fbtft: add tearing signal detect
From: zhangxuezhi For st7789v ic,add tearing signal detect to avoid screen tearing Signed-off-by: zhangxuezhi --- v3:modify author name --- drivers/staging/fbtft/fb_st7789v.c | 134 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 134 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..5426276 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,38 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 +static struct mutex te_mutex;/*mutex for tearing line*/ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void enable_spi_panel_te_irq(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + if (!par->gpio.te) { + pr_err("%s:%d,SPI panel TE GPIO not configured\n", + __func__, __LINE__); + return; + } + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +117,29 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + pr_err("TE request_irq failed.\n"); + devm_gpiod_put(dev, par->gpio.te); + par->gpio.te = NULL; + } else { + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + pr_info("TE request_irq completion.\n"); + } + } else { + pr_err("%s:%d, TE gpio not specified\n", + __func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +195,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +206,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int rc, ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; + startbyte_size = 1; + } + + while (remain) { + to_copy = min(tx_array_size, remain); + dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", + to_copy, remain - to_copy); + + for (i = 0; i < to_copy; i++) + txbuf16[i] = cpu_to_be16(vmem1
[PATCH v2] fbtft: add tearing signal detect
From: "carlis.zhang_cp" For st7789v ic,add tearing signal detect to avoid screen tearing Signed-off-by: carlis.zhang_cp --- v2:add release te gpio after irq request fail --- drivers/staging/fbtft/fb_st7789v.c | 134 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 134 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..5426276 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,38 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 +static struct mutex te_mutex;/*mutex for tearing line*/ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void enable_spi_panel_te_irq(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + if (!par->gpio.te) { + pr_err("%s:%d,SPI panel TE GPIO not configured\n", + __func__, __LINE__); + return; + } + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +117,29 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + pr_err("TE request_irq failed.\n"); + devm_gpiod_put(dev, par->gpio.te); + par->gpio.te = NULL; + } else { + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + pr_info("TE request_irq completion.\n"); + } + } else { + pr_err("%s:%d, TE gpio not specified\n", + __func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +195,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +206,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int rc, ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; + startbyte_size = 1; + } + + while (remain) { + to_copy = min(tx_array_size, remain); + dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", + to_copy, remain - to_copy); + + for (i = 0; i < to_copy; i++) +
[PATCH] fbtft: add tearing signal detect
From: "carlis.zhang_cp" For st7789v ic,add tearing signal detect to avoid screen tearing Signed-off-by: carlis.zhang_cp --- drivers/staging/fbtft/fb_st7789v.c | 133 - drivers/staging/fbtft/fbtft.h | 1 + 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..c687b58 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -9,9 +9,12 @@ #include #include #include +#include +#include +#include #include #include - +#include #include "fbtft.h" #define DRVNAME "fb_st7789v" @@ -66,6 +69,38 @@ enum st7789v_command { #define MADCTL_MX BIT(6) /* bitmask for column address order */ #define MADCTL_MY BIT(7) /* bitmask for page address order */ +#define SPI_PANEL_TE_TIMEOUT 400 +static struct mutex te_mutex;/*mutex for tearing line*/ +static struct completion spi_panel_te; + +static irqreturn_t spi_panel_te_handler(int irq, void *data) +{ + complete(&spi_panel_te); + return IRQ_HANDLED; +} + +static void enable_spi_panel_te_irq(struct fbtft_par *par, bool enable) +{ + static int te_irq_count; + + if (!par->gpio.te) { + pr_err("%s:%d,SPI panel TE GPIO not configured\n", + __func__, __LINE__); + return; + } + + mutex_lock(&te_mutex); + + if (enable) { + if (++te_irq_count == 1) + enable_irq(gpiod_to_irq(par->gpio.te)); + } else { + if (--te_irq_count == 0) + disable_irq(gpiod_to_irq(par->gpio.te)); + } + mutex_unlock(&te_mutex); +} + /** * init_display() - initialize the display controller * @@ -82,6 +117,28 @@ enum st7789v_command { */ static int init_display(struct fbtft_par *par) { + int rc; + struct device *dev = par->info->device; + + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN); + if (par->gpio.te) { + init_completion(&spi_panel_te); + mutex_init(&te_mutex); + rc = devm_request_irq(dev, + gpiod_to_irq(par->gpio.te), +spi_panel_te_handler, IRQF_TRIGGER_RISING, +"TE_GPIO", par); + if (rc) { + pr_err("TE request_irq failed.\n"); + par->gpio.te = NULL; + } else { + disable_irq_nosync(gpiod_to_irq(par->gpio.te)); + pr_err("TE request_irq completion.\n"); + } + } else { + pr_err("%s:%d, TE gpio not specified\n", + __func__, __LINE__); + } /* turn off sleep mode */ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); mdelay(120); @@ -137,6 +194,9 @@ static int init_display(struct fbtft_par *par) */ write_reg(par, PWCTRL1, 0xA4, 0xA1); +/*Tearing Effect Line On*/ + if (par->gpio.te) + write_reg(par, 0x35, 0x00); write_reg(par, MIPI_DCS_SET_DISPLAY_ON); if (HSD20_IPS) @@ -145,6 +205,76 @@ static int init_display(struct fbtft_par *par) return 0; } +/* + * + * int (*write_vmem)(struct fbtft_par *par); + * + */ + +/* 16 bit pixel over 8-bit databus */ +int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) +{ + u16 *vmem16; + __be16 *txbuf16 = par->txbuf.buf; + size_t remain; + size_t to_copy; + size_t tx_array_size; + int i; + int rc, ret = 0; + size_t startbyte_size = 0; + + fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, len=%zu)\n", + __func__, offset, len); + + remain = len / 2; + vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (par->gpio.dc) + gpiod_set_value(par->gpio.dc, 1); + + /* non buffered write */ + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + + /* buffered write */ + tx_array_size = par->txbuf.len / 2; + + if (par->startbyte) { + txbuf16 = par->txbuf.buf + 1; + tx_array_size -= 2; + *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; + startbyte_size = 1; + } + + while (remain) { + to_copy = min(tx_array_size, remain); + dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", + to_copy, remain - to_copy); + + for (i = 0; i < to_copy; i++) + txbuf16[i] = cpu_to_be16(vmem16[i]); + + vmem16 = vmem16 + to_copy; + if (par-