Skip to content

Commit 53ebeea

Browse files
mingqian-0mchehab
authored andcommitted
media: imx-jpeg: Support to assign slot for encoder/decoder
imx jpeg encoder and decoder support 4 slots each, aim to support some virtualization scenarios. driver should only enable one slot one time. but due to some hardware issue, only slot 0 can be enabled in imx8q platform, and they may be fixed in imx9 platform. Signed-off-by: Ming Qian <ming.qian@nxp.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
1 parent dcff0b5 commit 53ebeea

File tree

3 files changed

+68
-73
lines changed

3 files changed

+68
-73
lines changed

drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
#define CAST_OFBSIZE_LO CAST_STATUS18
5959
#define CAST_OFBSIZE_HI CAST_STATUS19
6060

61-
#define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/
6261
/* JPEG-Decoder Wrapper Slot Registers 0..3 */
6362
#define SLOT_BASE 0x10000
6463
#define SLOT_STATUS 0x0

drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c

Lines changed: 65 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -745,87 +745,77 @@ static void notify_src_chg(struct mxc_jpeg_ctx *ctx)
745745
v4l2_event_queue_fh(&ctx->fh, &ev);
746746
}
747747

748-
static int mxc_get_free_slot(struct mxc_jpeg_slot_data slot_data[], int n)
748+
static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data)
749749
{
750-
int free_slot = 0;
751-
752-
while (slot_data[free_slot].used && free_slot < n)
753-
free_slot++;
754-
755-
return free_slot; /* >=n when there are no more free slots */
750+
if (!slot_data->used)
751+
return slot_data->slot;
752+
return -1;
756753
}
757754

758-
static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg,
759-
unsigned int slot)
755+
static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
760756
{
761757
struct mxc_jpeg_desc *desc;
762758
struct mxc_jpeg_desc *cfg_desc;
763759
void *cfg_stm;
764760

765-
if (jpeg->slot_data[slot].desc)
761+
if (jpeg->slot_data.desc)
766762
goto skip_alloc; /* already allocated, reuse it */
767763

768764
/* allocate descriptor for decoding/encoding phase */
769765
desc = dma_alloc_coherent(jpeg->dev,
770766
sizeof(struct mxc_jpeg_desc),
771-
&jpeg->slot_data[slot].desc_handle,
767+
&jpeg->slot_data.desc_handle,
772768
GFP_ATOMIC);
773769
if (!desc)
774770
goto err;
775-
jpeg->slot_data[slot].desc = desc;
771+
jpeg->slot_data.desc = desc;
776772

777773
/* allocate descriptor for configuration phase (encoder only) */
778774
cfg_desc = dma_alloc_coherent(jpeg->dev,
779775
sizeof(struct mxc_jpeg_desc),
780-
&jpeg->slot_data[slot].cfg_desc_handle,
776+
&jpeg->slot_data.cfg_desc_handle,
781777
GFP_ATOMIC);
782778
if (!cfg_desc)
783779
goto err;
784-
jpeg->slot_data[slot].cfg_desc = cfg_desc;
780+
jpeg->slot_data.cfg_desc = cfg_desc;
785781

786782
/* allocate configuration stream */
787783
cfg_stm = dma_alloc_coherent(jpeg->dev,
788784
MXC_JPEG_MAX_CFG_STREAM,
789-
&jpeg->slot_data[slot].cfg_stream_handle,
785+
&jpeg->slot_data.cfg_stream_handle,
790786
GFP_ATOMIC);
791787
if (!cfg_stm)
792788
goto err;
793-
jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm;
789+
jpeg->slot_data.cfg_stream_vaddr = cfg_stm;
794790

795791
skip_alloc:
796-
jpeg->slot_data[slot].used = true;
792+
jpeg->slot_data.used = true;
797793

798794
return true;
799795
err:
800-
dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", slot);
796+
dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot);
801797

802798
return false;
803799
}
804800

805-
static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg,
806-
unsigned int slot)
801+
static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
807802
{
808-
if (slot >= MXC_MAX_SLOTS) {
809-
dev_err(jpeg->dev, "Invalid slot %d, nothing to free.", slot);
810-
return;
811-
}
812-
813803
/* free descriptor for decoding/encoding phase */
814804
dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
815-
jpeg->slot_data[slot].desc,
816-
jpeg->slot_data[slot].desc_handle);
805+
jpeg->slot_data.desc,
806+
jpeg->slot_data.desc_handle);
817807

818808
/* free descriptor for encoder configuration phase / decoder DHT */
819809
dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
820-
jpeg->slot_data[slot].cfg_desc,
821-
jpeg->slot_data[slot].cfg_desc_handle);
810+
jpeg->slot_data.cfg_desc,
811+
jpeg->slot_data.cfg_desc_handle);
822812

