@@ -137,6 +137,17 @@ struct ipu_image_convert_ctx;
137
137
struct ipu_image_convert_chan ;
138
138
struct ipu_image_convert_priv ;
139
139
140
+ enum eof_irq_mask {
141
+ EOF_IRQ_IN = BIT (0 ),
142
+ EOF_IRQ_ROT_IN = BIT (1 ),
143
+ EOF_IRQ_OUT = BIT (2 ),
144
+ EOF_IRQ_ROT_OUT = BIT (3 ),
145
+ };
146
+
147
+ #define EOF_IRQ_COMPLETE (EOF_IRQ_IN | EOF_IRQ_OUT)
148
+ #define EOF_IRQ_ROT_COMPLETE (EOF_IRQ_IN | EOF_IRQ_OUT | \
149
+ EOF_IRQ_ROT_IN | EOF_IRQ_ROT_OUT)
150
+
140
151
struct ipu_image_convert_ctx {
141
152
struct ipu_image_convert_chan * chan ;
142
153
@@ -173,6 +184,9 @@ struct ipu_image_convert_ctx {
173
184
/* where to place converted tile in dest image */
174
185
unsigned int out_tile_map [MAX_TILES ];
175
186
187
+ /* mask of completed EOF irqs at every tile conversion */
188
+ enum eof_irq_mask eof_mask ;
189
+
176
190
struct list_head list ;
177
191
};
178
192
@@ -189,6 +203,8 @@ struct ipu_image_convert_chan {
189
203
struct ipuv3_channel * rotation_out_chan ;
190
204
191
205
/* the IPU end-of-frame irqs */
206
+ int in_eof_irq ;
207
+ int rot_in_eof_irq ;
192
208
int out_eof_irq ;
193
209
int rot_out_eof_irq ;
194
210
@@ -1380,6 +1396,9 @@ static int convert_start(struct ipu_image_convert_run *run, unsigned int tile)
1380
1396
dev_dbg (priv -> ipu -> dev , "%s: task %u: starting ctx %p run %p tile %u -> %u\n" ,
1381
1397
__func__ , chan -> ic_task , ctx , run , tile , dst_tile );
1382
1398
1399
+ /* clear EOF irq mask */
1400
+ ctx -> eof_mask = 0 ;
1401
+
1383
1402
if (ipu_rot_mode_is_irt (ctx -> rot_mode )) {
1384
1403
/* swap width/height for resizer */
1385
1404
dest_width = d_image -> tile [dst_tile ].height ;
@@ -1615,7 +1634,7 @@ static bool ic_settings_changed(struct ipu_image_convert_ctx *ctx)
1615
1634
}
1616
1635
1617
1636
/* hold irqlock when calling */
1618
- static irqreturn_t do_irq (struct ipu_image_convert_run * run )
1637
+ static irqreturn_t do_tile_complete (struct ipu_image_convert_run * run )
1619
1638
{
1620
1639
struct ipu_image_convert_ctx * ctx = run -> ctx ;
1621
1640
struct ipu_image_convert_chan * chan = ctx -> chan ;
@@ -1700,6 +1719,7 @@ static irqreturn_t do_irq(struct ipu_image_convert_run *run)
1700
1719
ctx -> cur_buf_num ^= 1 ;
1701
1720
}
1702
1721
1722
+ ctx -> eof_mask = 0 ; /* clear EOF irq mask for next tile */
1703
1723
ctx -> next_tile ++ ;
1704
1724
return IRQ_HANDLED ;
1705
1725
done :
@@ -1715,8 +1735,9 @@ static irqreturn_t eof_irq(int irq, void *data)
1715
1735
struct ipu_image_convert_priv * priv = chan -> priv ;
1716
1736
struct ipu_image_convert_ctx * ctx ;
1717
1737
struct ipu_image_convert_run * run ;
1738
+ irqreturn_t ret = IRQ_HANDLED ;
1739
+ bool tile_complete = false;
1718
1740
unsigned long flags ;
1719
- irqreturn_t ret ;
1720
1741
1721
1742
spin_lock_irqsave (& chan -> irqlock , flags );
1722
1743
@@ -1729,27 +1750,33 @@ static irqreturn_t eof_irq(int irq, void *data)
1729
1750
1730
1751
ctx = run -> ctx ;
1731
1752
1732
- if (irq == chan -> out_eof_irq ) {
1733
- if (ipu_rot_mode_is_irt (ctx -> rot_mode )) {
1734
- /* this is a rotation op, just ignore */
1735
- ret = IRQ_HANDLED ;
1736
- goto out ;
1737
- }
1738
- } else if (irq == chan -> rot_out_eof_irq ) {
1753
+ if (irq == chan -> in_eof_irq ) {
1754
+ ctx -> eof_mask |= EOF_IRQ_IN ;
1755
+ } else if (irq == chan -> out_eof_irq ) {
1756
+ ctx -> eof_mask |= EOF_IRQ_OUT ;
1757
+ } else if (irq == chan -> rot_in_eof_irq ||
1758
+ irq == chan -> rot_out_eof_irq ) {
1739
1759
if (!ipu_rot_mode_is_irt (ctx -> rot_mode )) {
1740
1760
/* this was NOT a rotation op, shouldn't happen */
1741
1761
dev_err (priv -> ipu -> dev ,
1742
1762
"Unexpected rotation interrupt\n" );
1743
- ret = IRQ_HANDLED ;
1744
1763
goto out ;
1745
1764
}
1765
+ ctx -> eof_mask |= (irq == chan -> rot_in_eof_irq ) ?
1766
+ EOF_IRQ_ROT_IN : EOF_IRQ_ROT_OUT ;
1746
1767
} else {
1747
1768
dev_err (priv -> ipu -> dev , "Received unknown irq %d\n" , irq );
1748
1769
ret = IRQ_NONE ;
1749
1770
goto out ;
1750
1771
}
1751
1772
1752
- ret = do_irq (run );
1773
+ if (ipu_rot_mode_is_irt (ctx -> rot_mode ))
1774
+ tile_complete = (ctx -> eof_mask == EOF_IRQ_ROT_COMPLETE );
1775
+ else
1776
+ tile_complete = (ctx -> eof_mask == EOF_IRQ_COMPLETE );
1777
+
1778
+ if (tile_complete )
1779
+ ret = do_tile_complete (run );
1753
1780
out :
1754
1781
spin_unlock_irqrestore (& chan -> irqlock , flags );
1755
1782
return ret ;
@@ -1783,6 +1810,10 @@ static void force_abort(struct ipu_image_convert_ctx *ctx)
1783
1810
1784
1811
static void release_ipu_resources (struct ipu_image_convert_chan * chan )
1785
1812
{
1813
+ if (chan -> in_eof_irq >= 0 )
1814
+ free_irq (chan -> in_eof_irq , chan );
1815
+ if (chan -> rot_in_eof_irq >= 0 )
1816
+ free_irq (chan -> rot_in_eof_irq , chan );
1786
1817
if (chan -> out_eof_irq >= 0 )
1787
1818
free_irq (chan -> out_eof_irq , chan );
1788
1819
if (chan -> rot_out_eof_irq >= 0 )
@@ -1801,7 +1832,27 @@ static void release_ipu_resources(struct ipu_image_convert_chan *chan)
1801
1832
1802
1833
chan -> in_chan = chan -> out_chan = chan -> rotation_in_chan =
1803
1834
chan -> rotation_out_chan = NULL ;
1804
- chan -> out_eof_irq = chan -> rot_out_eof_irq = -1 ;
1835
+ chan -> in_eof_irq = -1 ;
1836
+ chan -> rot_in_eof_irq = -1 ;
1837
+ chan -> out_eof_irq = -1 ;
1838
+ chan -> rot_out_eof_irq = -1 ;
1839
+ }
1840
+
1841
+ static int get_eof_irq (struct ipu_image_convert_chan * chan ,
1842
+ struct ipuv3_channel * channel )
1843
+ {
1844
+ struct ipu_image_convert_priv * priv = chan -> priv ;
1845
+ int ret , irq ;
1846
+
1847
+ irq = ipu_idmac_channel_irq (priv -> ipu , channel , IPU_IRQ_EOF );
1848
+
1849
+ ret = request_threaded_irq (irq , eof_irq , do_bh , 0 , "ipu-ic" , chan );
1850
+ if (ret < 0 ) {
1851
+ dev_err (priv -> ipu -> dev , "could not acquire irq %d\n" , irq );
1852
+ return ret ;
1853
+ }
1854
+
1855
+ return irq ;
1805
1856
}
1806
1857
1807
1858
static int get_ipu_resources (struct ipu_image_convert_chan * chan )
@@ -1837,31 +1888,33 @@ static int get_ipu_resources(struct ipu_image_convert_chan *chan)
1837
1888
}
1838
1889
1839
1890
/* acquire the EOF interrupts */
1840
- chan -> out_eof_irq = ipu_idmac_channel_irq (priv -> ipu ,
1841
- chan -> out_chan ,
1842
- IPU_IRQ_EOF );
1891
+ ret = get_eof_irq (chan , chan -> in_chan );
1892
+ if (ret < 0 ) {
1893
+ chan -> in_eof_irq = -1 ;
1894
+ goto err ;
1895
+ }
1896
+ chan -> in_eof_irq = ret ;
1843
1897
1844
- ret = request_threaded_irq (chan -> out_eof_irq , eof_irq , do_bh ,
1845
- 0 , "ipu-ic" , chan );
1898
+ ret = get_eof_irq (chan , chan -> rotation_in_chan );
1846
1899
if (ret < 0 ) {
1847
- dev_err (priv -> ipu -> dev , "could not acquire irq %d\n" ,
1848
- chan -> out_eof_irq );
1849
- chan -> out_eof_irq = -1 ;
1900
+ chan -> rot_in_eof_irq = -1 ;
1850
1901
goto err ;
1851
1902
}
1903
+ chan -> rot_in_eof_irq = ret ;
1852
1904
1853
- chan -> rot_out_eof_irq = ipu_idmac_channel_irq (priv -> ipu ,
1854
- chan -> rotation_out_chan ,
1855
- IPU_IRQ_EOF );
1905
+ ret = get_eof_irq (chan , chan -> out_chan );
1906
+ if (ret < 0 ) {
1907
+ chan -> out_eof_irq = -1 ;
1908
+ goto err ;
1909
+ }
1910
+ chan -> out_eof_irq = ret ;
1856
1911
1857
- ret = request_threaded_irq (chan -> rot_out_eof_irq , eof_irq , do_bh ,
1858
- 0 , "ipu-ic" , chan );
1912
+ ret = get_eof_irq (chan , chan -> rotation_out_chan );
1859
1913
if (ret < 0 ) {
1860
- dev_err (priv -> ipu -> dev , "could not acquire irq %d\n" ,
1861
- chan -> rot_out_eof_irq );
1862
1914
chan -> rot_out_eof_irq = -1 ;
1863
1915
goto err ;
1864
1916
}
1917
+ chan -> rot_out_eof_irq = ret ;
1865
1918
1866
1919
return 0 ;
1867
1920
err :
@@ -2440,6 +2493,8 @@ int ipu_image_convert_init(struct ipu_soc *ipu, struct device *dev)
2440
2493
chan -> ic_task = i ;
2441
2494
chan -> priv = priv ;
2442
2495
chan -> dma_ch = & image_convert_dma_chan [i ];
2496
+ chan -> in_eof_irq = -1 ;
2497
+ chan -> rot_in_eof_irq = -1 ;
2443
2498
chan -> out_eof_irq = -1 ;
2444
2499
chan -> rot_out_eof_irq = -1 ;
2445
2500
0 commit comments