diff options
author | Xinyu Chen <xinyu.chen@freescale.com> | 2012-11-30 11:59:33 +0800 |
---|---|---|
committer | Xinyu Chen <xinyu.chen@freescale.com> | 2012-11-30 11:59:33 +0800 |
commit | 08c473f52af7434b09214fedcfce222fb9821033 (patch) | |
tree | 555dc016292a132bd55096d42c945c61c6394174 /drivers/mxc | |
parent | 9ae3b66a8ea648d977cbcebf02209f21cc9be3a4 (diff) | |
parent | 57ade285e32285186879f96c346dd5b45a7f0dd6 (diff) |
Merge remote-tracking branch 'fsl-linux-sdk/imx_3.0.35_1.1.0' into imx_3.0.35_android
Conflicts:
arch/arm/mach-mx6/board-mx6q_sabrelite.c
arch/arm/mach-mx6/board-mx6q_sabresd.c
arch/arm/plat-mxc/cpufreq.c
Diffstat (limited to 'drivers/mxc')
23 files changed, 1049 insertions, 121 deletions
diff --git a/drivers/mxc/asrc/mxc_asrc.c b/drivers/mxc/asrc/mxc_asrc.c index b728fe19226d..4a17f5856d45 100644 --- a/drivers/mxc/asrc/mxc_asrc.c +++ b/drivers/mxc/asrc/mxc_asrc.c @@ -49,6 +49,7 @@ #define ASRC_RATIO_DECIMAL_DEPTH 26 DEFINE_SPINLOCK(data_lock); +DEFINE_SPINLOCK(pair_lock); DEFINE_SPINLOCK(input_int_lock); DEFINE_SPINLOCK(output_int_lock); @@ -153,6 +154,8 @@ static unsigned char output_clk_map_v2[] = { static unsigned char *input_clk_map, *output_clk_map; +struct asrc_p2p_ops asrc_pcm_p2p_ops_asrc; + static struct dma_chan *imx_asrc_dma_alloc(u32 dma_req); static int imx_asrc_dma_config( struct asrc_pair_params *params, @@ -661,6 +664,28 @@ int asrc_config_pair(struct asrc_config *config) EXPORT_SYMBOL(asrc_config_pair); +int asrc_set_watermark(enum asrc_pair_index index, u32 in_wm, u32 out_wm) +{ + u32 reg; + + if ((in_wm > 63) || (out_wm > 63)) { + pr_err("error watermark!\n"); + return -EINVAL; + } + + reg = __raw_readl( + g_asrc->vaddr + ASRC_ASRMCRA_REG + (index << 3)); + reg |= 1 << 22; + reg &= ~0x3f; + reg += in_wm; + reg &= ~(0x3f << 12); + reg += out_wm << 12; + __raw_writel(reg, + g_asrc->vaddr + ASRC_ASRMCRA_REG + (index << 3)); + return 0; +} +EXPORT_SYMBOL(asrc_set_watermark); + void asrc_start_conv(enum asrc_pair_index index) { int reg, reg_1; @@ -920,6 +945,7 @@ static void asrc_read_output_FIFO_S16(struct asrc_pair_params *params) u32 size, i, j, reg, t_size; u16 *index = params->output_last_period.dma_vaddr; + t_size = 0; size = asrc_get_output_FIFO_size(params->index); while (size) { for (i = 0; i < size; i++) { @@ -935,6 +961,8 @@ static void asrc_read_output_FIFO_S16(struct asrc_pair_params *params) size = asrc_get_output_FIFO_size(params->index); } + if (t_size > ASRC_OUTPUT_LAST_SAMPLE) + t_size = ASRC_OUTPUT_LAST_SAMPLE; params->output_last_period.length = t_size * params->channel_nums * 2; } @@ -959,6 +987,8 @@ static void asrc_read_output_FIFO_S24(struct asrc_pair_params *params) size = asrc_get_output_FIFO_size(params->index); } + if (t_size > ASRC_OUTPUT_LAST_SAMPLE) + t_size = ASRC_OUTPUT_LAST_SAMPLE; params->output_last_period.length = t_size * params->channel_nums * 4; } @@ -970,6 +1000,11 @@ static void asrc_output_task_worker(struct work_struct *w) unsigned long lock_flags; /* asrc output work struct */ + spin_lock_irqsave(&pair_lock, lock_flags); + if (!params->pair_hold) { + spin_unlock_irqrestore(&pair_lock, lock_flags); + return; + } switch (params->output_word_width) { case ASRC_WIDTH_24_BIT: asrc_read_output_FIFO_S24(params); @@ -981,6 +1016,7 @@ static void asrc_output_task_worker(struct work_struct *w) default: pr_err("%s: error word width\n", __func__); } + spin_unlock_irqrestore(&pair_lock, lock_flags); /* finish receiving all output data */ spin_lock_irqsave(&output_int_lock, lock_flags); @@ -1113,13 +1149,13 @@ static int imx_asrc_dma_config( slave_config.dst_addr = dma_addr; slave_config.dst_addr_width = buswidth; slave_config.dst_maxburst = - ASRC_INPUTFIFO_THRESHOLD * params->channel_nums; + params->input_wm * params->channel_nums; } else { slave_config.direction = DMA_DEV_TO_MEM; slave_config.src_addr = dma_addr; slave_config.src_addr_width = buswidth; slave_config.src_maxburst = - ASRC_OUTPUTFIFO_THRESHOLD * params->channel_nums; + params->output_wm * params->channel_nums; } ret = dmaengine_slave_config(chan, &slave_config); if (ret) { @@ -1223,7 +1259,7 @@ static int mxc_asrc_prepare_input_buffer(struct asrc_pair_params *params, } if (pbuf->input_buffer_length < - word_size * params->channel_nums * ASRC_INPUTFIFO_THRESHOLD) { + word_size * params->channel_nums * params->input_wm) { pr_err("input buffer size[%d] is too small!\n", pbuf->input_buffer_length); return -EINVAL; @@ -1256,9 +1292,6 @@ static int mxc_asrc_prepare_output_buffer(struct asrc_pair_params *params, { u32 word_size; - pbuf->output_buffer_length = asrc_get_output_buffer_size( - pbuf->input_buffer_length, - params->input_sample_rate, params->output_sample_rate); switch (params->output_word_width) { case ASRC_WIDTH_24_BIT: word_size = 4; @@ -1447,6 +1480,13 @@ static long asrc_ioctl(struct file *file, err = asrc_config_pair(&config); if (err < 0) break; + + params->input_wm = 4; + params->output_wm = 2; + err = asrc_set_watermark(config.pair, + params->input_wm, params->output_wm); + if (err < 0) + break; params->output_buffer_size = config.dma_buffer_size; params->input_buffer_size = config.dma_buffer_size; if (config.buffer_num > ASRC_DMA_BUFFER_NUM) @@ -1513,13 +1553,18 @@ static long asrc_ioctl(struct file *file, case ASRC_RELEASE_PAIR: { enum asrc_pair_index index; + unsigned long lock_flags; if (copy_from_user (&index, (void __user *)arg, sizeof(enum asrc_pair_index))) { err = -EFAULT; break; } + params->asrc_active = 0; + spin_lock_irqsave(&pair_lock, lock_flags); + params->pair_hold = 0; + spin_unlock_irqrestore(&pair_lock, lock_flags); if (params->input_dma_channel) dma_release_channel(params->input_dma_channel); if (params->output_dma_channel) @@ -1528,8 +1573,6 @@ static long asrc_ioctl(struct file *file, mxc_free_dma_buf(params); asrc_release_pair(index); asrc_finish_conv(index); - params->asrc_active = 0; - params->pair_hold = 0; break; } case ASRC_CONVERT: @@ -1704,9 +1747,11 @@ static int mxc_asrc_open(struct inode *inode, struct file *file) static int mxc_asrc_close(struct inode *inode, struct file *file) { struct asrc_pair_params *pair_params; + unsigned long lock_flags; pair_params = file->private_data; if (pair_params) { if (pair_params->asrc_active) { + pair_params->asrc_active = 0; dmaengine_terminate_all( pair_params->input_dma_channel); dmaengine_terminate_all( @@ -1716,6 +1761,9 @@ static int mxc_asrc_close(struct inode *inode, struct file *file) wake_up_interruptible(&pair_params->output_wait_queue); } if (pair_params->pair_hold) { + spin_lock_irqsave(&pair_lock, lock_flags); + pair_params->pair_hold = 0; + spin_unlock_irqrestore(&pair_lock, lock_flags); if (pair_params->input_dma_channel) dma_release_channel( pair_params->input_dma_channel); @@ -2016,6 +2064,18 @@ static struct platform_driver mxc_asrc_driver = { static __init int asrc_init(void) { int ret; + + asrc_pcm_p2p_ops_asrc.asrc_p2p_start_conv = asrc_start_conv; + asrc_pcm_p2p_ops_asrc.asrc_p2p_stop_conv = asrc_stop_conv; + asrc_pcm_p2p_ops_asrc.asrc_p2p_get_dma_request = asrc_get_dma_request; + asrc_pcm_p2p_ops_asrc.asrc_p2p_per_addr = asrc_get_per_addr; + asrc_pcm_p2p_ops_asrc.asrc_p2p_req_pair = asrc_req_pair; + asrc_pcm_p2p_ops_asrc.asrc_p2p_config_pair = asrc_config_pair; + asrc_pcm_p2p_ops_asrc.asrc_p2p_release_pair = asrc_release_pair; + asrc_pcm_p2p_ops_asrc.asrc_p2p_finish_conv = asrc_finish_conv; + + asrc_p2p_hook(&asrc_pcm_p2p_ops_asrc); + ret = platform_driver_register(&mxc_asrc_driver); return ret; } @@ -2025,6 +2085,8 @@ static __init int asrc_init(void) * */ static void __exit asrc_exit(void) { + asrc_p2p_hook(NULL); + platform_driver_unregister(&mxc_asrc_driver); return; } diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c index d8898a376fe1..a52c1c817560 100644 --- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c +++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c @@ -623,6 +623,7 @@ _InitializeContextBuffer( index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x02C00 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); @@ -905,6 +906,16 @@ _DestroyContext( /* Free state delta map. */ if (buffer->logical != gcvNULL) { +#if gcdVIRTUAL_COMMAND_BUFFER + gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer( + Context->hardware->kernel->eventObj, + Context->totalSize, + buffer->physical, + buffer->logical, + gcvKERNEL_PIXEL + )); + +#else gcmkONERROR(gckEVENT_FreeContiguousMemory( Context->hardware->kernel->eventObj, Context->totalSize, @@ -912,6 +923,7 @@ _DestroyContext( buffer->logical, gcvKERNEL_PIXEL )); +#endif buffer->logical = gcvNULL; } @@ -1149,6 +1161,16 @@ gckCONTEXT_Construct( )); /* Create a new physical context buffer. */ +#if gcdVIRTUAL_COMMAND_BUFFER + gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer( + context->hardware->kernel, + gcvFALSE, + &context->totalSize, + &buffer->physical, + &pointer + )); + +#else gcmkONERROR(gckOS_AllocateContiguous( Os, gcvFALSE, @@ -1156,6 +1178,7 @@ gckCONTEXT_Construct( &buffer->physical, &pointer )); +#endif buffer->logical = pointer; diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c index 377ce32ed4c3..2812582ff7fc 100644 --- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c +++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c @@ -221,17 +221,8 @@ _IdentifyHardware( Identity->superTileMode = 0; } - /* If new HZ is available, disable other early z modes. */ - if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) - || ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))))) - { - /* Disable EZ. */ - Identity->chipFeatures - = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))); - } - /* Disable HZ when EZ is present for older chips. */ - else if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))))) + if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))))) { /* Disable HIERARCHICAL_Z. */ Identity->chipMinorFeatures @@ -408,7 +399,7 @@ _IdentifyHardware( (instructionCount == 0) ? " (default)" : ""); /* Get the number of constants. */ - Identity->numConstants = numConstants; + Identity->numConstants = (numConstants == 0) ? 168 : numConstants; gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Specs: numConstants=%u%s", @@ -2344,25 +2335,32 @@ gckHARDWARE_ConvertLogical( gcmkVERIFY_ARGUMENT(Logical != gcvNULL); gcmkVERIFY_ARGUMENT(Address != gcvNULL); - /* Convert logical address into a physical address. */ - gcmkONERROR( - gckOS_GetPhysicalAddress(Hardware->os, Logical, &address)); +#if gcdVIRTUAL_COMMAND_BUFFER + status = gckKERNEL_GetGPUAddress(Hardware->kernel, Logical, Address); - /* For old MMU, get GPU address according to baseAddress. */ - if (Hardware->mmuVersion == 0) + if (status == gcvSTATUS_INVALID_ADDRESS) +#endif { - gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress)); + /* Convert logical address into a physical address. */ + gcmkONERROR( + gckOS_GetPhysicalAddress(Hardware->os, Logical, &address)); - /* Subtract base address to get a GPU address. */ - gcmkASSERT(address >= baseAddress); - address -= baseAddress; - } + /* For old MMU, get GPU address according to baseAddress. */ + if (Hardware->mmuVersion == 0) + { + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress)); - /* Return hardware specific address. */ - *Address = (Hardware->mmuVersion == 0) - ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) - : address; + /* Subtract base address to get a GPU address. */ + gcmkASSERT(address >= baseAddress); + address -= baseAddress; + } + + /* Return hardware specific address. */ + *Address = (Hardware->mmuVersion == 0) + ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) + : address; + } /* Success. */ gcmkFOOTER_ARG("*Address=0x%08x", *Address); @@ -2621,7 +2619,7 @@ gckHARDWARE_QuerySystemMemory( return gcvSTATUS_OK; } -#if !defined(VIVANTE_NO_3D) +#ifndef VIVANTE_NO_3D /******************************************************************************* ** ** gckHARDWARE_QueryShaderCaps @@ -3393,8 +3391,13 @@ gckHARDWARE_SetFastClear( /* Set fast clear bypass. */ debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))); - /* Set compression bypass. */ - debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21))) | (((gctUINT32) ((gctUINT32) (Compression == 0) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21))); + if ( + ((((gctUINT32) (Hardware->identity.chipMinorFeatures2)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) || + (Hardware->identity.chipModel >= gcv4000)) + { + /* Set compression bypass. */ + debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21))) | (((gctUINT32) ((gctUINT32) (Compression == 0) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21))); + } /* Write back AQMemoryDebug register. */ gcmkONERROR( @@ -5250,6 +5253,7 @@ gckHARDWARE_DumpMMUException( IN gckHARDWARE Hardware ) { +#if !gcdPOWER_SUSNPEND_WHEN_IDLE && !gcdPOWEROFF_TIMEOUT gctUINT32 mmu, mmuStatus, address, i; #if gcdDEBUG gctUINT32 mtlb, stlb, offset; @@ -5339,6 +5343,13 @@ gckHARDWARE_DumpMMUException( } gcmkFOOTER_NO(); +#else + /* If clock could be off automatically, we can't read mmu debug + ** register here; build driver with gcdPOWER_SUSPEND_WHEN_IDLE = 0 + ** and gcdPOWEROFF_TIMEOUT = 0 to make it safe to read mmu register. */ + gcmkPRINT("[galcore] %s(%d): MMU Exception!", __FUNCTION__, __LINE__); +#endif + return gcvSTATUS_OK; } diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c index 75ee7276fde7..ddccb4a4f700 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c @@ -220,6 +220,14 @@ gckKERNEL_Construct( /* Save context. */ kernel->context = Context; +#if gcdVIRTUAL_COMMAND_BUFFER + kernel->virtualBufferHead = + kernel->virtualBufferTail = gcvNULL; + + gcmkONERROR( + gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock)); +#endif + /* Construct atom holding number of clients. */ kernel->atomClients = gcvNULL; gcmkONERROR(gckOS_AtomConstruct(Os, &kernel->atomClients)); @@ -349,6 +357,14 @@ OnError: gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel->db)); } +#if gcdVIRTUAL_COMMAND_BUFFER + if (kernel->virtualBufferLock != gcvNULL) + { + /* Destroy the virtual command buffer mutex. */ + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->virtualBufferLock)); + } +#endif + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel)); } @@ -460,6 +476,10 @@ gckKERNEL_Destroy( /* Detsroy the client atom. */ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients)); +#if gcdVIRTUAL_COMMAND_BUFFER + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock)); +#endif + /* Mark the gckKERNEL object as unknown. */ Kernel->object.type = gcvOBJ_UNKNOWN; @@ -969,6 +989,27 @@ gckKERNEL_Dispatch( Interface->u.AllocateNonPagedMemory.bytes)); break; + case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER: +#if gcdVIRTUAL_COMMAND_BUFFER + gcmkONERROR( + gckKERNEL_AllocateVirtualCommandBuffer( + Kernel, + FromUser, + &Interface->u.AllocateVirtualCommandBuffer.bytes, + &Interface->u.AllocateVirtualCommandBuffer.physical, + &Interface->u.AllocateVirtualCommandBuffer.logical)); + + gcmkVERIFY_OK( + gckKERNEL_AddProcessDB(Kernel, + processID, gcvDB_COMMAND_BUFFER, + Interface->u.AllocateVirtualCommandBuffer.logical, + Interface->u.AllocateVirtualCommandBuffer.physical, + Interface->u.AllocateVirtualCommandBuffer.bytes)); +#else + status = gcvSTATUS_NOT_SUPPORTED; +#endif + break; + case gcvHAL_FREE_NON_PAGED_MEMORY: physical = Interface->u.FreeNonPagedMemory.physical; @@ -1338,7 +1379,7 @@ gckKERNEL_Dispatch( { gcmkONERROR( gckOS_SignalQueryHardware(Kernel->os, - (gctSIGNAL)Interface->u.UserSignal.id, + (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id, &hardware)); if (hardware) @@ -1390,8 +1431,8 @@ gckKERNEL_Dispatch( case gcvUSER_SIGNAL_MAP: gcmkONERROR( gckOS_MapSignal(Kernel->os, - (gctSIGNAL)Interface->u.UserSignal.id, - (gctHANDLE)processID, + (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id, + (gctHANDLE)(gctUINTPTR_T)processID, &signal)); gcmkVERIFY_OK( @@ -3082,7 +3123,253 @@ gckKERNEL_SetTimeOut( gcmkFOOTER_NO(); } +#if gcdVIRTUAL_COMMAND_BUFFER +gceSTATUS +gckKERNEL_AllocateVirtualCommandBuffer( + IN gckKERNEL Kernel, + IN gctBOOL InUserSpace, + IN OUT gctSIZE_T * Bytes, + OUT gctPHYS_ADDR * Physical, + OUT gctPOINTER * Logical + ) +{ + gckOS os = Kernel->os; + gceSTATUS status; + gctPOINTER logical; + gctSIZE_T pageCount; + gctSIZE_T bytes = *Bytes; + gckVIRTUAL_COMMAND_BUFFER_PTR buffer; + + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu", + os, InUserSpace, gcmOPT_VALUE(Bytes)); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(os, gcvOBJ_OS); + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL); + gcmkVERIFY_ARGUMENT(*Bytes > 0); + gcmkVERIFY_ARGUMENT(Physical != gcvNULL); + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); + + gcmkONERROR(gckOS_Allocate(os, + sizeof(gckVIRTUAL_COMMAND_BUFFER), + (gctPOINTER)&buffer)); + + gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER))); + + gcmkONERROR(gckOS_AllocatePagedMemoryEx(os, + gcvFALSE, + bytes, + &buffer->physical)); + + if (InUserSpace) + { + gcmkONERROR(gckOS_LockPages(os, + buffer->physical, + bytes, + gcvFALSE, + &logical, + &pageCount)); + + *Logical = + buffer->userLogical = logical; + } + else + { + gcmkONERROR( + gckOS_CreateKernelVirtualMapping(buffer->physical, + &pageCount, + &logical)); + *Logical = + buffer->kernelLogical = logical; + } + + buffer->pageCount = pageCount; + buffer->kernel = Kernel; + + gcmkONERROR(gckOS_GetProcessID(&buffer->pid)); + + gcmkONERROR(gckMMU_AllocatePages(Kernel->mmu, + pageCount, + &buffer->pageTable, + &buffer->gpuAddress)); + + gcmkONERROR(gckOS_MapPagesEx(os, + Kernel->core, + buffer->physical, + pageCount, + buffer->pageTable)); + + gcmkONERROR(gckMMU_Flush(Kernel->mmu)); + + *Physical = buffer; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL, + "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x", + buffer->gpuAddress, buffer->pageCount, + buffer->kernelLogical, buffer->userLogical); + + gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE)); + + if (Kernel->virtualBufferHead == gcvNULL) + { + Kernel->virtualBufferHead = + Kernel->virtualBufferTail = buffer; + } + else + { + buffer->prev = Kernel->virtualBufferTail; + Kernel->virtualBufferTail->next = buffer; + Kernel->virtualBufferTail = buffer; + } + + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock)); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (buffer->gpuAddress) + { + gcmkVERIFY_OK( + gckMMU_FreePages(Kernel->mmu, buffer->pageTable, buffer->pageCount)); + } + + if (buffer->userLogical) + { + gcmkVERIFY_OK( + gckOS_UnlockPages(os, buffer->physical, bytes, buffer->userLogical)); + } + + if (buffer->kernelLogical) + { + gcmkVERIFY_OK( + gckOS_DestroyKernelVirtualMapping(buffer->kernelLogical)); + } + + if (buffer->physical) + { + gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes)); + } + gcmkVERIFY_OK(gckOS_Free(os, buffer)); + + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckKERNEL_DestroyVirtualCommandBuffer( + IN gckKERNEL Kernel, + IN gctSIZE_T Bytes, + IN gctPHYS_ADDR Physical, + IN gctPOINTER Logical + ) +{ + gckOS os; + gckKERNEL kernel; + gckVIRTUAL_COMMAND_BUFFER_PTR buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical; + + gcmkHEADER(); + gcmkVERIFY_ARGUMENT(buffer != gcvNULL); + + kernel = buffer->kernel; + os = kernel->os; + + if (buffer->userLogical) + { + gcmkVERIFY_OK(gckOS_UnlockPages(os, buffer->physical, Bytes, Logical)); + } + else + { + gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(Logical)); + } + + gcmkVERIFY_OK( + gckMMU_FreePages(kernel->mmu, buffer->pageTable, buffer->pageCount)); + + gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, Bytes)); + + gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE)); + + if (buffer == kernel->virtualBufferHead) + { + if ((kernel->virtualBufferHead = buffer->next) == gcvNULL) + { + kernel->virtualBufferTail = gcvNULL; + } + } + else + { + buffer->prev->next = buffer->next; + + if (buffer == kernel->virtualBufferTail) + { + kernel->virtualBufferTail = buffer->prev; + } + else + { + buffer->next->prev = buffer->prev; + } + } + + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock)); + + gcmkVERIFY_OK(gckOS_Free(os, buffer)); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + +gceSTATUS +gckKERNEL_GetGPUAddress( + IN gckKERNEL Kernel, + IN gctPOINTER Logical, + OUT gctUINT32 * Address + ) +{ + gceSTATUS status; + gckVIRTUAL_COMMAND_BUFFER_PTR buffer; + gctPOINTER start; + gctINT pid; + + gcmkHEADER_ARG("Logical = %x", Logical); + + gckOS_GetProcessID(&pid); + + status = gcvSTATUS_INVALID_ADDRESS; + + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE)); + + /* Walk all command buffer. */ + for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next) + { + if (buffer->userLogical) + { + start = buffer->userLogical; + } + else + { + start = buffer->kernelLogical; + } + + if (Logical >= start + && (Logical < (start + buffer->pageCount * 4096)) + && pid == buffer->pid + ) + { + * Address = buffer->gpuAddress + (Logical - start); + status = gcvSTATUS_OK; + break; + } + } + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock)); + + gcmkFOOTER_NO(); + return status; +} +#endif /******************************************************************************* ***** Test Code **************************************************************** diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h index 1f3c9ccc20a8..908f925417b1 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h @@ -134,6 +134,7 @@ gcskSECURE_CACHE; typedef enum _gceDATABASE_TYPE { gcvDB_VIDEO_MEMORY = 1, /* Video memory created. */ + gcvDB_COMMAND_BUFFER, /* Command Buffer. */ gcvDB_NON_PAGED, /* Non paged memory. */ gcvDB_CONTIGUOUS, /* Contiguous memory. */ gcvDB_SIGNAL, /* Signal. */ @@ -292,6 +293,24 @@ struct _gckDB gctUINT64 lastSlowdownIdle; }; +#if gcdVIRTUAL_COMMAND_BUFFER +typedef struct _gckVIRTUAL_COMMAND_BUFFER * gckVIRTUAL_COMMAND_BUFFER_PTR; +typedef struct _gckVIRTUAL_COMMAND_BUFFER +{ + gctPHYS_ADDR physical; + gctPOINTER userLogical; + gctPOINTER kernelLogical; + gctSIZE_T pageCount; + gctPOINTER pageTable; + gctUINT32 gpuAddress; + gctUINT pid; + gckVIRTUAL_COMMAND_BUFFER_PTR next; + gckVIRTUAL_COMMAND_BUFFER_PTR prev; + gckKERNEL kernel; +} +gckVIRTUAL_COMMAND_BUFFER; +#endif + /* gckKERNEL object. */ struct _gckKERNEL { @@ -350,6 +369,12 @@ struct _gckKERNEL #if gcdENABLE_VG gckVGKERNEL vg; #endif + +#if gcdVIRTUAL_COMMAND_BUFFER + gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferHead; + gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferTail; + gctPOINTER virtualBufferLock; +#endif }; /* gckCOMMAND object. */ @@ -452,6 +477,8 @@ typedef struct _gcsEVENT /* Kernel. */ gckKERNEL kernel; #endif + + gctBOOL fromKernel; } gcsEVENT; @@ -735,6 +762,44 @@ struct _gckMMU #endif }; +#if gcdVIRTUAL_COMMAND_BUFFER +gceSTATUS +gckOS_CreateKernelVirtualMapping( + IN gctPHYS_ADDR Physical, + OUT gctSIZE_T * PageCount, + OUT gctPOINTER * Logical + ); + +gceSTATUS +gckOS_DestroyKernelVirtualMapping( + IN gctPOINTER Logical + ); + +gceSTATUS +gckKERNEL_AllocateVirtualCommandBuffer( + IN gckKERNEL Kernel, + IN gctBOOL InUserSpace, + IN OUT gctSIZE_T * Bytes, + OUT gctPHYS_ADDR * Physical, + OUT gctPOINTER * Logical + ); + +gceSTATUS +gckKERNEL_DestroyVirtualCommandBuffer( + IN gckKERNEL Kernel, + IN gctSIZE_T Bytes, + IN gctPHYS_ADDR Physical, + IN gctPOINTER Logical + ); + +gceSTATUS +gckKERNEL_GetGPUAddress( + IN gckKERNEL Kernel, + IN gctPOINTER Logical, + OUT gctUINT32 * Address + ); +#endif + gceSTATUS gckKERNEL_AttachProcess( IN gckKERNEL Kernel, diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c index fbaff6666a10..f350f451882d 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c @@ -1971,7 +1971,7 @@ gckCOMMAND_Commit( /* Append event record to event queue. */ gcmkONERROR(gckEVENT_AddList( - Command->kernel->eventObj, &eventRecord->iface, gcvKERNEL_PIXEL, gcvTRUE + Command->kernel->eventObj, &eventRecord->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE )); /* Next record in the queue. */ diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c index e5b659262a46..b3e28ec09d80 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c @@ -915,7 +915,7 @@ _HardwareToKernel( } offset = Address - nodePhysical; - *KernelPointer = (gctPOINTER)((gctUINT32)Node->VidMem.kernelVirtual + offset); + *KernelPointer = (gctPOINTER)((gctUINT8_PTR)Node->VidMem.kernelVirtual + offset); #else /* Determine the header offset within the pool it is allocated in. */ offset = Address - memory->baseAddress; diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c index 9dbb9d3cab25..9ab599b1da9f 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c @@ -1161,6 +1161,21 @@ gckKERNEL_DestroyProcessDB( record->data, record->bytes, status); break; +#if gcdVIRTUAL_COMMAND_BUFFER + case gcvDB_COMMAND_BUFFER: + /* Free the command buffer. */ + status = gckEVENT_DestroyVirtualCommandBuffer(record->kernel->eventObj, + record->bytes, + record->physical, + record->data, + gcvKERNEL_PIXEL); + + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE, + "DB: COMMAND_BUFFER 0x%x, bytes=%lu (status=%d)", + record->data, record->bytes, status); + break; +#endif + case gcvDB_CONTIGUOUS: /* Unmap user logical memory first. */ status = gckOS_UnmapUserLogical(Kernel->os, @@ -1191,7 +1206,7 @@ gckKERNEL_DestroyProcessDB( gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE, "DB: SIGNAL %d (status=%d)", - (gctINT) record->data, status); + (gctINT)(gctUINTPTR_T)record->data, status); break; case gcvDB_VIDEO_MEMORY_LOCKED: diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c index d38312d3bf9b..75647c0a4315 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c @@ -286,6 +286,21 @@ __RemoveRecordFromProcessDB( while (Record != gcvNULL) { + if (Record->info.command == gcvHAL_SIGNAL) + { + /* TODO: Find a better place to bind signal to hardware.*/ + gcmkVERIFY_OK(gckOS_SignalSetHardware(Event->os, + Record->info.u.Signal.signal, + Event->kernel->hardware)); + } + + if (Record->fromKernel) + { + /* No need to check db if event is from kernel. */ + Record = Record->next; + continue; + } + switch (Record->info.command) { case gcvHAL_FREE_NON_PAGED_MEMORY: @@ -328,10 +343,12 @@ __RemoveRecordFromProcessDB( Record->info.u.UnmapUserMemory.info)); break; - case gcvHAL_SIGNAL: - gcmkVERIFY_OK(gckOS_SignalSetHardware(Event->os, - Record->info.u.Signal.signal, - Event->kernel->hardware)); + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER: + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( + Event->kernel, + Record->processID, + gcvDB_COMMAND_BUFFER, + Record->info.u.FreeVirtualCommandBuffer.logical)); break; default: @@ -883,7 +900,8 @@ gckEVENT_AddList( IN gckEVENT Event, IN gcsHAL_INTERFACE_PTR Interface, IN gceKERNEL_WHERE FromWhere, - IN gctBOOL AllocateAllowed + IN gctBOOL AllocateAllowed, + IN gctBOOL FromKernel ) { gceSTATUS status; @@ -913,6 +931,7 @@ gckEVENT_AddList( || (Interface->command == gcvHAL_UNMAP_USER_MEMORY) || (Interface->command == gcvHAL_TIMESTAMP) || (Interface->command == gcvHAL_COMMIT_DONE) + || (Interface->command == gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER) ); /* Validate the source. */ @@ -928,6 +947,9 @@ gckEVENT_AddList( /* Termninate the record. */ record->next = gcvNULL; + /* Record the committer. */ + record->fromKernel = FromKernel; + /* Copy the event interface into the record. */ gcmkONERROR(gckOS_MemCopy(&record->info, Interface, gcmSIZEOF(record->info))); @@ -1081,7 +1103,7 @@ gckEVENT_Unlock( iface.u.UnlockVideoMemory.asynchroneous = 0; /* Append it to the queue. */ - gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE)); + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE)); /* Success. */ gcmkFOOTER_NO(); @@ -1136,7 +1158,7 @@ gckEVENT_FreeVideoMemory( iface.u.FreeVideoMemory.node = VideoMemory; /* Append it to the queue. */ - gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE)); + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE)); /* Success. */ gcmkFOOTER_NO(); @@ -1200,7 +1222,48 @@ gckEVENT_FreeNonPagedMemory( iface.u.FreeNonPagedMemory.logical = Logical; /* Append it to the queue. */ - gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE)); + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE)); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckEVENT_DestroyVirtualCommandBuffer( + IN gckEVENT Event, + IN gctSIZE_T Bytes, + IN gctPHYS_ADDR Physical, + IN gctPOINTER Logical, + IN gceKERNEL_WHERE FromWhere + ) +{ + gceSTATUS status; + gcsHAL_INTERFACE iface; + + gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x " + "FromWhere=%d", + Event, Bytes, Physical, Logical, FromWhere); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT); + gcmkVERIFY_ARGUMENT(Physical != gcvNULL); + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); + gcmkVERIFY_ARGUMENT(Bytes > 0); + + /* Create an event. */ + iface.command = gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER; + iface.u.FreeVirtualCommandBuffer.bytes = Bytes; + iface.u.FreeVirtualCommandBuffer.physical = Physical; + iface.u.FreeVirtualCommandBuffer.logical = Logical; + + /* Append it to the queue. */ + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE)); /* Success. */ gcmkFOOTER_NO(); @@ -1264,7 +1327,7 @@ gckEVENT_FreeContiguousMemory( iface.u.FreeContiguousMemory.logical = Logical; /* Append it to the queue. */ - gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE)); + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE)); /* Success. */ gcmkFOOTER_NO(); @@ -1325,7 +1388,7 @@ gckEVENT_Signal( iface.u.Signal.process = gcvNULL; /* Append it to the queue. */ - gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE)); + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE)); /* Success. */ gcmkFOOTER_NO(); @@ -1372,7 +1435,7 @@ gckEVENT_CommitDone( iface.command = gcvHAL_COMMIT_DONE; /* Append it to the queue. */ - gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE)); + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE)); /* Success. */ gcmkFOOTER_NO(); @@ -1624,7 +1687,7 @@ gckEVENT_Commit( /* Append event record to event queue. */ gcmkONERROR( - gckEVENT_AddList(Event, &record->iface, gcvKERNEL_PIXEL, gcvTRUE)); + gckEVENT_AddList(Event, &record->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE)); /* Next record in the queue. */ next = record->next; @@ -2381,6 +2444,17 @@ gckEVENT_Notify( } break; +#if gcdVIRTUAL_COMMAND_BUFFER + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER: + gcmkVERIFY_OK( + gckKERNEL_DestroyVirtualCommandBuffer(Event->kernel, + record->info.u.FreeVirtualCommandBuffer.bytes, + record->info.u.FreeVirtualCommandBuffer.physical, + record->info.u.FreeVirtualCommandBuffer.logical + )); + break; +#endif + case gcvHAL_COMMIT_DONE: break; @@ -2714,6 +2788,11 @@ _PrintRecord( gcmkPRINT(" gcvHAL_COMMIT_DONE"); break; + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER: + gcmkPRINT(" gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER logical=0x%08x", + record->info.u.FreeVirtualCommandBuffer.logical); + break; + default: gcmkPRINT(" Illegal Event %d", record->info.command); break; diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c index 9012599b1bef..72e2b4f8f308 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c @@ -78,6 +78,25 @@ gcsSharedPageTable; static gcsSharedPageTable_PTR sharedPageTable = gcvNULL; #endif +#if gcdMIRROR_PAGETABLE +typedef struct _gcsMirrorPageTable * gcsMirrorPageTable_PTR; +typedef struct _gcsMirrorPageTable +{ + /* gckMMU objects. */ + gckMMU mmus[gcdMAX_GPU_COUNT]; + + /* Hardwares which use this shared pagetable. */ + gckHARDWARE hardwares[gcdMAX_GPU_COUNT]; + + /* Number of cores use this shared pagetable. */ + gctUINT32 reference; +} +gcsMirrorPageTable; + +static gcsMirrorPageTable_PTR mirrorPageTable = gcvNULL; +static gctPOINTER mirrorPageTableMutex = gcvNULL; +#endif + static gceSTATUS _FillPageTable( IN gctUINT32_PTR PageTable, @@ -873,6 +892,47 @@ OnError: gcmkFOOTER(); return status; +#elif gcdMIRROR_PAGETABLE + gceSTATUS status; + gctPOINTER pointer; + + gcmkHEADER_ARG("Kernel=0x%08x", Kernel); + + if (mirrorPageTable == gcvNULL) + { + gcmkONERROR( + gckOS_Allocate(Kernel->os, + sizeof(struct _gcsMirrorPageTable), + &pointer)); + mirrorPageTable = pointer; + + gcmkONERROR( + gckOS_ZeroMemory(mirrorPageTable, + sizeof(struct _gcsMirrorPageTable))); + + gcmkONERROR( + gckOS_CreateMutex(Kernel->os, &mirrorPageTableMutex)); + } + + gcmkONERROR(_Construct(Kernel, MmuSize, Mmu)); + + mirrorPageTable->mmus[mirrorPageTable->reference] = *Mmu; + + mirrorPageTable->hardwares[mirrorPageTable->reference] = Kernel->hardware; + + mirrorPageTable->reference++; + + gcmkFOOTER_ARG("mirrorPageTable->reference=%lu", mirrorPageTable->reference); + return gcvSTATUS_OK; + +OnError: + if (mirrorPageTable && mirrorPageTable->reference == 0) + { + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, mirrorPageTable)); + } + + gcmkFOOTER(); + return status; #else return _Construct(Kernel, MmuSize, Mmu); #endif @@ -897,6 +957,16 @@ gckMMU_Destroy( } return gcvSTATUS_OK; +#elif gcdMIRROR_PAGETABLE + mirrorPageTable->reference--; + + if (mirrorPageTable->reference == 0) + { + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTable)); + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTableMutex)); + } + + return _Destroy(Mmu); #else return _Destroy(Mmu); #endif @@ -926,7 +996,7 @@ gckMMU_Destroy( ** Pointer to a variable that receives the hardware specific address. */ gceSTATUS -gckMMU_AllocatePages( +_AllocatePages( IN gckMMU Mmu, IN gctSIZE_T PageCount, OUT gctPOINTER * PageTable, @@ -949,6 +1019,9 @@ gckMMU_AllocatePages( if (PageCount > Mmu->pageTableEntries) { + gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.", + __FUNCTION__, __LINE__); + /* Not enough pages avaiable. */ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } @@ -1010,6 +1083,9 @@ gckMMU_AllocatePages( } else { + gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.", + __FUNCTION__, __LINE__); + /* Out of resources. */ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } @@ -1122,7 +1198,7 @@ OnError: ** Nothing. */ gceSTATUS -gckMMU_FreePages( +_FreePages( IN gckMMU Mmu, IN gctPOINTER PageTable, IN gctSIZE_T PageCount @@ -1191,6 +1267,90 @@ OnError: } gceSTATUS +gckMMU_AllocatePages( + IN gckMMU Mmu, + IN gctSIZE_T PageCount, + OUT gctPOINTER * PageTable, + OUT gctUINT32 * Address + ) +{ +#if gcdMIRROR_PAGETABLE + gceSTATUS status; + gctPOINTER pageTable; + gctUINT32 address; + gctINT i; + gckMMU mmu; + + gckOS_AcquireMutex(Mmu->os, mirrorPageTableMutex, gcvINFINITE); + + /* Allocate page table for current MMU. */ + for (i = 0; i < mirrorPageTable->reference; i++) + { + if (Mmu == mirrorPageTable->mmus[i]) + { + gcmkONERROR(_AllocatePages(Mmu, PageCount, PageTable, Address)); + } + } + + /* Allocate page table for other MMUs. */ + for (i = 0; i < mirrorPageTable->reference; i++) + { + mmu = mirrorPageTable->mmus[i]; + + if (Mmu != mmu) + { + gcmkONERROR(_AllocatePages(mmu, PageCount, &pageTable, &address)); + gcmkASSERT(address == *Address); + } + } + + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex); + + return gcvSTATUS_OK; +OnError: + return status; +#else + return _AllocatePages(Mmu, PageCount, PageTable, Address); +#endif +} + +gceSTATUS +gckMMU_FreePages( + IN gckMMU Mmu, + IN gctPOINTER PageTable, + IN gctSIZE_T PageCount + ) +{ +#if gcdMIRROR_PAGETABLE + gctINT i; + gctUINT32 offset; + gckMMU mmu; + + gckOS_AcquireMutex(Mmu->os, mirrorPageTableMutex, gcvINFINITE); + + gcmkVERIFY_OK(_FreePages(Mmu, PageTable, PageCount)); + + offset = (gctUINT32)PageTable - (gctUINT32)Mmu->pageTableLogical; + + for (i = 0; i < mirrorPageTable->reference; i++) + { + mmu = mirrorPageTable->mmus[i]; + + if (mmu != Mmu) + { + gcmkVERIFY_OK(_FreePages(mmu, mmu->pageTableLogical + offset/4, PageCount)); + } + } + + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex); + + return gcvSTATUS_OK; +#else + return _FreePages(Mmu, PageTable, PageCount); +#endif +} + +gceSTATUS gckMMU_Enable( IN gckMMU Mmu, IN gctUINT32 PhysBaseAddr, @@ -1284,6 +1444,14 @@ gckMMU_SetPage( IN gctUINT32 *PageEntry ) { +#if gcdMIRROR_PAGETABLE + gctUINT32_PTR pageEntry; + gctINT i; + gckMMU mmu; + gctUINT32 offset = (gctUINT32)PageEntry - (gctUINT32)Mmu->pageTableLogical; +#endif + + gctUINT32 data; gcmkHEADER_ARG("Mmu=0x%x", Mmu); /* Verify the arguments. */ @@ -1293,13 +1461,40 @@ gckMMU_SetPage( if (Mmu->hardware->mmuVersion == 0) { - *PageEntry = PageAddress; + data = PageAddress; } else { - *PageEntry = _SetPage(PageAddress); + data = _SetPage(PageAddress); + } + + if (Mmu->hardware->bigEndian) + { + data = gcmSWAB32(data); } + *PageEntry = data; +#if gcdMIRROR_PAGETABLE + for (i = 0; i < mirrorPageTable->reference; i++) + { + mmu = mirrorPageTable->mmus[i]; + + if (mmu != Mmu) + { + pageEntry = mmu->pageTableLogical + offset / 4; + + if (Mmu->hardware->mmuVersion == 0) + { + *pageEntry = PageAddress; + } + else + { + *pageEntry = _SetPage(PageAddress); + } + } + + } +#endif /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -1453,6 +1648,16 @@ gckMMU_Flush( gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1)); } } +#elif gcdMIRROR_PAGETABLE + gctINT i; + for (i = 0; i < mirrorPageTable->reference; i++) + { + hardware = mirrorPageTable->hardwares[i]; + + /* Notify cores who use this page table. */ + gcmkVERIFY_OK( + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1)); + } #else hardware = Mmu->hardware; gcmkVERIFY_OK( diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h index 5bf887054e04..5b90e2f8ec60 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h @@ -2114,7 +2114,8 @@ gckEVENT_AddList( IN gckEVENT Event, IN gcsHAL_INTERFACE_PTR Interface, IN gceKERNEL_WHERE FromWhere, - IN gctBOOL AllocateAllowed + IN gctBOOL AllocateAllowed, + IN gctBOOL FromKernel ); /* Schedule a FreeNonPagedMemory event. */ @@ -2168,6 +2169,18 @@ gckEVENT_CommitDone( IN gceKERNEL_WHERE FromWhere ); +#if gcdVIRTUAL_COMMAND_BUFFER +/* Schedule a FreeVirtualCommandBuffer event. */ +gceSTATUS +gckEVENT_DestroyVirtualCommandBuffer( + IN gckEVENT Event, + IN gctSIZE_T Bytes, + IN gctPHYS_ADDR Physical, + IN gctPOINTER Logical, + IN gceKERNEL_WHERE FromWhere + ); +#endif + gceSTATUS gckEVENT_Submit( IN gckEVENT Event, diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h index 8d50c977a95d..a089280c7ea5 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h @@ -340,6 +340,14 @@ struct _gcsHINT /* Flag whether the VS has point size or not. */ gctBOOL vsHasPointSize; +#if gcdUSE_WCLIP_PATCH + /* Flag whether the VS gl_position.z depends on gl_position.w + it's a hint for wclipping */ + gctBOOL vsPositionZDependsOnW; +#endif + + gctBOOL clipW; + /* Element count. */ gctUINT32 elementCount; @@ -511,6 +519,12 @@ typedef enum _gceSHADER_FLAGS } gceSHADER_FLAGS; +gceSTATUS +gcSHADER_CheckClipW( + IN gctCONST_STRING VertexSource, + IN gctCONST_STRING FragmentSource, + OUT gctBOOL * clipW); + /* Function argument qualifier */ typedef enum _gceINPUT_OUTPUT { @@ -2527,6 +2541,14 @@ gcSHADER_CheckValidity( IN gcSHADER Shader ); +#if gcdUSE_WCLIP_PATCH +gceSTATUS +gcATTRIBUTE_IsPosition( + IN gcATTRIBUTE Attribute, + OUT gctBOOL * IsPosition + ); +#endif + /******************************************************************************* ** gcATTRIBUTE_GetType ******************************************************************************** diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h index 898bfb137a02..30b6b1858f2d 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h @@ -155,6 +155,10 @@ typedef enum _gceHAL_COMMAND_CODES gcvHAL_DUMP_GPU_STATE, gcvHAL_DUMP_EVENT, + /* Virtual command buffer. */ + gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER, + gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER, + /* FSCALE_VAL. */ gcvHAL_SET_FSCALE_VALUE, gcvHAL_GET_FSCALE_VALUE @@ -475,6 +479,34 @@ typedef struct _gcsHAL_INTERFACE } FreeNonPagedMemory; + /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */ + struct _gcsHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER + { + /* Number of bytes to allocate. */ + IN OUT gctSIZE_T bytes; + + /* Physical address of allocation. */ + OUT gctPHYS_ADDR physical; + + /* Logical address of allocation. */ + OUT gctPOINTER logical; + } + AllocateVirtualCommandBuffer; + + /* gcvHAL_FREE_NON_PAGED_MEMORY */ + struct _gcsHAL_FREE_VIRTUAL_COMMAND_BUFFER + { + /* Number of bytes allocated. */ + IN gctSIZE_T bytes; + + /* Physical address of allocation. */ + IN gctPHYS_ADDR physical; + + /* Logical address of allocation. */ + IN gctPOINTER logical; + } + FreeVirtualCommandBuffer; + /* gcvHAL_EVENT_COMMIT. */ struct _gcsHAL_EVENT_COMMIT { diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h index 86ab105b389a..f7934ea45e94 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h @@ -45,6 +45,12 @@ typedef struct __BITFIELDINFO{ RGBQUAD bmiColors[2]; } BITFIELDINFO; +#elif defined(LINUX) && defined(EGL_API_DFB) && !defined(__APPLE__) +#include <directfb.h> +typedef IDirectFB * HALNativeDisplayType; +typedef IDirectFBWindow * HALNativeWindowType; +typedef struct _DFBPixmap * HALNativePixmapType; + #elif defined(LINUX) && defined(EGL_API_FB) && !defined(__APPLE__) #if defined(EGL_API_WL) diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h index 7400b3201b91..bbfdbc66c8e7 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h @@ -1221,6 +1221,13 @@ gco3D_SetWPlaneLimitX( IN gctFIXED_POINT Value ); + +gceSTATUS +gco3D_SetWPlaneLimit( + IN gco3D Engine, + IN gctFLOAT Value + ); + /*----------------------------------------------------------------------------*/ /*-------------------------- gco3D Fragment Processor ------------------------*/ @@ -1478,6 +1485,14 @@ gcoTEXTURE_UploadCompressedSub( IN gctSIZE_T Size ); +/* GetImageFormat of texture. */ +gceSTATUS +gcoTEXTURE_GetImageFormat( + IN gcoTEXTURE Texture, + IN gctUINT MipMap, + OUT gctINT * ImageFormat + ); + /* Get gcoSURF object for a mipmap level. */ gceSTATUS gcoTEXTURE_GetMipMap( @@ -1779,6 +1794,10 @@ typedef struct _gcsVERTEXARRAY /* Vertex shader linkage. */ gctUINT linkage; + +#if gcdUSE_WCLIP_PATCH + gctBOOL isPosition; +#endif } gcsVERTEXARRAY, * gcsVERTEXARRAY_PTR; @@ -1805,7 +1824,13 @@ gcoVERTEXARRAY_Bind( IN gcoINDEX IndexObject, IN gctPOINTER IndexMemory, IN OUT gcePRIMITIVE * PrimitiveType, +#if gcdUSE_WCLIP_PATCH + IN OUT gctUINT * PrimitiveCount, + IN OUT gctFLOAT * wLimitRms, + IN OUT gctBOOL * wLimitDirty +#else IN OUT gctUINT * PrimitiveCount +#endif ); gctUINT diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h index d951c3a965d9..67ad54fce5a4 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h @@ -146,6 +146,8 @@ typedef enum _gceFEATURE gcvFEATURE_PE_DITHER_FIX, gcvFEATURE_2D_YUV_SEPARATE_STRIDE, gcvFEATURE_FRUSTUM_CLIP_FIX, + gcvFEATURE_TEXTURE_LINEAR, + gcvFEATURE_TEXTURE_YUV_ASSEMBLER, } gceFEATURE; @@ -477,6 +479,17 @@ typedef enum _gceSURF_ALIGNMENT } gceSURF_ALIGNMENT; + +/* Surface Addressing. */ +typedef enum _gceSURF_ADDRESSING +{ + gcvSURF_NO_STRIDE_TILED = 0, + gcvSURF_NO_STRIDE_LINEAR, + gcvSURF_STRIDE_TILED, + gcvSURF_STRIDE_LINEAR +} +gceSURF_ADDRESSING; + /* Transparency modes. */ typedef enum _gce2D_TRANSPARENCY { diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h index 33fddfbbfed2..8b00ccd65a71 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h @@ -153,6 +153,15 @@ #endif /* + gcdVIRTUAL_COMMAND_BUFFER + When set to 1, user command buffer and context buffer will be allocated + from gcvPOOL_VIRTUAL. +*/ +#ifndef gcdVIRTUAL_COMMAND_BUFFER +# define gcdVIRTUAL_COMMAND_BUFFER 0 +#endif + +/* gcdENABLE_FSCALE_VAL_ADJUST When non-zero, FSCALE_VAL when gcvPOWER_ON can be adjusted externally. */ @@ -267,14 +276,28 @@ #endif /* + gcdMIRROR_PAGETABLE + + Enable it when GPUs with old MMU and new MMU exist at same SoC. It makes + each GPU use same virtual address to access same physical memory. +*/ +#ifndef gcdMIRROR_PAGETABLE +# define gcdMIRROR_PAGETABLE 0 +#endif + +/* gcdMMU_SIZE Size of the MMU page table in bytes. Each 4 bytes can hold 4kB worth of virtual data. */ #ifndef gcdMMU_SIZE +#if gcdMIRROR_PAGETABLE +# define gcdMMU_SIZE 0x200000 +#else # define gcdMMU_SIZE (2048 << 10) #endif +#endif /* gcdSECURE_USER diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h index e3ceadfce7ee..d9b29933ced6 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h @@ -954,7 +954,7 @@ gceSTATUS gco2D_SetStateU32( IN gco2D Engine, IN gce2D_STATE State, - IN OUT gctUINT32_PTR Value + IN gctUINT32 Value ); #ifdef __cplusplus diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h index 4e063776cd44..f3d6fad30f42 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h @@ -146,6 +146,7 @@ typedef unsigned char gctUINT8; typedef unsigned short gctUINT16; typedef unsigned int gctUINT32; typedef unsigned long long gctUINT64; +typedef unsigned long gctUINTPTR_T; typedef gctUINT * gctUINT_PTR; typedef gctUINT8 * gctUINT8_PTR; @@ -889,6 +890,12 @@ gceSTATUS; gcmPTR2INT(& (((struct s *) 0)->field)) \ ) +#define gcmSWAB32(x) ((gctUINT32)( \ + (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \ + (((gctUINT32)(x) & (gctUINT32)0x0000FF00UL) << 8) | \ + (((gctUINT32)(x) & (gctUINT32)0x00FF0000UL) >> 8) | \ + (((gctUINT32)(x) & (gctUINT32)0xFF000000UL) >> 24))) + /******************************************************************************* ***** Database ****************************************************************/ diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c index 5a21a94ed7fd..99d7d9a3600a 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c @@ -167,7 +167,7 @@ static gcsDebugFileSystem gc_dbgfs ; static caddr_t _ReadFromNode ( gcsDebugFileSystemNode* Node , - int *Length , + size_t *Length , loff_t *Offset ) { diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c index eba81b64be92..27c1e6fb7ef8 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c @@ -694,7 +694,7 @@ gckGALDEVICE_Construct( gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } - device->internalPhysical = (gctPHYS_ADDR) physical; + device->internalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical; physical += device->internalSize; } } @@ -724,7 +724,7 @@ gckGALDEVICE_Construct( gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } - device->externalPhysical = (gctPHYS_ADDR) physical; + device->externalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical; physical += device->externalSize; } } @@ -840,7 +840,7 @@ gckGALDEVICE_Construct( } #endif - device->contiguousPhysical = (gctPHYS_ADDR) ContiguousBase; + device->contiguousPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) ContiguousBase; device->contiguousSize = ContiguousSize; device->contiguousMapped = gcvTRUE; } diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c index b326463b8133..c7928dd3a6f9 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c @@ -650,7 +650,7 @@ static int drv_mmap( ret = io_remap_pfn_range( vma, vma->vm_start, - (gctUINT32) device->contiguousPhysical >> PAGE_SHIFT, + (gctUINTPTR_T) device->contiguousPhysical >> PAGE_SHIFT, size, vma->vm_page_prot ); diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c index 22e8da4b0382..8f2346d4ee83 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c @@ -582,7 +582,7 @@ _CreateMdl( gcmkHEADER_ARG("ProcessID=%d", ProcessID); - mdl = (PLINUX_MDL)kmalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | __GFP_NOWARN); + mdl = (PLINUX_MDL)kzalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | __GFP_NOWARN); if (mdl == gcvNULL) { gcmkFOOTER_NO(); @@ -1408,39 +1408,60 @@ gckOS_Destroy( return gcvSTATUS_OK; } -#ifdef NO_DMA_COHERENT static gctSTRING _CreateKernelVirtualMapping( - IN struct page * Page, - IN gctINT NumPages + IN PLINUX_MDL Mdl ) { gctSTRING addr = 0; + gctINT numPages = Mdl->numPages; #if gcdNONPAGED_MEMORY_CACHEABLE - addr = page_address(Page); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) + if (Mdl->contiguous) + { + addr = page_address(Mdl->u.contiguousPages); + } + else + { + addr = vmap(Mdl->u.nonContiguousPages, + numPages, + 0, + PAGE_KERNEL); + } +#else struct page ** pages; + gctBOOL free = gcvFALSE; gctINT i; - pages = kmalloc(sizeof(struct page *) * NumPages, GFP_KERNEL | __GFP_NOWARN); - - if (!pages) + if (Mdl->contiguous) { - return gcvNULL; - } + pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | __GFP_NOWARN); - for (i = 0; i < NumPages; i++) + if (!pages) + { + return gcvNULL; + } + + for (i = 0; i < numPages; i++) + { + pages[i] = nth_page(Mdl->u.contiguousPages, i); + } + + free = gcvTRUE; + } + else { - pages[i] = nth_page(Page, i); + pages = Mdl->u.nonContiguousPages; } /* ioremap() can't work on system memory since 2.6.38. */ - addr = vmap(pages, NumPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL)); + addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL)); + + if (free) + { + kfree(pages); + } - kfree(pages); -#else - addr = gcmkIOREMAP(page_to_phys(Page), NumPages * PAGE_SIZE); #endif return addr; @@ -1452,14 +1473,31 @@ _DestoryKernelVirtualMapping( ) { #if !gcdNONPAGED_MEMORY_CACHEABLE -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) vunmap(Addr); -# else - iounmap(Addr); -# endif #endif } -#endif + +gceSTATUS +gckOS_CreateKernelVirtualMapping( + IN gctPHYS_ADDR Physical, + OUT gctSIZE_T * PageCount, + OUT gctPOINTER * Logical + ) +{ + *PageCount = ((PLINUX_MDL)Physical)->numPages; + *Logical = _CreateKernelVirtualMapping((PLINUX_MDL)Physical); + + return gcvSTATUS_OK; +} + +gceSTATUS +gckOS_DestroyKernelVirtualMapping( + IN gctPOINTER Logical + ) +{ + _DestoryKernelVirtualMapping((gctSTRING)Logical); + return gcvSTATUS_OK; +} /******************************************************************************* ** @@ -2136,7 +2174,9 @@ gckOS_AllocateNonPagedMemory( } vaddr = (gctPOINTER)page_address(page); - addr = _CreateKernelVirtualMapping(page, mdl->numPages); + mdl->contiguous = gcvTRUE; + mdl->u.contiguousPages = page; + addr = _CreateKernelVirtualMapping(mdl); mdl->dmaHandle = virt_to_phys(vaddr); mdl->kaddr = vaddr; mdl->u.contiguousPages = page; @@ -3438,7 +3478,7 @@ gckOS_AtomicExchangePtr( gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); /* Exchange the pair of pointers. */ - *OldValue = (gctPOINTER) atomic_xchg((atomic_t *) Target, (int) NewValue); + *OldValue = (gctPOINTER)(gctUINTPTR_T) atomic_xchg((atomic_t *) Target, (int)(gctUINTPTR_T) NewValue); /* Success. */ gcmkFOOTER_ARG("*OldValue=0x%X", *OldValue); @@ -4343,8 +4383,8 @@ gckOS_LockPages( gcvLEVEL_INFO, gcvZONE_OS, "%s(%d): vmaAddr->0x%X for phys_addr->0x%X", __FUNCTION__, __LINE__, - (gctUINT32) mdlMap->vmaAddr, - (gctUINT32) mdl + (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr, + (gctUINT32)(gctUINTPTR_T)mdl ); if (IS_ERR(mdlMap->vmaAddr)) @@ -4441,10 +4481,10 @@ gckOS_LockPages( gcvLEVEL_INFO, gcvZONE_OS, "%s(%d): gctPHYS_ADDR->0x%X Logical->0x%X Unable to map addr->0x%X to start->0x%X", __FUNCTION__, __LINE__, - (gctUINT32) Physical, - (gctUINT32) *Logical, - (gctUINT32) addr, - (gctUINT32) start + (gctUINT32)(gctUINTPTR_T)Physical, + (gctUINT32)(gctUINTPTR_T)*Logical, + (gctUINT32)(gctUINTPTR_T)addr, + (gctUINT32)(gctUINTPTR_T)start ); mdlMap->vmaAddr = gcvNULL; @@ -4571,8 +4611,8 @@ gckOS_MapPagesEx( gcvLEVEL_INFO, gcvZONE_OS, "%s(%d): Physical->0x%X PageCount->0x%X PagedMemory->?%d", __FUNCTION__, __LINE__, - (gctUINT32) Physical, - (gctUINT32) PageCount, + (gctUINT32)(gctUINTPTR_T)Physical, + (gctUINT32)(gctUINTPTR_T)PageCount, mdl->pagedMem ); @@ -5430,7 +5470,7 @@ OnError: gctSIZE_T pageCount, i, j; gctUINT32_PTR pageTable; gctUINT32 address = 0, physical = ~0U; - gctUINT32 start, end, memory; + gctUINTPTR_T start, end, memory; gctUINT32 offset; gctINT result = 0; @@ -5446,7 +5486,7 @@ OnError: do { - memory = (gctUINT32) Memory; + memory = (gctUINTPTR_T) Memory; /* Get the number of required pages. */ end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT; @@ -5604,7 +5644,7 @@ OnError: { /* Flush(clean) the data cache. */ gcmkONERROR(gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL, - (gctPOINTER)(physical & PAGE_MASK), + (gctPOINTER)(gctUINTPTR_T)(physical & PAGE_MASK), (gctPOINTER)(memory & PAGE_MASK), PAGE_SIZE * pageCount)); } @@ -5844,7 +5884,7 @@ OnError: return status; #else { - gctUINT32 memory, start, end; + gctUINTPTR_T memory, start, end; gcsPageInfo_PTR info; gctSIZE_T pageCount, i; struct page **pages; @@ -5877,7 +5917,7 @@ OnError: return gcvSTATUS_OK; } - memory = (gctUINT32) Memory; + memory = (gctUINTPTR_T)Memory; end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT; start = memory >> PAGE_SHIFT; pageCount = end - start; @@ -6183,7 +6223,7 @@ _HandleOuterCache( else { /* Non contiguous virtual memory */ - vaddr = (gctPOINTER)gcmALIGN_BASE((gctUINT32)Logical, PAGE_SIZE); + vaddr = (gctPOINTER)gcmALIGN_BASE((gctUINTPTR_T)Logical, PAGE_SIZE); pageNum = GetPageCount(Bytes, 0); for (i = 0; i < pageNum; i += 1) @@ -7239,7 +7279,7 @@ gckOS_CreateSignal( } /* Save the process ID. */ - signal->process = (gctHANDLE) _GetProcessID(); + signal->process = (gctHANDLE)(gctUINTPTR_T) _GetProcessID(); signal->manualReset = ManualReset; signal->hardware = gcvNULL; init_completion(&signal->obj); @@ -7247,7 +7287,7 @@ gckOS_CreateSignal( gcmkONERROR(_AllocateIntegerId(&Os->signalDB, signal, &signal->id)); - *Signal = (gctSIGNAL)signal->id; + *Signal = (gctSIGNAL)(gctUINTPTR_T)signal->id; gcmkFOOTER_ARG("*Signal=0x%X", *Signal); return gcvSTATUS_OK; @@ -7279,7 +7319,7 @@ gckOS_SignalQueryHardware( gcmkVERIFY_ARGUMENT(Signal != gcvNULL); gcmkVERIFY_ARGUMENT(Hardware != gcvNULL); - gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal)); + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal)); *Hardware = signal->hardware; @@ -7306,7 +7346,7 @@ gckOS_SignalSetHardware( gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); gcmkVERIFY_ARGUMENT(Signal != gcvNULL); - gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal)); + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal)); signal->hardware = Hardware; @@ -7354,9 +7394,9 @@ gckOS_DestroySignal( gcmkONERROR(gckOS_AcquireMutex(Os, Os->signalMutex, gcvINFINITE)); acquired = gcvTRUE; - gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal)); + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal)); - gcmkASSERT(signal->id == (gctUINT32)Signal); + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal); if (atomic_dec_and_test(&signal->ref)) { @@ -7426,9 +7466,9 @@ gckOS_Signal( gcmkONERROR(gckOS_AcquireMutex(Os, Os->signalMutex, gcvINFINITE)); acquired = gcvTRUE; - gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal)); + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal)); - gcmkASSERT(signal->id == (gctUINT32)Signal); + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal); if (State) { @@ -7475,7 +7515,7 @@ gckOS_SetSignalVG( struct task_struct * userTask; struct siginfo info; - userTask = FIND_TASK_BY_PID((pid_t) Process); + userTask = FIND_TASK_BY_PID((pid_t)(gctUINTPTR_T) Process); if (userTask != gcvNULL) { @@ -7554,7 +7594,7 @@ gckOS_UserSignal( gctSIGNAL signal; gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=%d", - Os, Signal, (gctINT32) Process); + Os, Signal, (gctINT32)(gctUINTPTR_T)Process); /* Map the signal into kernel space. */ gcmkONERROR(gckOS_MapSignal(Os, Signal, Process, &signal)); @@ -7612,9 +7652,9 @@ gckOS_WaitSignal( gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); gcmkVERIFY_ARGUMENT(Signal != gcvNULL); - gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal)); + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal)); - gcmkASSERT(signal->id == (gctUINT32)Signal); + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal); might_sleep(); @@ -7786,7 +7826,7 @@ gckOS_MapSignal( gcmkVERIFY_ARGUMENT(Signal != gcvNULL); gcmkVERIFY_ARGUMENT(MappedSignal != gcvNULL); - gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal)); + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal)); if(atomic_inc_return(&signal->ref) <= 1) { @@ -7885,7 +7925,7 @@ gckOS_DestroyUserSignal( IN gctINT SignalID ) { - return gckOS_DestroySignal(Os, (gctSIGNAL)SignalID); + return gckOS_DestroySignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID); } /******************************************************************************* @@ -7917,7 +7957,7 @@ gckOS_WaitUserSignal( IN gctUINT32 Wait ) { - return gckOS_WaitSignal(Os, (gctSIGNAL)SignalID, Wait); + return gckOS_WaitSignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, Wait); } /******************************************************************************* @@ -7949,7 +7989,7 @@ gckOS_SignalUserSignal( IN gctBOOL State ) { - return gckOS_Signal(Os, (gctSIGNAL)SignalID, State); + return gckOS_Signal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, State); } #if gcdENABLE_VG @@ -8082,7 +8122,7 @@ gckOS_SetSignal( struct task_struct * userTask; struct siginfo info; - userTask = FIND_TASK_BY_PID((pid_t) Process); + userTask = FIND_TASK_BY_PID((pid_t)(gctUINTPTR_T) Process); if (userTask != gcvNULL) { |