823813
/* free configuration stream */
824814
dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
825-
jpeg->slot_data[slot].cfg_stream_vaddr,
826-
jpeg->slot_data[slot].cfg_stream_handle);
815+
jpeg->slot_data.cfg_stream_vaddr,
816+
jpeg->slot_data.cfg_stream_handle);
827817

828-
jpeg->slot_data[slot].used = false;
818+
jpeg->slot_data.used = false;
829819
}
830820

831821
static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
@@ -855,7 +845,7 @@ static void mxc_jpeg_job_finish(struct mxc_jpeg_ctx *ctx, enum vb2_buffer_state
855845
v4l2_m2m_buf_done(dst_buf, state);
856846

857847
mxc_jpeg_disable_irq(reg, ctx->slot);
858-
ctx->mxc_jpeg->slot_data[ctx->slot].used = false;
848+
jpeg->slot_data.used = false;
859849
if (reset)
860850
mxc_jpeg_sw_reset(reg);
861851
}
@@ -919,7 +909,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
919909
goto job_unlock;
920910
}
921911

922-
if (!jpeg->slot_data[slot].used)
912+
if (!jpeg->slot_data.used)
923913
goto job_unlock;
924914

925915
dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
@@ -1179,13 +1169,13 @@ static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf,
11791169
struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
11801170
void __iomem *reg = jpeg->base_reg;
11811171
unsigned int slot = ctx->slot;
1182-
struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc;
1183-
struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc;
1184-
dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle;
1185-
dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle;
1186-
dma_addr_t cfg_stream_handle = jpeg->slot_data[slot].cfg_stream_handle;
1187-
unsigned int *cfg_size = &jpeg->slot_data[slot].cfg_stream_size;
1188-
void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr;
1172+
struct mxc_jpeg_desc *desc = jpeg->slot_data.desc;
1173+
struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc;
1174+
dma_addr_t desc_handle = jpeg->slot_data.desc_handle;
1175+
dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle;
1176+
dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle;
1177+
unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size;
1178+
void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr;
11891179
struct mxc_jpeg_src_buf *jpeg_src_buf;
11901180

11911181
jpeg_src_buf = vb2_to_mxc_buf(src_buf);
@@ -1245,18 +1235,18 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
12451235
struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
12461236
void __iomem *reg = jpeg->base_reg;
12471237
unsigned int slot = ctx->slot;
1248-
struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc;
1249-
struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc;
1250-
dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle;
1251-
dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle;
1252-
void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr;
1238+
struct mxc_jpeg_desc *desc = jpeg->slot_data.desc;
1239+
struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc;
1240+
dma_addr_t desc_handle = jpeg->slot_data.desc_handle;
1241+
dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle;
1242+
void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr;
12531243
struct mxc_jpeg_q_data *q_data;
12541244
enum mxc_jpeg_image_format img_fmt;
12551245
int w, h;
12561246

12571247
q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type);
12581248

1259-
jpeg->slot_data[slot].cfg_stream_size =
1249+
jpeg->slot_data.cfg_stream_size =
12601250
mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
12611251
q_data->fmt->fourcc,
12621252
q_data->crop.width,
@@ -1265,7 +1255,7 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
12651255
/* chain the config descriptor with the encoding descriptor */
12661256
cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
12671257

1268-
cfg_desc->buf_base0 = jpeg->slot_data[slot].cfg_stream_handle;
1258+
cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle;
12691259
cfg_desc->buf_base1 = 0;
12701260
cfg_desc->line_pitch = 0;
12711261
cfg_desc->stm_bufbase = 0; /* no output expected */
@@ -1408,7 +1398,7 @@ static void mxc_jpeg_device_run_timeout(struct work_struct *work)
14081398
unsigned long flags;
14091399

