Merge commit '8f92481f41b7570445e85deeb2cb92b9f5864b55'

* commit '8f92481f41b7570445e85deeb2cb92b9f5864b55':
  media: i2c: cam-tb-setup: add rockit_en_mcu flag
  media: i2c: cam-tb-setup: add more cmdline parameters for dual camera
  media: i2c: cam-tb-setup: rk_cam_skip_frame_interval modified to rk_cam_skip
  media: i2c: cam-tb-setup: enable by VIDEO_ROCKCHIP_THUNDER_BOOT_SETUP
  mmc: debugfs: Allow more host caps to be moodified
  drm/rockchip: vop2: Request userspace reset if there is a post_buf_empty strom in non-overlay mode
  drm/rockchip: vop2: Report POST_BUF_EMPTY event to userspace
  drm/rockchip: Report drm error event to userspace
  drm/rockchip: vop2: Avoid call clk_get_rate from vop2_crtc_debugfs_dump when in interrupt context
  drm/rockchip: dw-dp: enable phy when hpd irq coming
  drm/rockchip: dw-dp: get eotf type before use it
  rockchip/drm: dw-dp: dump some info when can't get bus format
  Revert "drm/rockchip: dw-dp: reset dp controller status"
  Revert "drm/rockchip: dw-dp: filtering unexpected hotplug event."
  ARM: dts: rockchip: rk3502: Fix rockchip,temp-freq-table for cpu0_opp_table
  MALI: bifrost: Sync mali_kbase_mem_linux.c to the status in 'develop-6.1-android14'

Change-Id: I077e315e93f33196f06f1307c418de4b241ce2fa
This commit is contained in:
Tao Huang
2024-11-06 20:10:53 +08:00
12 changed files with 414 additions and 172 deletions

View File

@@ -218,6 +218,7 @@
rockchip,temp-freq-table = <
85000 1008000
100000 600000
>;
rockchip,pvtm-voltage-sel = <

View File

