Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

cfe improvements/fixes #5630

Merged
merged 14 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 43 additions & 36 deletions drivers/media/platform/raspberrypi/rp1_cfe/cfe.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@
#define CFE_MODULE_NAME "rp1-cfe"
#define CFE_VERSION "1.0"

bool cfe_debug_irq;
bool cfe_debug_verbose;
module_param_named(verbose_debug, cfe_debug_verbose, bool, 0644);
MODULE_PARM_DESC(verbose_debug, "verbose debugging messages");

#define cfe_dbg_irq(fmt, arg...) \
#define cfe_dbg_verbose(fmt, arg...) \
do { \
if (cfe_debug_irq) \
if (cfe_debug_verbose) \
dev_dbg(&cfe->pdev->dev, fmt, ##arg); \
} while (0)
#define cfe_dbg(fmt, arg...) dev_dbg(&cfe->pdev->dev, fmt, ##arg)
Expand Down Expand Up @@ -108,6 +110,7 @@ const struct v4l2_mbus_framefmt cfe_default_meta_format = {
.width = 8192,
.height = 1,
.code = MEDIA_BUS_FMT_SENSOR_DATA,
.field = V4L2_FIELD_NONE,
};

enum node_ids {
Expand Down Expand Up @@ -290,7 +293,6 @@ struct cfe_device {
struct csi2_device csi2;
struct pisp_fe_device fe;

bool sensor_embedded_data;
int fe_csi2_channel;

unsigned int sequence;
Expand Down Expand Up @@ -518,8 +520,8 @@ static void cfe_schedule_next_csi2_job(struct cfe_device *cfe)
node->next_frm = buf;
list_del(&buf->list);

cfe_dbg("%s: [%s] buffer:%p\n",
__func__, node_desc[node->id].name, &buf->vb.vb2_buf);
cfe_dbg_verbose("%s: [%s] buffer:%p\n", __func__,
node_desc[node->id].name, &buf->vb.vb2_buf);

if (is_meta_node(node)) {
size = node->fmt.fmt.meta.buffersize;
Expand Down Expand Up @@ -550,8 +552,8 @@ static void cfe_schedule_next_pisp_job(struct cfe_device *cfe)
buf = list_first_entry(&node->dma_queue, struct cfe_buffer,
list);

cfe_dbg_irq("%s: [%s] buffer:%p\n", __func__,
node_desc[node->id].name, &buf->vb.vb2_buf);
cfe_dbg_verbose("%s: [%s] buffer:%p\n", __func__,
node_desc[node->id].name, &buf->vb.vb2_buf);

node->next_frm = buf;
vb2_bufs[node_desc[i].link_pad] = &buf->vb.vb2_buf;
Expand All @@ -573,8 +575,8 @@ static bool cfe_check_job_ready(struct cfe_device *cfe)
continue;

if (list_empty(&node->dma_queue)) {
cfe_dbg_irq("%s: [%s] has no buffer, unable to schedule job\n",
__func__, node_desc[i].name);
cfe_dbg_verbose("%s: [%s] has no buffer, unable to schedule job\n",
__func__, node_desc[i].name);
return false;
}
}
Expand All @@ -592,16 +594,16 @@ static void cfe_prepare_next_job(struct cfe_device *cfe)
/* Flag if another job is ready after this. */
cfe->job_ready = cfe_check_job_ready(cfe);

cfe_dbg_irq("%s: end with scheduled job\n", __func__);
cfe_dbg_verbose("%s: end with scheduled job\n", __func__);
}

static void cfe_process_buffer_complete(struct cfe_node *node,
unsigned int sequence)
{
struct cfe_device *cfe = node->cfe;

cfe_dbg_irq("%s: [%s] buffer:%p\n", __func__, node_desc[node->id].name,
&node->cur_frm->vb.vb2_buf);
cfe_dbg_verbose("%s: [%s] buffer:%p\n", __func__,
node_desc[node->id].name, &node->cur_frm->vb.vb2_buf);

node->cur_frm->vb.sequence = sequence;
vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
Expand All @@ -621,8 +623,8 @@ static void cfe_sof_isr_handler(struct cfe_node *node)
{
struct cfe_device *cfe = node->cfe;

cfe_dbg_irq("%s: [%s] seq %u\n", __func__, node_desc[node->id].name,
cfe->sequence);
cfe_dbg_verbose("%s: [%s] seq %u\n", __func__, node_desc[node->id].name,
cfe->sequence);

node->cur_frm = node->next_frm;
node->next_frm = NULL;
Expand Down Expand Up @@ -651,8 +653,8 @@ static void cfe_eof_isr_handler(struct cfe_node *node)
{
struct cfe_device *cfe = node->cfe;

cfe_dbg_irq("%s: [%s] seq %u\n", __func__, node_desc[node->id].name,
cfe->sequence);
cfe_dbg_verbose("%s: [%s] seq %u\n", __func__, node_desc[node->id].name,
cfe->sequence);

if (node->cur_frm)
cfe_process_buffer_complete(node, cfe->sequence);
Expand Down Expand Up @@ -763,20 +765,16 @@ static void cfe_start_channel(struct cfe_node *node)
struct v4l2_mbus_framefmt *source_fmt;
const struct cfe_fmt *fmt;
unsigned long flags;
unsigned int width = 0, height = 0;
bool start_fe = is_fe_enabled(cfe) &&
test_all_nodes(cfe, NODE_ENABLED, NODE_STREAMING);

cfe_dbg("%s: [%s]\n", __func__, node_desc[node->id].name);

if (start_fe || is_image_output_node(node)) {
width = node->fmt.fmt.pix.width;
height = node->fmt.fmt.pix.height;
}

state = v4l2_subdev_lock_and_get_active_state(&cfe->csi2.sd);

if (start_fe) {
unsigned int width, height;

WARN_ON(!is_fe_enabled(cfe));
cfe_dbg("%s: %s using csi2 channel %d\n",
__func__, node_desc[FE_OUT0].name,
Expand All @@ -785,6 +783,9 @@ static void cfe_start_channel(struct cfe_node *node)
source_fmt = v4l2_subdev_get_pad_format(&cfe->csi2.sd, state, cfe->fe_csi2_channel);
fmt = find_format_by_code(source_fmt->code);

width = source_fmt->width;
height = source_fmt->height;

/*
* Start the associated CSI2 Channel as well.
*
Expand All @@ -800,13 +801,18 @@ static void cfe_start_channel(struct cfe_node *node)
}

if (is_csi2_node(node)) {
unsigned int width = 0, height = 0;

u32 mode = CSI2_MODE_NORMAL;

source_fmt = v4l2_subdev_get_pad_format(&cfe->csi2.sd, state,
node_desc[node->id].link_pad - CSI2_NUM_CHANNELS);
fmt = find_format_by_code(source_fmt->code);

if (is_image_output_node(node)) {
width = source_fmt->width;
height = source_fmt->height;

if (node->fmt.fmt.pix.pixelformat ==
fmt->remap[CFE_REMAP_16BIT])
mode = CSI2_MODE_REMAP;
Expand Down Expand Up @@ -917,8 +923,8 @@ static int cfe_buffer_prepare(struct vb2_buffer *vb)
struct cfe_buffer *buf = to_cfe_buffer(vb);
unsigned long size;

cfe_dbg_irq("%s: [%s] buffer:%p\n", __func__, node_desc[node->id].name,
vb);
cfe_dbg_verbose("%s: [%s] buffer:%p\n", __func__,
node_desc[node->id].name, vb);

size = is_image_output_node(node) ? node->fmt.fmt.pix.sizeimage :
node->fmt.fmt.meta.buffersize;
Expand Down Expand Up @@ -950,8 +956,8 @@ static void cfe_buffer_queue(struct vb2_buffer *vb)
struct cfe_buffer *buf = to_cfe_buffer(vb);
unsigned long flags;

cfe_dbg_irq("%s: [%s] buffer:%p\n", __func__, node_desc[node->id].name,
vb);
cfe_dbg_verbose("%s: [%s] buffer:%p\n", __func__,
node_desc[node->id].name, vb);

spin_lock_irqsave(&cfe->state_lock, flags);

Expand Down Expand Up @@ -991,6 +997,14 @@ static int cfe_start_streaming(struct vb2_queue *vq, unsigned int count)
goto err_streaming;
}

/* When using the Frontend, we must enable the FE_CONFIG node. */
if (is_fe_enabled(cfe) &&
!check_state(cfe, NODE_ENABLED, cfe->node[FE_CONFIG].id)) {
cfe_err("FE enabled, but FE_CONFIG node is not\n");
ret = -EINVAL;
goto err_streaming;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naushir Ah, noticed only now. The above code block is on the wrong side of the pm_runtime_resume_and_get. It will miss a runtime put in error case.

ret = media_pipeline_start(&node->pad, &cfe->pipe);
if (ret < 0) {
cfe_err("Failed to start media pipeline: %d\n", ret);
Expand Down Expand Up @@ -1815,8 +1829,6 @@ static int cfe_probe_complete(struct cfe_device *cfe)

cfe->v4l2_dev.notify = cfe_notify;

cfe->sensor_embedded_data = (cfe->sensor->entity.num_pads >= 2);

for (i = 0; i < NUM_NODES; i++) {
ret = cfe_register_node(cfe, i);
if (ret) {
Expand All @@ -1837,17 +1849,10 @@ static int cfe_probe_complete(struct cfe_device *cfe)
goto unregister;
}

/*
* Release the initial reference, all references are now owned by the
* video devices.
*/
cfe_put(cfe);
return 0;

unregister:
cfe_unregister_nodes(cfe);
cfe_put(cfe);

return ret;
}

Expand Down Expand Up @@ -2129,6 +2134,8 @@ static int cfe_remove(struct platform_device *pdev)

v4l2_device_unregister(&cfe->v4l2_dev);

cfe_put(cfe);

return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/media/platform/raspberrypi/rp1_cfe/cfe.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <linux/media-bus-format.h>
#include <linux/videodev2.h>

extern bool cfe_debug_irq;
extern bool cfe_debug_verbose;

enum cfe_remap_types {
CFE_REMAP_16BIT,
Expand Down
Loading