static u32 mdss_mdp_smp_mmb_reserve(struct mdss_mdp_pipe_smp_map *smp_map, size_t n) { u32 i, mmb; u32 fixed_cnt = bitmap_weight(smp_map->fixed, SMP_MB_CNT); struct mdss_data_type *mdata = mdss_mdp_get_mdata(); if (n <= fixed_cnt) return fixed_cnt; else n -= fixed_cnt; i = bitmap_weight(smp_map->allocated, SMP_MB_CNT); if (i != 0 && n != i) { pr_debug("Can't change mmb config, num_blks: %d alloc: %d\n", n, i); return 0; } mdss_mdp_smp_mmb_free(smp_map->reserved, false); for (; i < n; i++) { if (bitmap_full(mdata->mmb_alloc_map, SMP_MB_CNT)) break; mmb = find_first_zero_bit(mdata->mmb_alloc_map, SMP_MB_CNT); set_bit(mmb, smp_map->reserved); set_bit(mmb, mdata->mmb_alloc_map); } return i + fixed_cnt; }
static u32 mdss_mdp_smp_mmb_reserve(struct mdss_mdp_pipe_smp_map *smp_map, size_t n, bool force_alloc) { u32 i, mmb; u32 fixed_cnt = bitmap_weight(smp_map->fixed, SMP_MB_CNT); struct mdss_data_type *mdata = mdss_mdp_get_mdata(); if (n <= fixed_cnt) return fixed_cnt; else n -= fixed_cnt; i = bitmap_weight(smp_map->allocated, SMP_MB_CNT); /* * SMP programming is not double buffered. Fail the request, * that calls for change in smp configuration (addition/removal * of smp blocks), so that fallback solution happens. */ #if defined(CONFIG_ARCH_MSM8226) || (CONFIG_ARCH_MSM8974) if (i != 0 && n != i && !force_alloc) { pr_debug("Can't change mmb config, num_blks: %d alloc: %d\n", n, i); pr_debug("Can't change mmb configuration in set call\n"); return 0; } #else if (i != 0 && n != i) { pr_debug("Can't change mmb config, num_blks: %d alloc: %d\n", n, i); pr_debug("Can't change mmb configuration in set call\n"); return 0; } #endif /* * Clear previous SMP reservations and reserve according to the * latest configuration */ mdss_mdp_smp_mmb_free(smp_map->reserved, false); /* Reserve mmb blocks*/ for (; i < n; i++) { if (bitmap_full(mdata->mmb_alloc_map, SMP_MB_CNT)) break; mmb = find_first_zero_bit(mdata->mmb_alloc_map, SMP_MB_CNT); set_bit(mmb, smp_map->reserved); set_bit(mmb, mdata->mmb_alloc_map); } return i + fixed_cnt; }
static u32 mdss_mdp_smp_mmb_reserve(struct mdss_mdp_pipe *pipe, struct mdss_mdp_pipe_smp_map *smp_map, size_t n) { u32 i, mmb; u32 fixed_cnt = bitmap_weight(smp_map->fixed, SMP_MB_CNT); struct mdss_data_type *mdata = mdss_mdp_get_mdata(); if (n <= fixed_cnt) return fixed_cnt; else n -= fixed_cnt; i = bitmap_weight(smp_map->allocated, SMP_MB_CNT); /* * SMP programming is not double buffered. Fail the request, * that calls for change in smp configuration (addition/removal * of smp blocks), so that fallback solution happens. */ if (pipe->src_fmt->is_yuv || (pipe->flags & MDP_BACKEND_COMPOSITION)) { if (i != 0 && n != i) { pr_debug("Can't change mmb configuration in set call\n"); return 0; } } /* * Clear previous SMP reservations and reserve according to the * latest configuration */ mdss_mdp_smp_mmb_free(smp_map->reserved, false); /* reserve more blocks if needed, but can't free mmb at this point */ for (; i < n; i++) { if (bitmap_full(mdata->mmb_alloc_map, SMP_MB_CNT)) break; mmb = find_first_zero_bit(mdata->mmb_alloc_map, SMP_MB_CNT); set_bit(mmb, smp_map->reserved); set_bit(mmb, mdata->mmb_alloc_map); } return i + fixed_cnt; }