@@ -3814,26 +3814,6 @@ static void dw_dp_link_disable(struct dw_dp *dp)
link->train.channel_equalized = false;
}
static void dw_dp_reset(struct dw_dp *dp)
{
int val;
disable_irq(dp->irq);
regmap_update_bits(dp->regmap, DPTX_SOFT_RESET_CTRL, CONTROLLER_RESET,
FIELD_PREP(CONTROLLER_RESET, 1));
udelay(100);
regmap_update_bits(dp->regmap, DPTX_SOFT_RESET_CTRL, CONTROLLER_RESET,
FIELD_PREP(CONTROLLER_RESET, 0));
dw_dp_init(dp);
if (!dp->hpd_gpio) {
regmap_read_poll_timeout(dp->regmap, DPTX_HPD_STATUS, val,
FIELD_GET(HPD_HOT_PLUG, val), 200, 200000);
regmap_write(dp->regmap, DPTX_HPD_STATUS, HPD_HOT_PLUG);
}
enable_irq(dp->irq);
}
static void dw_dp_mst_encoder_atomic_disable(struct drm_encoder *encoder,
struct drm_atomic_state *state)
{
@@ -3886,10 +3866,8 @@ static void dw_dp_mst_encoder_atomic_disable(struct drm_encoder *encoder,
drm_dp_send_power_updown_phy(&dp->mst_mgr, mst_conn->port, false);
dw_dp_video_disable(dp, mst_enc->stream_id);
if (!dp->active_mst_links) {
if (!dp->active_mst_links)
dw_dp_link_disable(dp);
dw_dp_reset(dp);
}
pm_runtime_mark_last_busy(dp->dev);
pm_runtime_put_autosuspend(dp->dev);
@@ -4470,7 +4448,6 @@ static void dw_dp_bridge_atomic_disable(struct drm_bridge *bridge,
dw_dp_video_disable(dp, 0);
dw_dp_link_disable(dp);
bitmap_zero(dp->sdp_reg_bank, SDP_REG_BANK_SIZE);
dw_dp_reset(dp);
extcon_set_state_sync(dp->audio->extcon, EXTCON_DISP_DP, false);
dw_dp_audio_handle_plugged_change(dp->audio, false);
@@ -4605,6 +4582,8 @@ static u32 *dw_dp_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
u32 *output_fmts;
unsigned int i, j = 0;
dp->eotf_type = dw_dp_get_eotf(conn_state);
if (dp->split_mode || dp->dual_connector_split)
drm_mode_convert_to_origin_mode(&mode);
@@ -4675,6 +4654,14 @@ static u32 *dw_dp_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
*num_output_fmts = j;
if (*num_output_fmts == 0) {
dev_warn(dp->dev, "here is not satisfied the require bus format\n");
dev_info(dp->dev,
"max bpc:%d, max fmt:%x, lanes:%d, rate:%d, bpc:%d, fmt:%d, eotf:%d\n",
conn_state->max_bpc, di->color_formats, link->lanes, link->max_rate,
dp_state->bpc, dp_state->color_format, dp->eotf_type);
}
return output_fmts;
}
@@ -5009,24 +4996,30 @@ static void dw_dp_hpd_work(struct work_struct *work)
dev_dbg(dp->dev, "got hpd irq - %s\n", long_hpd ? "long" : "short");
if (!long_hpd) {
phy_power_on(dp->phy);
if (dp->is_mst) {
dw_dp_check_mst_status(dp);
phy_power_off(dp->phy);
return;
}
if (dw_dp_hpd_short_pulse(dp))
if (dw_dp_hpd_short_pulse(dp)) {
phy_power_off(dp->phy);
return;
}
if (dp->compliance.test_active &&
dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
dw_dp_phy_test(dp);
/* just do the PHY test and nothing else */
phy_power_off(dp->phy);
return;
}
ret = dw_dp_link_retrain(dp);
if (ret)
dev_warn(dp->dev, "Retrain link failed\n");
phy_power_off(dp->phy);
} else {
drm_helper_hpd_irq_event(dp->bridge.dev);
}

View File

@@ -18,7 +18,9 @@
#include <linux/component.h>
#include <linux/console.h>
#include <linux/iommu.h>
#include <linux/kthread.h>
#include <linux/of_reserved_mem.h>
#include <uapi/linux/sched/types.h>
#include <drm/drm_aperture.h>
#include <drm/drm_debugfs.h>
@@ -1370,6 +1372,28 @@ void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc)
priv->crtc_funcs[pipe] = NULL;
}
/*
* a high frequency of page faults will follow up, if
* there is a iommu fault, so it's better to limit the
* registers dump frequency to save log buffer
*
* Report no more than once every 10s, give userspace time
* to do recovery process, as for a serdes based display
* pipeline, the disable/enable time may very long.
*/
static DEFINE_RATELIMIT_STATE(fault_handler_rate, 10 * HZ, 1);
static int fault_handler_rate_limit(void)
{
return __ratelimit(&fault_handler_rate);
}
void rockchip_drm_reset_iommu_fault_handler_rate_limit(void)
{
fault_handler_rate.begin = 0;
fault_handler_rate.printed = 0;
}
static int rockchip_drm_fault_handler(struct iommu_domain *iommu,
struct device *dev,
unsigned long iova, int flags, void *arg)
@@ -1377,11 +1401,27 @@ static int rockchip_drm_fault_handler(struct iommu_domain *iommu,
struct drm_device *drm_dev = arg;
struct rockchip_drm_private *priv = drm_dev->dev_private;
struct drm_crtc *crtc;
bool handled = false;
DRM_ERROR("iommu fault handler flags: 0x%x: count: %lld\n",
flags, ++priv->iommu_fault_count);
if (!fault_handler_rate_limit())
return 0;
DRM_ERROR("iommu fault handler flags: 0x%x\n", flags);
drm_for_each_crtc(crtc, drm_dev) {
int pipe = drm_crtc_index(crtc);
/*
* Only need to call iommu fault handler once for one iommu fault
*/
if (priv->crtc_funcs[pipe] &&
priv->crtc_funcs[pipe]->iommu_fault_handler &&
!handled) {
priv->crtc_funcs[pipe]->iommu_fault_handler(crtc, iommu);
handled = true;
}
if (priv->crtc_funcs[pipe] &&
priv->crtc_funcs[pipe]->regs_dump)
priv->crtc_funcs[pipe]->regs_dump(crtc, NULL);
@@ -1784,6 +1824,111 @@ static void rockchip_drm_sysfs_fini(struct drm_device *drm_dev)
}
}
void rockchip_drm_send_error_event(struct rockchip_drm_private *priv,
enum rockchip_drm_error_event_type event)
{
struct rockchip_drm_error_event *error_event = &priv->error_event;
struct drm_event_vblank *e;
struct timespec64 tv;
unsigned long flags;
/*
* Maybe the error thread has not be created.
*/
if (IS_ERR_OR_NULL(priv->error_event.thread))
return;
spin_lock_irqsave(&error_event->lock, flags);
tv = ktime_to_timespec64(ktime_get());
e = &error_event->event;
e->base.type = event;
e->base.length = sizeof(*e);
e->tv_sec = tv.tv_sec;
e->tv_usec = tv.tv_nsec / 1000;
e->sequence++;
error_event->error_state = true;
spin_unlock_irqrestore(&error_event->lock, flags);
wake_up_interruptible_all(&error_event->wait);
}
static int rockchip_drm_error_event_thread(void *data)
{
struct drm_device *drm_dev = data;
struct rockchip_drm_private *priv = drm_dev->dev_private;
struct rockchip_drm_error_event *error_event = &priv->error_event;
struct drm_event_vblank *e;
int ret = 0;
int cnt = 0;
while (!kthread_should_stop()) {
e = &error_event->event;
error_event->error_state = false;
ret = wait_event_interruptible(error_event->wait, error_event->error_state);
if (!ret) {
sysfs_notify(&drm_dev->dev->kobj, NULL, "error_event");
drm_info(drm_dev, "rockchipdrm send_error_event_type: 0x%x, count:%d\n",
e->base.type, ++cnt);
}
}
return 0;
}
static ssize_t rockchip_drm_error_event_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
struct rockchip_drm_private *priv = drm_dev->dev_private;
struct rockchip_drm_error_event *error_event = &priv->error_event;
struct drm_event_vblank *e;
uint32_t length = sizeof(*e);
unsigned long flags;
spin_lock_irqsave(&error_event->lock, flags);
e = &error_event->event;
memcpy(buf, e, length);
spin_unlock_irqrestore(&error_event->lock, flags);
return length;
}
static DEVICE_ATTR(error_event, 0444, rockchip_drm_error_event_show, NULL);
static void rockchip_drm_error_event_init(struct drm_device *drm_dev)
{
struct rockchip_drm_private *priv = drm_dev->dev_private;
struct sched_param sched_param = { .sched_priority = MAX_RT_PRIO - 1 };
int ret;
ret = device_create_file(drm_dev->dev, &dev_attr_error_event);
if (ret) {
dev_warn(drm_dev->dev, "failed to create vcnt event file\n");
return;
}
init_waitqueue_head(&priv->error_event.wait);
spin_lock_init(&priv->error_event.lock);
priv->error_event.thread = kthread_run(rockchip_drm_error_event_thread,
drm_dev, "display-error-event-thread");
if (IS_ERR(priv->error_event.thread)) {
priv->error_event.thread = NULL;
drm_err(drm_dev, "failed to run display error_event thread\n");
} else {
sched_setscheduler(priv->error_event.thread, SCHED_FIFO, &sched_param);
drm_info(drm_dev, "run display error_event monitor\n");
}
}
static void rockchip_drm_error_event_fini(struct drm_device *drm_dev)
{
struct rockchip_drm_private *priv = drm_dev->dev_private;
if (priv->error_event.thread)
kthread_stop(priv->error_event.thread);
device_remove_file(drm_dev->dev, &dev_attr_error_event);
}
static int rockchip_drm_bind(struct device *dev)
{
struct drm_device *drm_dev;
@@ -1891,6 +2036,8 @@ static int rockchip_drm_bind(struct device *dev)
if (ret)
goto err_drm_fbdev_fini;
rockchip_drm_error_event_init(drm_dev);
return 0;
err_drm_fbdev_fini:
rockchip_drm_fbdev_fini(drm_dev);
@@ -1915,6 +2062,7 @@ static void rockchip_drm_unbind(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
rockchip_drm_error_event_fini(drm_dev);
rockchip_drm_sysfs_fini(drm_dev);
rockchip_drm_fbdev_fini(drm_dev);
drm_dev_unregister(drm_dev);

View File

@@ -349,6 +349,15 @@ struct rockchip_drm_vcnt {
int pipe;
};
struct rockchip_drm_error_event {
wait_queue_head_t wait;
struct task_struct *thread;
struct list_head event_list;
struct drm_event_vblank event;
bool error_state;
spinlock_t lock;
};
struct rockchip_logo {
dma_addr_t dma_addr;
struct drm_mm_node logo_reserved_node;
@@ -511,6 +520,7 @@ struct rockchip_crtc_funcs {
int (*crtc_set_color_bar)(struct drm_crtc *crtc, enum rockchip_color_bar_mode mode);
int (*set_aclk)(struct drm_crtc *crtc, enum rockchip_drm_vop_aclk_mode aclk_mode, struct dmcfreq_vop_info *vop_bw_info);
int (*get_crc)(struct drm_crtc *crtc);
void (*iommu_fault_handler)(struct drm_crtc *crtc, struct iommu_domain *iommu);
};
struct rockchip_dclk_pll {
@@ -558,6 +568,8 @@ struct rockchip_drm_private {
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
uint64_t iommu_fault_count;
struct rockchip_dclk_pll default_pll;
struct rockchip_dclk_pll hdmi_pll;
@@ -568,6 +580,8 @@ struct rockchip_drm_private {
struct mutex ovl_lock;
struct rockchip_drm_vcnt vcnt[ROCKCHIP_MAX_CRTC];
struct rockchip_drm_error_event error_event;
/**
* @loader_protect
* ignore restore_fbdev_mode_atomic when in logo on state
@@ -647,6 +661,9 @@ int rockchip_drm_dclk_set_rate(u32 version, struct clk *dclk, unsigned long rate
bool rockchip_drm_is_afbc(struct drm_plane *plane, u64 modifier);
bool rockchip_drm_is_rfbc(struct drm_plane *plane, u64 modifier);
const char *rockchip_drm_modifier_to_string(uint64_t modifier);
void rockchip_drm_reset_iommu_fault_handler_rate_limit(void);
void rockchip_drm_send_error_event(struct rockchip_drm_private *priv,
enum rockchip_drm_error_event_type event);
__printf(3, 4)
void rockchip_drm_dbg(const struct device *dev,

View File

@@ -25,6 +25,7 @@
#include <linux/debugfs.h>
#include <linux/fixp-arith.h>
#include <linux/jiffies.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -817,6 +818,11 @@ struct vop2_video_port {
*/
bool has_extra_layer;
/**
* @has_scale_down_layer: use layer for scale down
*/
bool has_scale_down_layer;
/**
* @crc_frame_num: calc crc frame num
*/
@@ -840,6 +846,11 @@ struct vop2_resource {
void __iomem *regs;
};
struct vop2_err_event {
u64 count;
unsigned long begin;
};
struct vop2 {
u32 version;
struct device *dev;
@@ -882,6 +893,16 @@ struct vop2 {
*/
bool skip_ref_fb;
/*
* report iommu fault event to userspace
*/
bool report_iommu_fault;
/*
* report post buf empty error event to userspace
*/
bool report_post_buf_empty;
bool loader_protect;
bool aclk_rate_reset;
@@ -962,6 +983,9 @@ struct vop2 {
unsigned long aclk_target_freq;
u32 aclk_mode_rate[ROCKCHIP_VOP_ACLK_MAX_MODE];
#endif
bool iommu_fault_in_progress;
struct vop2_err_event post_buf_empty;
/* aclk auto cs div */
u32 csu_div;
@@ -2903,6 +2927,8 @@ static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win *win,
const struct vop2_win_data *win_data = &vop2_data->win[win->win_id];
struct vop2_plane_state *vpstate = to_vop2_plane_state(pstate);
struct drm_framebuffer *fb = pstate->fb;
struct drm_crtc *crtc = pstate->crtc;
struct vop2_video_port *vp = to_vop2_video_port(crtc);
uint32_t pixel_format = fb->format->format;
const struct drm_format_info *info = drm_format_info(pixel_format);
uint8_t hsub = info->hsub;
@@ -2975,6 +3001,9 @@ static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win *win,
yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
if (yrgb_hor_scl_mode == SCALE_DOWN || yrgb_ver_scl_mode == SCALE_DOWN)
vp->has_scale_down_layer = true;
if (yrgb_hor_scl_mode == SCALE_UP)
hscl_filter_mode = win_data->hsu_filter_mode;
else
@@ -4267,6 +4296,87 @@ static int vop3_get_esmart_lb_mode(struct vop2 *vop2)
return vop2->data->esmart_lb_mode_map[0].lb_map_value;
}
static bool vop2_non_overlay_mode(struct vop2 *vop2)
{
struct vop2_video_port *vp;
int i;
bool non_ovl_mode = true;
for (i = 0; i < vop2->data->nr_vps; i++) {
vp = &vop2->vps[i];
if (vp->nr_layers > 1 || vp->has_scale_down_layer) {
non_ovl_mode = false;
break;
}
}
return non_ovl_mode;
}
/*
* POST_BUF_EMPTY will cause hundreds thousands of interrupts strom per
* second.
*/
#define POST_BUF_EMPTY_COUNT_PER_MINUTE 100
static DEFINE_RATELIMIT_STATE(post_buf_empty_handler_rate, 5 * HZ, 10);
static int vop2_post_buf_empty_handler_rate_limit(void)
{
return __ratelimit(&post_buf_empty_handler_rate);
}
static void vop2_reset_post_buf_empty_handler_rate_limit(struct vop2 *vop2)
{
vop2->post_buf_empty.begin = 0;
vop2->post_buf_empty.count = 0;
}
static void vop2_handle_post_buf_empty(struct drm_crtc *crtc)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct vop2 *vop2 = vp->vop2;
struct rockchip_drm_private *private = vop2->drm_dev->dev_private;
struct vop2_err_event *event = &vop2->post_buf_empty;
enum rockchip_drm_error_event_type type;
if (!vop2->report_post_buf_empty)
return;
/*
* No need to handle POST_BUF_EMPTY if we are in iommu fault,
* because we will try to recovery from the iommu fault handle
*/
if (vop2->iommu_fault_in_progress)
return;
if (!event->begin)
event->begin = jiffies;
if (vop2_post_buf_empty_handler_rate_limit())
event->count++;
if (time_is_before_jiffies(event->begin + 60 * HZ)) {
if (event->count >= POST_BUF_EMPTY_COUNT_PER_MINUTE) {
/*
* Request userspace disable then enable all display
* pipeline if still POST_BUF_EMPTY in non-overlay
* and non-scale mode
*/
if (vop2_non_overlay_mode(vop2))
type = ROCKCHIP_DRM_ERROR_EVENT_REQUEST_RESET;
else
type = ROCKCHIP_DRM_ERROR_EVENT_POST_BUF_EMPTY;
rockchip_drm_send_error_event(private, type);
}
DRM_DEV_ERROR(vop2->dev, "post_buf_err event count: %lld\n", event->count);
event->begin = 0;
event->count = 0;
}
}
static void vop2_initial(struct drm_crtc *crtc)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
@@ -4290,6 +4400,8 @@ static void vop2_initial(struct drm_crtc *crtc)
return;
}
vop2->aclk_current_freq = clk_get_rate(vop2->aclk);
if (vop2_soc_is_rk3566())
VOP_CTRL_SET(vop2, otp_en, 1);
@@ -4603,6 +4715,14 @@ static void vop2_disable(struct drm_crtc *crtc)
vop2_set_aclk_rate(crtc, ROCKCHIP_VOP_ACLK_RESET_MODE, NULL);
rockchip_drm_dma_detach_device(vop2->drm_dev, vop2->dev);
vop2->is_iommu_enabled = false;
vop2->iommu_fault_in_progress = false;
/*
* Reset fault handler rate limit state, so that we can
* immediately report the error event again if an error occurs
* shortly after the recovery(Disable then enable) process done.
*/
rockchip_drm_reset_iommu_fault_handler_rate_limit();
vop2_reset_post_buf_empty_handler_rate_limit(vop2);
}
if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3576)
vop2_power_off_all_pd(vop2);
@@ -7219,12 +7339,22 @@ static int vop2_crtc_debugfs_dump(struct drm_crtc *crtc, struct seq_file *s)
struct rockchip_crtc_state *state = to_rockchip_crtc_state(crtc->state);
bool interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
struct drm_plane *plane;
unsigned long aclk_rate;
DEBUG_PRINT("Video Port%d: %s\n", vp->id, crtc_state->active ? "ACTIVE" : "DISABLED");
if (!crtc_state->active)
return 0;
/*
* clk_get_rate can't run in interrupt context,
* for example, called from iommu fault handler
*/
if (!s)
aclk_rate = vop2->aclk_current_freq;
else
aclk_rate = clk_get_rate(vop2->aclk);
vop2_dump_connector_on_crtc(crtc, s);
DEBUG_PRINT("\tbus_format[%x]: %s\n", state->bus_format,
drm_get_bus_format_name(state->bus_format));
@@ -7238,7 +7368,7 @@ static int vop2_crtc_debugfs_dump(struct drm_crtc *crtc, struct seq_file *s)
mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
drm_mode_vrefresh(mode));
DEBUG_PRINT("\tdclk[%d kHz] real_dclk[%d kHz] aclk[%ld kHz] type[%x] flag[%x]\n",
mode->clock, mode->crtc_clock, clk_get_rate(vop2->aclk) / 1000,
mode->clock, mode->crtc_clock, aclk_rate / 1000,
mode->type, mode->flags);
DEBUG_PRINT("\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
mode->hsync_end, mode->htotal);
@@ -7946,6 +8076,21 @@ static int vop2_crtc_get_crc(struct drm_crtc *crtc)
return 0;
}
static void vop2_iommu_fault_handler(struct drm_crtc *crtc, struct iommu_domain *iommu)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct vop2 *vop2 = vp->vop2;
struct drm_device *drm_dev = vop2->drm_dev;
struct rockchip_drm_private *private = drm_dev->dev_private;
if (!vop2->report_iommu_fault)
return;
vop2->iommu_fault_in_progress = true;
rockchip_drm_send_error_event(private, ROCKCHIP_DRM_ERROR_EVENT_IOMMU_FAULT);
}
static const struct rockchip_crtc_funcs private_crtc_funcs = {
.loader_protect = vop2_crtc_loader_protect,
.cancel_pending_vblank = vop2_crtc_cancel_pending_vblank,
@@ -7967,6 +8112,7 @@ static const struct rockchip_crtc_funcs private_crtc_funcs = {
.crtc_set_color_bar = vop2_crtc_set_color_bar,
.set_aclk = vop2_set_aclk_rate,
.get_crc = vop2_crtc_get_crc,
.iommu_fault_handler = vop2_iommu_fault_handler,
};
static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -11259,6 +11405,8 @@ static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_stat
}
vp->hdr10_at_splice_mode = hdr10_at_splice_mode;
vp->has_scale_down_layer = false;
rockchip_drm_dbg(vop2->dev, VOP_DEBUG_OVERLAY, "vp%d: %d windows, active layers %d",
vp->id, hweight32(vp->win_mask), nr_layers);
if (nr_layers) {
@@ -12553,10 +12701,7 @@ static irqreturn_t vop2_isr(int irq, void *data)
#define ERROR_HANDLER(x) \
do { \
if (active_irqs & x##_INTR) {\
if (x##_INTR == POST_BUF_EMPTY_INTR) \
DRM_DEV_ERROR_RATELIMITED(vop2->dev, #x " irq err at vp%d\n", vp->id); \
else \
DRM_DEV_ERROR_RATELIMITED(vop2->dev, #x " irq err\n"); \
DRM_DEV_ERROR_RATELIMITED(vop2->dev, #x " irq err\n"); \
active_irqs &= ~x##_INTR; \
ret = IRQ_HANDLED; \
} \
@@ -12629,7 +12774,12 @@ static irqreturn_t vop2_isr(int irq, void *data)
ret = IRQ_HANDLED;
}
ERROR_HANDLER(POST_BUF_EMPTY);
if (active_irqs & POST_BUF_EMPTY_INTR) {
vop2_handle_post_buf_empty(crtc);
DRM_DEV_ERROR_RATELIMITED(vop2->dev, "POST_BUF_EMPTY irq err at vp%d\n", vp->id);
active_irqs &= ~POST_BUF_EMPTY_INTR;
ret = IRQ_HANDLED;
}
/* Unhandled irqs are spurious. */
if (active_irqs)
@@ -14332,6 +14482,8 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
vop2->disable_afbc_win = of_property_read_bool(dev->of_node, "disable-afbc-win");
vop2->disable_win_move = of_property_read_bool(dev->of_node, "disable-win-move");
vop2->skip_ref_fb = of_property_read_bool(dev->of_node, "skip-ref-fb");
vop2->report_iommu_fault = of_property_read_bool(dev->of_node, "rockchip,report-iommu-fault");
vop2->report_post_buf_empty = of_property_read_bool(dev->of_node, "rockchip,report-post-buf-empty");
if (!is_vop3(vop2) ||
vop2->version == VOP_VERSION_RK3528 || vop2->version == VOP_VERSION_RK3562)
vop2->merge_irq = true;

View File

@@ -11,6 +11,12 @@ config VIDEO_CAM_SLEEP_WAKEUP
help
Support for sensor sleep and wake up.
config VIDEO_ROCKCHIP_THUNDER_BOOT_SETUP
bool "Enable camera Thunderboot setup function"
depends on ROCKCHIP_THUNDER_BOOT
help
Say y if you need camera Thunderboot setup functions.
comment "IR I2C driver auto-selected by 'Autoselect ancillary drivers'"
depends on MEDIA_SUBDRV_AUTOSELECT && I2C && RC_CORE

View File

@@ -206,7 +206,7 @@ obj-$(CONFIG_VIDEO_RDACM21) += rdacm21.o
obj-$(CONFIG_VIDEO_RJ54N1) += rj54n1cb0c.o
obj-$(CONFIG_VIDEO_RK628) += rk628/
obj-$(CONFIG_VIDEO_RK_IRCUT) += rk_ircut.o
obj-$(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) += cam-tb-setup.o
obj-$(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_SETUP) += cam-tb-setup.o
obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/
obj-$(CONFIG_VIDEO_S5K3L6XX) += s5k3l6xx.o
obj-$(CONFIG_VIDEO_S5K3L8XX) += s5k3l8xx.o

View File

@@ -6,116 +6,37 @@
#include <linux/kernel.h>
#include "cam-tb-setup.h"
static u32 rk_cam_w;
static u32 rk_cam_h;
static u32 rk_cam_hdr;
static u32 rk_cam_fps;
static u32 rk_cam_skip_frame_interval;
static int __init rk_cam_w_setup(char *str)
{
int ret = 0;
unsigned long val = 0;
#define DEFINE_CAM_TB_PARAM(para) \
static u32 para; \
static int __init para##_setup(char *str) \
{ \
int ret = 0; \
unsigned long val = 0; \
ret = kstrtoul(str, 0, &val); \
if (!ret) \
para = (u32)val; \
else \
pr_err("get "#para" fail\n"); \
return 0; \
} \
u32 get_##para(void) \
{ \
return para; \
} \
EXPORT_SYMBOL(get_##para); \
__setup(#para"=", para##_setup)
ret = kstrtoul(str, 0, &val);
if (!ret)
rk_cam_w = (u32)val;
else
pr_err("get rk_cam_w fail\n");
DEFINE_CAM_TB_PARAM(rk_cam_w);
DEFINE_CAM_TB_PARAM(rk_cam_h);
DEFINE_CAM_TB_PARAM(rk_cam_hdr);
DEFINE_CAM_TB_PARAM(rk_cam_fps);
DEFINE_CAM_TB_PARAM(rk_cam1_max_fps);
DEFINE_CAM_TB_PARAM(rk_cam2_w);
DEFINE_CAM_TB_PARAM(rk_cam2_h);
DEFINE_CAM_TB_PARAM(rk_cam2_hdr);
DEFINE_CAM_TB_PARAM(rk_cam2_fps);
DEFINE_CAM_TB_PARAM(rk_cam2_max_fps);
DEFINE_CAM_TB_PARAM(rk_cam_skip);
DEFINE_CAM_TB_PARAM(rockit_en_mcu);
return 0;
}
u32 get_rk_cam_w(void)
{
return rk_cam_w;
}
EXPORT_SYMBOL(get_rk_cam_w);
static int __init rk_cam_h_setup(char *str)
{
int ret = 0;
unsigned long val = 0;
ret = kstrtoul(str, 0, &val);
if (!ret)
rk_cam_h = (u32)val;
else
pr_err("get rk_cam_h fail\n");
return 0;
}
u32 get_rk_cam_h(void)
{
return rk_cam_h;
}
EXPORT_SYMBOL(get_rk_cam_h);
static int __init rk_cam_hdr_setup(char *str)
{
int ret = 0;
unsigned long val = 0;
ret = kstrtoul(str, 0, &val);
if (!ret)
rk_cam_hdr = (u32)val;
else
pr_err("get rk_cam_hdr fail\n");
return 0;
}
u32 get_rk_cam_hdr(void)
{
return rk_cam_hdr;
}
EXPORT_SYMBOL(get_rk_cam_hdr);
static int __init __maybe_unused rk_cam_fps_setup(char *str)
{
int ret = 0;
unsigned long val = 0;
ret = kstrtoul(str, 0, &val);
if (!ret)
rk_cam_fps = (u32)val;
else
pr_err("get rk_cam_fps fail\n");
return 0;
}
u32 get_rk_cam_fps(void)
{
return rk_cam_fps;
}
EXPORT_SYMBOL(get_rk_cam_fps);
static int __init __maybe_unused rk_cam_skip_frame_interval_setup(char *str)
{
int ret = 0;
unsigned long val = 0;
ret = kstrtoul(str, 0, &val);
if (!ret) {
rk_cam_skip_frame_interval = (u32)val;
} else {
rk_cam_skip_frame_interval = 0;
pr_err("get rk_cam_skip_frame_interval fail\n");
}
return 0;
}
u32 get_rk_cam_skip_frame_interval(void)
{
return rk_cam_skip_frame_interval;
}
EXPORT_SYMBOL(get_rk_cam_skip_frame_interval);
__setup("rk_cam_w=", rk_cam_w_setup);
__setup("rk_cam_h=", rk_cam_h_setup);
__setup("rk_cam_hdr=", rk_cam_hdr_setup);
__setup("rk_cam_fps=", rk_cam_fps_setup);
__setup("rk_cam_skip_frame_interval=", rk_cam_skip_frame_interval_setup);

View File

@@ -3,36 +3,28 @@
#ifndef CAM_TB_SETUP_H
#define CAM_TB_SETUP_H
#include <linux/types.h>
#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
u32 get_rk_cam_w(void);
u32 get_rk_cam_h(void);
u32 get_rk_cam_hdr(void);
u32 get_rk_cam_fps(void);
u32 get_rk_cam_skip_frame_interval(void);
#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_SETUP
#define EXTERN_CAM_TB_PARAM(para) u32 get_##para(void)
#else
static inline u32 get_rk_cam_w(void)
{
return 0;
}
static inline u32 get_rk_cam_h(void)
{
return 0;
}
static inline u32 get_rk_cam_hdr(void)
{
return 0;
}
static inline u32 get_rk_cam_fps(void)
{
return 0;
}
static inline u32 get_rk_cam_skip_frame_interval(void)
{
return 0;
#define EXTERN_CAM_TB_PARAM(para) \
static inline u32 get_##para(void) \
{ \
return 0; \
}
#endif
EXTERN_CAM_TB_PARAM(rk_cam_w);
EXTERN_CAM_TB_PARAM(rk_cam_h);
EXTERN_CAM_TB_PARAM(rk_cam_hdr);
EXTERN_CAM_TB_PARAM(rk_cam_fps);
EXTERN_CAM_TB_PARAM(rk_cam1_max_fps);
EXTERN_CAM_TB_PARAM(rk_cam2_w);
EXTERN_CAM_TB_PARAM(rk_cam2_h);
EXTERN_CAM_TB_PARAM(rk_cam2_hdr);
EXTERN_CAM_TB_PARAM(rk_cam2_fps);
EXTERN_CAM_TB_PARAM(rk_cam2_max_fps);
EXTERN_CAM_TB_PARAM(rk_cam_skip);
EXTERN_CAM_TB_PARAM(rockit_en_mcu);
#endif

View File

@@ -8288,7 +8288,7 @@ void rkcif_stream_init(struct rkcif_device *dev, u32 id)
init_completion(&stream->stop_complete);
init_completion(&stream->start_complete);
stream->is_wait_stop_complete = false;
stream->thunderboot_skip_interval = get_rk_cam_skip_frame_interval();
stream->thunderboot_skip_interval = get_rk_cam_skip();
atomic_set(&stream->sub_stream_buf_cnt, 0);
spin_lock_init(&stream->fence_lock);
rkcif_fence_context_init(&stream->fence_ctx);

View File

@@ -315,7 +315,10 @@ static int mmc_caps_set(void *data, u64 val)
MMC_CAP_SD_HIGHSPEED |
MMC_CAP_MMC_HIGHSPEED |
MMC_CAP_UHS |
MMC_CAP_DDR;
MMC_CAP_DDR |
MMC_CAP_4_BIT_DATA |
MMC_CAP_8_BIT_DATA |
MMC_CAP_CMD23;
if (diff & ~allowed)
return -EINVAL;
@@ -327,7 +330,10 @@ static int mmc_caps_set(void *data, u64 val)
static int mmc_caps2_set(void *data, u64 val)
{
u32 allowed = MMC_CAP2_HSX00_1_8V | MMC_CAP2_HSX00_1_2V;
u32 allowed = MMC_CAP2_HSX00_1_8V |
MMC_CAP2_HSX00_1_2V |
MMC_CAP2_CQE |
MMC_CAP2_CQE_DCMD;
u32 *caps = data;
u32 diff = *caps ^ val;

View File

@@ -111,6 +111,12 @@ enum rockchip_cabc_mode {
ROCKCHIP_DRM_CABC_MODE_USERSPACE,
};
enum rockchip_drm_error_event_type {
ROCKCHIP_DRM_ERROR_EVENT_IOMMU_FAULT = (1 << 0),
ROCKCHIP_DRM_ERROR_EVENT_POST_BUF_EMPTY = (1 << 1),
ROCKCHIP_DRM_ERROR_EVENT_REQUEST_RESET = (1 << 2),
};
#define DRM_ROCKCHIP_GEM_CREATE 0x00
#define DRM_ROCKCHIP_GEM_MAP_OFFSET 0x01
#define DRM_ROCKCHIP_GEM_CPU_ACQUIRE 0x02