|
@@ -1201,44 +1201,111 @@ static int _sde_rm_reserve_ctls(
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static bool _sde_rm_check_dsc(struct sde_rm *rm,
|
|
|
+ struct sde_rm_rsvp *rsvp,
|
|
|
+ struct sde_rm_hw_blk *dsc,
|
|
|
+ struct sde_rm_hw_blk *paired_dsc)
|
|
|
+{
|
|
|
+ const struct sde_dsc_cfg *dsc_cfg = to_sde_hw_dsc(dsc->hw)->caps;
|
|
|
+
|
|
|
+ /* Already reserved? */
|
|
|
+ if (RESERVED_BY_OTHER(dsc, rsvp)) {
|
|
|
+ SDE_DEBUG("dsc %d already reserved\n", dsc_cfg->id);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check if this dsc is a peer of the proposed paired DSC */
|
|
|
+ if (paired_dsc) {
|
|
|
+ const struct sde_dsc_cfg *paired_dsc_cfg =
|
|
|
+ to_sde_hw_dsc(paired_dsc->hw)->caps;
|
|
|
+
|
|
|
+ if (!test_bit(dsc_cfg->id, paired_dsc_cfg->dsc_pair_mask)) {
|
|
|
+ SDE_DEBUG("dsc %d not peer of dsc %d\n", dsc_cfg->id,
|
|
|
+ paired_dsc_cfg->id);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
static int _sde_rm_reserve_dsc(
|
|
|
struct sde_rm *rm,
|
|
|
struct sde_rm_rsvp *rsvp,
|
|
|
const struct sde_rm_topology_def *top,
|
|
|
u8 *_dsc_ids)
|
|
|
{
|
|
|
- struct sde_rm_hw_iter iter;
|
|
|
+ struct sde_rm_hw_iter iter_i, iter_j;
|
|
|
+ struct sde_rm_hw_blk *dsc[MAX_BLOCKS];
|
|
|
int alloc_count = 0;
|
|
|
- int num_dsc_enc = top->num_lm;
|
|
|
+ int num_dsc_enc = top->num_comp_enc;
|
|
|
+ int i;
|
|
|
|
|
|
if (!top->num_comp_enc)
|
|
|
return 0;
|
|
|
|
|
|
- sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_DSC);
|
|
|
+ sde_rm_init_hw_iter(&iter_i, 0, SDE_HW_BLK_DSC);
|
|
|
|
|
|
- while (_sde_rm_get_hw_locked(rm, &iter)) {
|
|
|
- if (RESERVED_BY_OTHER(iter.blk, rsvp))
|
|
|
+ /* Find a first DSC */
|
|
|
+ while (alloc_count != num_dsc_enc &&
|
|
|
+ _sde_rm_get_hw_locked(rm, &iter_i)) {
|
|
|
+ memset(&dsc, 0, sizeof(dsc));
|
|
|
+ alloc_count = 0;
|
|
|
+
|
|
|
+ if (_dsc_ids && (iter_i.blk->id != _dsc_ids[alloc_count]))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (!_sde_rm_check_dsc(rm, rsvp, iter_i.blk, NULL))
|
|
|
continue;
|
|
|
|
|
|
SDE_DEBUG("blk id = %d, _dsc_ids[%d] = %d\n",
|
|
|
- iter.blk->id,
|
|
|
+ iter_i.blk->id,
|
|
|
alloc_count,
|
|
|
_dsc_ids ? _dsc_ids[alloc_count] : -1);
|
|
|
|
|
|
- if (_dsc_ids && (iter.blk->id != _dsc_ids[alloc_count]))
|
|
|
- continue;
|
|
|
+ dsc[alloc_count++] = iter_i.blk;
|
|
|
|
|
|
- iter.blk->rsvp_nxt = rsvp;
|
|
|
- SDE_EVT32(iter.blk->type, rsvp->enc_id, iter.blk->id);
|
|
|
+ /* Valid first dsc found, find matching peers */
|
|
|
+ sde_rm_init_hw_iter(&iter_j, 0, SDE_HW_BLK_DSC);
|
|
|
|
|
|
- if (++alloc_count == num_dsc_enc)
|
|
|
- return 0;
|
|
|
+ while (alloc_count != num_dsc_enc &&
|
|
|
+ _sde_rm_get_hw_locked(rm, &iter_j)) {
|
|
|
+ if (iter_i.blk == iter_j.blk)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (_dsc_ids && (iter_j.blk->id !=
|
|
|
+ _dsc_ids[alloc_count]))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (!_sde_rm_check_dsc(rm, rsvp,
|
|
|
+ iter_j.blk, iter_i.blk))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ SDE_DEBUG("blk id = %d, _dsc_ids[%d] = %d\n",
|
|
|
+ iter_j.blk->id,
|
|
|
+ alloc_count,
|
|
|
+ _dsc_ids ? _dsc_ids[alloc_count] : -1);
|
|
|
+
|
|
|
+ dsc[alloc_count++] = iter_j.blk;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- SDE_ERROR("couldn't reserve %d dsc blocks for enc id %d\n",
|
|
|
- num_dsc_enc, rsvp->enc_id);
|
|
|
+ if (alloc_count != num_dsc_enc) {
|
|
|
+ SDE_ERROR("couldn't reserve %d dsc blocks for enc id %d\n",
|
|
|
+ num_dsc_enc, rsvp->enc_id);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
- return -ENAVAIL;
|
|
|
+ for (i = 0; i < ARRAY_SIZE(dsc); i++) {
|
|
|
+ if (!dsc[i])
|
|
|
+ break;
|
|
|
+
|
|
|
+ dsc[i]->rsvp_nxt = rsvp;
|
|
|
+
|
|
|
+ SDE_EVT32(dsc[i]->type, rsvp->enc_id, dsc[i]->id);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int _sde_rm_reserve_qdss(
|