static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev) { u32 nwb; int rc = 0; u32 *ctl_offsets = NULL, *wb_offsets = NULL; struct mdss_data_type *mdata = platform_get_drvdata(pdev); mdata->nctl = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-ctl-off"); nwb = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-wb-off"); if (mdata->nctl != nwb) { pr_err("device tree err: unequal number of ctl and wb\n"); rc = -EINVAL; goto parse_done; } ctl_offsets = kzalloc(sizeof(u32) * mdata->nctl, GFP_KERNEL); if (!ctl_offsets) { pr_err("no more mem for ctl offsets\n"); return -ENOMEM; } wb_offsets = kzalloc(sizeof(u32) * nwb, GFP_KERNEL); if (!wb_offsets) { pr_err("no more mem for writeback offsets\n"); rc = -ENOMEM; goto wb_alloc_fail; } rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-ctl-off", ctl_offsets, mdata->nctl); if (rc) goto parse_done; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-wb-off", wb_offsets, nwb); if (rc) goto parse_done; rc = mdss_mdp_ctl_addr_setup(mdata, ctl_offsets, wb_offsets, mdata->nctl); if (rc) goto parse_done; parse_done: kfree(wb_offsets); wb_alloc_fail: kfree(ctl_offsets); return rc; }
static int mdss_mdp_parse_dt_ad_cfg(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); u32 *ad_offsets = NULL; int rc; mdata->nad_cfgs = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-ad-off"); if (mdata->nad_cfgs == 0) { mdata->ad_cfgs = NULL; return 0; } if (mdata->nad_cfgs > mdata->nmixers_intf) return -EINVAL; ad_offsets = kzalloc(sizeof(u32) * mdata->nad_cfgs, GFP_KERNEL); if (!ad_offsets) { pr_err("no mem assigned: kzalloc fail\n"); return -ENOMEM; } rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-ad-off", ad_offsets, mdata->nad_cfgs); if (rc) goto parse_done; rc = mdss_mdp_ad_addr_setup(mdata, ad_offsets); if (rc) pr_err("unable to setup assertive display\n"); parse_done: kfree(ad_offsets); return rc; }
static int mdss_mdp_parse_dt_smp(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); u32 num; u32 data[2]; int rc; num = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-smp-data"); if (num != 2) return -EINVAL; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-smp-data", data, num); if (rc) return rc; rc = mdss_mdp_smp_setup(mdata, data[0], data[1]); if (rc) { pr_err("unable to setup smp data\n"); return rc; } rc = of_property_read_u32(pdev->dev.of_node, "qcom,mdss-smp-mb-per-pipe", data); mdata->smp_mb_per_pipe = (!rc ? data[0] : 0); return 0; }
static int mdss_mdp_parse_dt_video_intf(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); u32 count; u32 *offsets; int rc; count = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-intf-off"); if (count == 0) return -EINVAL; offsets = kzalloc(sizeof(u32) * count, GFP_KERNEL); if (!offsets) { pr_err("no mem assigned for video intf\n"); return -ENOMEM; } rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-intf-off", offsets, count); if (rc) goto parse_fail; rc = mdss_mdp_video_addr_setup(mdata, offsets, count); if (rc) pr_err("unable to setup video interfaces\n"); parse_fail: kfree(offsets); return rc; }
static int mdss_mdp_parse_dt_smp(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); u32 num; u32 data[2]; int rc; num = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-smp-data"); if (num != 2) return -EINVAL; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-smp-data", data, num); if (rc) return rc; rc = mdss_mdp_smp_setup(mdata, data[0], data[1]); if (rc) pr_err("unable to setup smp data\n"); return rc; }
static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev) { u32 nmixers, ndspp, npingpong; int rc = 0; u32 *mixer_offsets = NULL, *dspp_offsets = NULL, *pingpong_offsets = NULL; struct mdss_data_type *mdata = platform_get_drvdata(pdev); mdata->nmixers_intf = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-mixer-intf-off"); mdata->nmixers_wb = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-mixer-wb-off"); ndspp = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-dspp-off"); npingpong = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pingpong-off"); nmixers = mdata->nmixers_intf + mdata->nmixers_wb; if (mdata->nmixers_intf != ndspp) { pr_err("device tree err: unequal no of dspp and intf mixers\n"); return -EINVAL; } if (mdata->nmixers_intf != npingpong) { pr_err("device tree err: unequal no of pingpong and intf mixers\n"); return -EINVAL; } mixer_offsets = kzalloc(sizeof(u32) * nmixers, GFP_KERNEL); if (!mixer_offsets) { pr_err("no mem assigned: kzalloc fail\n"); return -ENOMEM; } dspp_offsets = kzalloc(sizeof(u32) * ndspp, GFP_KERNEL); if (!dspp_offsets) { pr_err("no mem assigned: kzalloc fail\n"); rc = -ENOMEM; goto dspp_alloc_fail; } pingpong_offsets = kzalloc(sizeof(u32) * npingpong, GFP_KERNEL); if (!pingpong_offsets) { pr_err("no mem assigned: kzalloc fail\n"); rc = -ENOMEM; goto pingpong_alloc_fail; } rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-mixer-intf-off", mixer_offsets, mdata->nmixers_intf); if (rc) goto parse_done; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-mixer-wb-off", mixer_offsets + mdata->nmixers_intf, mdata->nmixers_wb); if (rc) goto parse_done; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-dspp-off", dspp_offsets, ndspp); if (rc) goto parse_done; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pingpong-off", pingpong_offsets, npingpong); if (rc) goto parse_done; rc = mdss_mdp_mixer_addr_setup(mdata, mixer_offsets, dspp_offsets, pingpong_offsets, MDSS_MDP_MIXER_TYPE_INTF, mdata->nmixers_intf); if (rc) goto parse_done; rc = mdss_mdp_mixer_addr_setup(mdata, mixer_offsets + mdata->nmixers_intf, NULL, NULL, MDSS_MDP_MIXER_TYPE_WRITEBACK, mdata->nmixers_wb); if (rc) goto parse_done; parse_done: kfree(pingpong_offsets); pingpong_alloc_fail: kfree(dspp_offsets); dspp_alloc_fail: kfree(mixer_offsets); return rc; }
static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) { u32 npipes, dma_off; int rc = 0; u32 nids = 0, setup_cnt = 0, len; u32 *offsets = NULL, *ftch_id = NULL; struct mdss_data_type *mdata = platform_get_drvdata(pdev); mdata->nvig_pipes = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-vig-off"); mdata->nrgb_pipes = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-rgb-off"); mdata->ndma_pipes = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-dma-off"); nids += mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-vig-fetch-id"); nids += mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-rgb-fetch-id"); nids += mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-dma-fetch-id"); npipes = mdata->nvig_pipes + mdata->nrgb_pipes + mdata->ndma_pipes; if (npipes != nids) { pr_err("device tree err: unequal number of pipes and smp ids"); return -EINVAL; } offsets = kzalloc(sizeof(u32) * npipes, GFP_KERNEL); if (!offsets) { pr_err("no mem assigned for offsets: kzalloc fail\n"); return -ENOMEM; } ftch_id = kzalloc(sizeof(u32) * nids, GFP_KERNEL); if (!ftch_id) { pr_err("no mem assigned for ftch_id: kzalloc fail\n"); rc = -ENOMEM; goto ftch_alloc_fail; } mdata->vig_pipes = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_pipe) * mdata->nvig_pipes, GFP_KERNEL); if (!mdata->vig_pipes) { pr_err("no mem for vig_pipes: kzalloc fail\n"); rc = -ENOMEM; goto vig_alloc_fail; } mdata->rgb_pipes = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_pipe) * mdata->nrgb_pipes, GFP_KERNEL); if (!mdata->rgb_pipes) { pr_err("no mem for rgb_pipes: kzalloc fail\n"); rc = -ENOMEM; goto rgb_alloc_fail; } mdata->dma_pipes = devm_kzalloc(&mdata->pdev->dev, sizeof(struct mdss_mdp_pipe) * mdata->ndma_pipes, GFP_KERNEL); if (!mdata->dma_pipes) { pr_err("no mem for dma_pipes: kzalloc fail\n"); rc = -ENOMEM; goto dma_alloc_fail; } rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-fetch-id", ftch_id, mdata->nvig_pipes); if (rc) goto parse_done; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-off", offsets, mdata->nvig_pipes); if (rc) goto parse_fail; len = min_t(int, DEFAULT_TOTAL_VIG_PIPES, (int)mdata->nvig_pipes); rc = mdss_mdp_pipe_addr_setup(mdata, mdata->vig_pipes, offsets, ftch_id, MDSS_MDP_PIPE_TYPE_VIG, MDSS_MDP_SSPP_VIG0, len); if (rc) goto parse_fail; setup_cnt += len; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-fetch-id", ftch_id + mdata->nvig_pipes, mdata->nrgb_pipes); if (rc) goto parse_fail; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-off", offsets + mdata->nvig_pipes, mdata->nrgb_pipes); if (rc) goto parse_fail; len = min_t(int, DEFAULT_TOTAL_RGB_PIPES, (int)mdata->nrgb_pipes); rc = mdss_mdp_pipe_addr_setup(mdata, mdata->rgb_pipes, offsets + mdata->nvig_pipes, ftch_id + mdata->nvig_pipes, MDSS_MDP_PIPE_TYPE_RGB, MDSS_MDP_SSPP_RGB0, len); if (rc) goto parse_fail; setup_cnt += len; dma_off = mdata->nvig_pipes + mdata->nrgb_pipes; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-fetch-id", ftch_id + dma_off, mdata->ndma_pipes); if (rc) goto parse_fail; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-off", offsets + dma_off, mdata->ndma_pipes); if (rc) goto parse_fail; len = mdata->ndma_pipes; rc = mdss_mdp_pipe_addr_setup(mdata, mdata->dma_pipes, offsets + dma_off, ftch_id + dma_off, MDSS_MDP_PIPE_TYPE_DMA, MDSS_MDP_SSPP_DMA0, len); if (rc) goto parse_fail; setup_cnt += len; if (mdata->nvig_pipes > DEFAULT_TOTAL_VIG_PIPES) { rc = mdss_mdp_pipe_addr_setup(mdata, mdata->vig_pipes + DEFAULT_TOTAL_VIG_PIPES, offsets + DEFAULT_TOTAL_VIG_PIPES, ftch_id + DEFAULT_TOTAL_VIG_PIPES, MDSS_MDP_PIPE_TYPE_VIG, setup_cnt, mdata->nvig_pipes - DEFAULT_TOTAL_VIG_PIPES); if (rc) goto parse_fail; setup_cnt += mdata->nvig_pipes - DEFAULT_TOTAL_VIG_PIPES; } if (mdata->nrgb_pipes > DEFAULT_TOTAL_RGB_PIPES) { rc = mdss_mdp_pipe_addr_setup(mdata, mdata->rgb_pipes + DEFAULT_TOTAL_RGB_PIPES, offsets + mdata->nvig_pipes + DEFAULT_TOTAL_RGB_PIPES, ftch_id + mdata->nvig_pipes + DEFAULT_TOTAL_RGB_PIPES, MDSS_MDP_PIPE_TYPE_RGB, setup_cnt, mdata->nrgb_pipes - DEFAULT_TOTAL_RGB_PIPES); if (rc) goto parse_fail; setup_cnt += mdata->nrgb_pipes - DEFAULT_TOTAL_RGB_PIPES; } goto parse_done; parse_fail: kfree(mdata->dma_pipes); dma_alloc_fail: kfree(mdata->rgb_pipes); rgb_alloc_fail: kfree(mdata->vig_pipes); parse_done: vig_alloc_fail: kfree(ftch_id); ftch_alloc_fail: kfree(offsets); return rc; }
static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) { u32 npipes, off; int rc = 0; u32 nids = 0; u32 *offsets = NULL, *ftch_id = NULL; struct mdss_data_type *mdata = platform_get_drvdata(pdev); mdata->nvig_pipes = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-vig-off"); mdata->nrgb_pipes = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-rgb-off"); mdata->ndma_pipes = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-dma-off"); nids += mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-vig-fetch-id"); nids += mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-rgb-fetch-id"); nids += mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-pipe-dma-fetch-id"); npipes = mdata->nvig_pipes + mdata->nrgb_pipes + mdata->ndma_pipes; if (npipes != nids) { pr_err("device tree err: unequal number of pipes and smp ids"); return -EINVAL; } offsets = kzalloc(sizeof(u32) * npipes, GFP_KERNEL); if (!offsets) { pr_err("no mem assigned: kzalloc fail\n"); return -ENOMEM; } ftch_id = kzalloc(sizeof(u32) * nids, GFP_KERNEL); if (!ftch_id) { pr_err("no mem assigned: kzalloc fail\n"); rc = -ENOMEM; goto ftch_alloc_fail; } rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-fetch-id", ftch_id, mdata->nvig_pipes); if (rc) goto parse_done; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-off", offsets, mdata->nvig_pipes); if (rc) goto parse_done; rc = mdss_mdp_pipe_addr_setup(mdata, offsets, ftch_id, MDSS_MDP_PIPE_TYPE_VIG, MDSS_MDP_SSPP_VIG0, mdata->nvig_pipes); if (rc) goto parse_done; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-fetch-id", ftch_id + mdata->nvig_pipes, mdata->nrgb_pipes); if (rc) goto parse_done; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-off", offsets + mdata->nvig_pipes, mdata->nrgb_pipes); if (rc) goto parse_done; rc = mdss_mdp_pipe_addr_setup(mdata, offsets + mdata->nvig_pipes, ftch_id + mdata->nvig_pipes, MDSS_MDP_PIPE_TYPE_RGB, MDSS_MDP_SSPP_RGB0, mdata->nrgb_pipes); if (rc) goto parse_done; off = mdata->nvig_pipes + mdata->nrgb_pipes; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-fetch-id", ftch_id + off, mdata->ndma_pipes); if (rc) goto parse_done; rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-off", offsets + off, mdata->ndma_pipes); if (rc) goto parse_done; rc = mdss_mdp_pipe_addr_setup(mdata, offsets + off, ftch_id + off, MDSS_MDP_PIPE_TYPE_DMA, MDSS_MDP_SSPP_DMA0, mdata->ndma_pipes); if (rc) goto parse_done; parse_done: kfree(ftch_id); ftch_alloc_fail: kfree(offsets); return rc; }