14101400
spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
1411-
if (ctx->slot < MXC_MAX_SLOTS && ctx->mxc_jpeg->slot_data[ctx->slot].used) {
1401+
if (ctx->mxc_jpeg->slot_data.used) {
14121402
dev_warn(jpeg->dev, "%s timeout, cancel it\n",
14131403
ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode");
14141404
mxc_jpeg_job_finish(ctx, VB2_BUF_STATE_ERROR, true);
@@ -1476,12 +1466,12 @@ static void mxc_jpeg_device_run(void *priv)
14761466
mxc_jpeg_enable(reg);
14771467
mxc_jpeg_set_l_endian(reg, 1);
14781468

1479-
ctx->slot = mxc_get_free_slot(jpeg->slot_data, MXC_MAX_SLOTS);
1480-
if (ctx->slot >= MXC_MAX_SLOTS) {
1469+
ctx->slot = mxc_get_free_slot(&jpeg->slot_data);
1470+
if (ctx->slot < 0) {
14811471
dev_err(dev, "No more free slots\n");
14821472
goto end;
14831473
}
1484-
if (!mxc_jpeg_alloc_slot_data(jpeg, ctx->slot)) {
1474+
if (!mxc_jpeg_alloc_slot_data(jpeg)) {
14851475
dev_err(dev, "Cannot allocate slot data\n");
14861476
goto end;
14871477
}
@@ -2101,7 +2091,7 @@ static int mxc_jpeg_open(struct file *file)
21012091
}
21022092
ctx->fh.ctrl_handler = &ctx->ctrl_handler;
21032093
mxc_jpeg_set_default_params(ctx);
2104-
ctx->slot = MXC_MAX_SLOTS; /* slot not allocated yet */
2094+
ctx->slot = -1; /* slot not allocated yet */
21052095
INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout);
21062096

21072097
if (mxc_jpeg->mode == MXC_JPEG_DECODE)
@@ -2677,6 +2667,11 @@ static int mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev *jpeg)
26772667
dev_err(dev, "No power domains defined for jpeg node\n");
26782668
return jpeg->num_domains;
26792669
}
2670+
if (jpeg->num_domains == 1) {
2671+
/* genpd_dev_pm_attach() attach automatically if power domains count is 1 */
2672+
jpeg->num_domains = 0;
2673+
return 0;
2674+
}
26802675

26812676
jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains,
26822677
sizeof(*jpeg->pd_dev), GFP_KERNEL);
@@ -2718,7 +2713,6 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
27182713
int ret;
27192714
int mode;
27202715
const struct of_device_id *of_id;
2721-
unsigned int slot;
27222716

27232717
of_id = of_match_node(mxc_jpeg_match, dev->of_node);
27242718
if (!of_id)
@@ -2742,19 +2736,22 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
27422736
if (IS_ERR(jpeg->base_reg))
27432737
return PTR_ERR(jpeg->base_reg);
27442738

2745-
for (slot = 0; slot < MXC_MAX_SLOTS; slot++) {
2746-
dec_irq = platform_get_irq(pdev, slot);
2747-
if (dec_irq < 0) {
2748-
ret = dec_irq;
2749-
goto err_irq;
2750-
}
2751-
ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq,
2752-
0, pdev->name, jpeg);
2753-
if (ret) {
2754-
dev_err(&pdev->dev, "Failed to request irq %d (%d)\n",
2755-
dec_irq, ret);
2756-
goto err_irq;
2757-
}
2739+
ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot);
2740+
if (ret)
2741+
jpeg->slot_data.slot = 0;
2742+
dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot);
2743+
dec_irq = platform_get_irq(pdev, 0);
2744+
if (dec_irq < 0) {
2745+
dev_err(&pdev->dev, "Failed to get irq %d\n", dec_irq);
2746+
ret = dec_irq;
2747+
goto err_irq;
2748+
}
2749+
ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq,
2750+
0, pdev->name, jpeg);
2751+
if (ret) {
2752+
dev_err(&pdev->dev, "Failed to request irq %d (%d)\n",
2753+
dec_irq, ret);
2754+
goto err_irq;
27582755
}
27592756

27602757
jpeg->pdev = pdev;
@@ -2914,11 +2911,9 @@ static const struct dev_pm_ops mxc_jpeg_pm_ops = {
29142911

29152912
static void mxc_jpeg_remove(struct platform_device *pdev)
29162913
{
2917-
unsigned int slot;
29182914
struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev);
29192915

2920-
for (slot = 0; slot < MXC_MAX_SLOTS; slot++)
2921-
mxc_jpeg_free_slot_data(jpeg, slot);
2916+
mxc_jpeg_free_slot_data(jpeg);
29222917

29232918
pm_runtime_disable(&pdev->dev);
29242919
video_unregister_device(jpeg->dec_vdev);

drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ struct mxc_jpeg_ctx {
9797
struct mxc_jpeg_q_data cap_q;
9898
struct v4l2_fh fh;
9999
enum mxc_jpeg_enc_state enc_state;
100-
unsigned int slot;
100+
int slot;
101101
unsigned int source_change;
102102
bool header_parsed;
103103
struct v4l2_ctrl_handler ctrl_handler;
@@ -106,6 +106,7 @@ struct mxc_jpeg_ctx {
106106
};
107107

108108
struct mxc_jpeg_slot_data {
109+
int slot;
109110
bool used;
110111
struct mxc_jpeg_desc *desc; // enc/dec descriptor
111112
struct mxc_jpeg_desc *cfg_desc; // configuration descriptor
@@ -128,7 +129,7 @@ struct mxc_jpeg_dev {
128129
struct v4l2_device v4l2_dev;
129130
struct v4l2_m2m_dev *m2m_dev;
130131
struct video_device *dec_vdev;
131-
struct mxc_jpeg_slot_data slot_data[MXC_MAX_SLOTS];
132+
struct mxc_jpeg_slot_data slot_data;
132133
int num_domains;
133134
struct device **pd_dev;
134135
struct device_link **pd_link;

0 commit comments

Comments
 (0)