diff options
Diffstat (limited to 'drivers/media/platform/davinci/vpss.c')
-rw-r--r-- | drivers/media/platform/davinci/vpss.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/drivers/media/platform/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c index 684e815a81b6..a19c552232d1 100644 --- a/drivers/media/platform/davinci/vpss.c +++ b/drivers/media/platform/davinci/vpss.c | |||
@@ -50,13 +50,29 @@ MODULE_AUTHOR("Texas Instruments"); | |||
50 | /* VENCINT - vpss_int8 */ | 50 | /* VENCINT - vpss_int8 */ |
51 | #define DM355_VPSSBL_EVTSEL_DEFAULT 0x4 | 51 | #define DM355_VPSSBL_EVTSEL_DEFAULT 0x4 |
52 | 52 | ||
53 | #define DM365_ISP5_PCCR 0x04 | 53 | #define DM365_ISP5_PCCR 0x04 |
54 | #define DM365_ISP5_PCCR_BL_CLK_ENABLE BIT(0) | ||
55 | #define DM365_ISP5_PCCR_ISIF_CLK_ENABLE BIT(1) | ||
56 | #define DM365_ISP5_PCCR_H3A_CLK_ENABLE BIT(2) | ||
57 | #define DM365_ISP5_PCCR_RSZ_CLK_ENABLE BIT(3) | ||
58 | #define DM365_ISP5_PCCR_IPIPE_CLK_ENABLE BIT(4) | ||
59 | #define DM365_ISP5_PCCR_IPIPEIF_CLK_ENABLE BIT(5) | ||
60 | #define DM365_ISP5_PCCR_RSV BIT(6) | ||
61 | |||
62 | #define DM365_ISP5_BCR 0x08 | ||
63 | #define DM365_ISP5_BCR_ISIF_OUT_ENABLE BIT(1) | ||
64 | |||
54 | #define DM365_ISP5_INTSEL1 0x10 | 65 | #define DM365_ISP5_INTSEL1 0x10 |
55 | #define DM365_ISP5_INTSEL2 0x14 | 66 | #define DM365_ISP5_INTSEL2 0x14 |
56 | #define DM365_ISP5_INTSEL3 0x18 | 67 | #define DM365_ISP5_INTSEL3 0x18 |
57 | #define DM365_ISP5_CCDCMUX 0x20 | 68 | #define DM365_ISP5_CCDCMUX 0x20 |
58 | #define DM365_ISP5_PG_FRAME_SIZE 0x28 | 69 | #define DM365_ISP5_PG_FRAME_SIZE 0x28 |
59 | #define DM365_VPBE_CLK_CTRL 0x00 | 70 | #define DM365_VPBE_CLK_CTRL 0x00 |
71 | |||
72 | #define VPSS_CLK_CTRL 0x01c40044 | ||
73 | #define VPSS_CLK_CTRL_VENCCLKEN BIT(3) | ||
74 | #define VPSS_CLK_CTRL_DACCLKEN BIT(4) | ||
75 | |||
60 | /* | 76 | /* |
61 | * vpss interrupts. VDINT0 - vpss_int0, VDINT1 - vpss_int1, | 77 | * vpss interrupts. VDINT0 - vpss_int0, VDINT1 - vpss_int1, |
62 | * AF - vpss_int3 | 78 | * AF - vpss_int3 |
@@ -94,12 +110,19 @@ struct vpss_hw_ops { | |||
94 | void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel); | 110 | void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel); |
95 | /* clear wbl overflow bit */ | 111 | /* clear wbl overflow bit */ |
96 | int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel); | 112 | int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel); |
113 | /* set sync polarity */ | ||
114 | void (*set_sync_pol)(struct vpss_sync_pol); | ||
115 | /* set the PG_FRAME_SIZE register*/ | ||
116 | void (*set_pg_frame_size)(struct vpss_pg_frame_size); | ||
117 | /* check and clear interrupt if occured */ | ||
118 | int (*dma_complete_interrupt)(void); | ||
97 | }; | 119 | }; |
98 | 120 | ||
99 | /* vpss configuration */ | 121 | /* vpss configuration */ |
100 | struct vpss_oper_config { | 122 | struct vpss_oper_config { |
101 | __iomem void *vpss_regs_base0; | 123 | __iomem void *vpss_regs_base0; |
102 | __iomem void *vpss_regs_base1; | 124 | __iomem void *vpss_regs_base1; |
125 | resource_size_t *vpss_regs_base2; | ||
103 | enum vpss_platform_type platform; | 126 | enum vpss_platform_type platform; |
104 | spinlock_t vpss_lock; | 127 | spinlock_t vpss_lock; |
105 | struct vpss_hw_ops hw_ops; | 128 | struct vpss_hw_ops hw_ops; |
@@ -157,6 +180,14 @@ static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel) | |||
157 | bl_regw(src_sel << VPSS_HSSISEL_SHIFT, DM355_VPSSBL_CCDCMUX); | 180 | bl_regw(src_sel << VPSS_HSSISEL_SHIFT, DM355_VPSSBL_CCDCMUX); |
158 | } | 181 | } |
159 | 182 | ||
183 | int vpss_dma_complete_interrupt(void) | ||
184 | { | ||
185 | if (!oper_cfg.hw_ops.dma_complete_interrupt) | ||
186 | return 2; | ||
187 | return oper_cfg.hw_ops.dma_complete_interrupt(); | ||
188 | } | ||
189 | EXPORT_SYMBOL(vpss_dma_complete_interrupt); | ||
190 | |||
160 | int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel) | 191 | int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel) |
161 | { | 192 | { |
162 | if (!oper_cfg.hw_ops.select_ccdc_source) | 193 | if (!oper_cfg.hw_ops.select_ccdc_source) |
@@ -182,6 +213,15 @@ static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel) | |||
182 | return 0; | 213 | return 0; |
183 | } | 214 | } |
184 | 215 | ||
216 | void vpss_set_sync_pol(struct vpss_sync_pol sync) | ||
217 | { | ||
218 | if (!oper_cfg.hw_ops.set_sync_pol) | ||
219 | return; | ||
220 | |||
221 | oper_cfg.hw_ops.set_sync_pol(sync); | ||
222 | } | ||
223 | EXPORT_SYMBOL(vpss_set_sync_pol); | ||
224 | |||
185 | int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel) | 225 | int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel) |
186 | { | 226 | { |
187 | if (!oper_cfg.hw_ops.clear_wbl_overflow) | 227 | if (!oper_cfg.hw_ops.clear_wbl_overflow) |
@@ -347,6 +387,15 @@ void dm365_vpss_set_sync_pol(struct vpss_sync_pol sync) | |||
347 | } | 387 | } |
348 | EXPORT_SYMBOL(dm365_vpss_set_sync_pol); | 388 | EXPORT_SYMBOL(dm365_vpss_set_sync_pol); |
349 | 389 | ||
390 | void vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size) | ||
391 | { | ||
392 | if (!oper_cfg.hw_ops.set_pg_frame_size) | ||
393 | return; | ||
394 | |||
395 | oper_cfg.hw_ops.set_pg_frame_size(frame_size); | ||
396 | } | ||
397 | EXPORT_SYMBOL(vpss_set_pg_frame_size); | ||
398 | |||
350 | void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size) | 399 | void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size) |
351 | { | 400 | { |
352 | int current_reg = ((frame_size.hlpfr >> 1) - 1) << 16; | 401 | int current_reg = ((frame_size.hlpfr >> 1) - 1) << 16; |
@@ -425,6 +474,16 @@ static int vpss_probe(struct platform_device *pdev) | |||
425 | oper_cfg.hw_ops.enable_clock = dm365_enable_clock; | 474 | oper_cfg.hw_ops.enable_clock = dm365_enable_clock; |
426 | oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source; | 475 | oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source; |
427 | /* Setup vpss interrupts */ | 476 | /* Setup vpss interrupts */ |
477 | isp5_write((isp5_read(DM365_ISP5_PCCR) | | ||
478 | DM365_ISP5_PCCR_BL_CLK_ENABLE | | ||
479 | DM365_ISP5_PCCR_ISIF_CLK_ENABLE | | ||
480 | DM365_ISP5_PCCR_H3A_CLK_ENABLE | | ||
481 | DM365_ISP5_PCCR_RSZ_CLK_ENABLE | | ||
482 | DM365_ISP5_PCCR_IPIPE_CLK_ENABLE | | ||
483 | DM365_ISP5_PCCR_IPIPEIF_CLK_ENABLE | | ||
484 | DM365_ISP5_PCCR_RSV), DM365_ISP5_PCCR); | ||
485 | isp5_write((isp5_read(DM365_ISP5_BCR) | | ||
486 | DM365_ISP5_BCR_ISIF_OUT_ENABLE), DM365_ISP5_BCR); | ||
428 | isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1); | 487 | isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1); |
429 | isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2); | 488 | isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2); |
430 | isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3); | 489 | isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3); |
@@ -470,11 +529,20 @@ static struct platform_driver vpss_driver = { | |||
470 | 529 | ||
471 | static void vpss_exit(void) | 530 | static void vpss_exit(void) |
472 | { | 531 | { |
532 | iounmap(oper_cfg.vpss_regs_base2); | ||
533 | release_mem_region(VPSS_CLK_CTRL, 4); | ||
473 | platform_driver_unregister(&vpss_driver); | 534 | platform_driver_unregister(&vpss_driver); |
474 | } | 535 | } |
475 | 536 | ||
476 | static int __init vpss_init(void) | 537 | static int __init vpss_init(void) |
477 | { | 538 | { |
539 | if (!request_mem_region(VPSS_CLK_CTRL, 4, "vpss_clock_control")) | ||
540 | return -EBUSY; | ||
541 | |||
542 | oper_cfg.vpss_regs_base2 = ioremap(VPSS_CLK_CTRL, 4); | ||
543 | writel(VPSS_CLK_CTRL_VENCCLKEN | | ||
544 | VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2); | ||
545 | |||
478 | return platform_driver_register(&vpss_driver); | 546 | return platform_driver_register(&vpss_driver); |
479 | } | 547 | } |
480 | subsys_initcall(vpss_init); | 548 | subsys_initcall(vpss_init); |