void t3_disable_la_scaling(enum tegra_la_id id) { unsigned long reg; void __iomem *scaling_enable_reg = (void __iomem *)(T3_MC_RA(ARB_OVERRIDE)); int idx; BUG_ON(id >= TEGRA_LA_MAX_ID); idx = cs->id_to_index[id]; BUG_ON(cs->la_info_array[idx].id != id); if (cs->la_info_array[idx].scaling_supported == false) return; spin_lock(&cs->lock); la_debug("\n%s: id=%d", __func__, id); cs->scaling_info[idx].scaling_ref_count--; BUG_ON(cs->scaling_info[idx].scaling_ref_count < 0); if (!--cs->la_scaling_enable_count) { reg = readl(scaling_enable_reg); reg = reg & ~(1 << GLOBAL_LATENCY_SCALING_ENABLE_BIT); writel(reg, scaling_enable_reg); la_debug("disabled scaling."); } spin_unlock(&cs->lock); }
static void set_thresholds(struct la_scaling_reg_info *info, enum tegra_la_id id) { unsigned long reg_read; unsigned long reg_write; unsigned int thresh_low; unsigned int thresh_mid; unsigned int thresh_high; int la_set; int idx = cs->id_to_index[id]; reg_read = readl(cs->la_info_array[idx].reg_addr); la_set = (reg_read & cs->la_info_array[idx].mask) >> cs->la_info_array[idx].shift; /* la should be set before enabling scaling. */ BUG_ON(la_set != cs->scaling_info[idx].la_set); thresh_low = (cs->scaling_info[idx].threshold_low * la_set) / 100; thresh_mid = (cs->scaling_info[idx].threshold_mid * la_set) / 100; thresh_high = (cs->scaling_info[idx].threshold_high * la_set) / 100; la_debug("%s: la_set=%d, thresh_low=%d(%d%%), thresh_mid=%d(%d%%)," " thresh_high=%d(%d%%) ", __func__, la_set, thresh_low, cs->scaling_info[idx].threshold_low, thresh_mid, cs->scaling_info[idx].threshold_mid, thresh_high, cs->scaling_info[idx].threshold_high); reg_read = readl(info->tl_reg_addr); reg_write = (reg_read & ~info->tl_mask) | (thresh_low << info->tl_shift); writel(reg_write, info->tl_reg_addr); la_debug("reg_addr=0x%x, read=0x%x, write=0x%x", (u32)info->tl_reg_addr, (u32)reg_read, (u32)reg_write); reg_read = readl(info->tm_reg_addr); reg_write = (reg_read & ~info->tm_mask) | (thresh_mid << info->tm_shift); writel(reg_write, info->tm_reg_addr); la_debug("reg_addr=0x%x, read=0x%x, write=0x%x", (u32)info->tm_reg_addr, (u32)reg_read, (u32)reg_write); reg_read = readl(info->th_reg_addr); reg_write = (reg_read & ~info->th_mask) | (thresh_high << info->th_shift); writel(reg_write, info->th_reg_addr); la_debug("reg_addr=0x%x, read=0x%x, write=0x%x", (u32)info->th_reg_addr, (u32)reg_read, (u32)reg_write); }
static void t11x_init_ptsa(void) { struct clk *emc_clk __attribute__((unused)); unsigned long emc_freq __attribute__((unused)); unsigned long same_freq __attribute__((unused)); unsigned long grant_dec __attribute__((unused)); unsigned long ring1_rate __attribute__((unused)); emc_clk = clk_get(NULL, "emc"); la_debug("**** emc clk_rate=%luMHz", clk_get_rate(emc_clk)/1000000); emc_freq = clk_get_rate(emc_clk); emc_freq /= 1000000; /* Compute initial value for grant dec */ same_freq = readl(T11X_MC_RA(EMEM_ARB_MISC0_0)); same_freq = same_freq >> 27 & 1; grant_dec = 256 * (same_freq ? 2 : 1) * emc_freq; if (grant_dec > 511) grant_dec = 511; writel(grant_dec, T11X_MC_RA(PTSA_GRANT_DECREMENT_0)); writel(0x3d, T11X_MC_RA(DIS_PTSA_MIN_0)); writel(0x14, T11X_MC_RA(DIS_PTSA_MAX_0)); writel(0x3d, T11X_MC_RA(DISB_PTSA_MIN_0)); writel(0x14, T11X_MC_RA(DISB_PTSA_MAX_0)); writel(t11x_get_ptsa_rate(T11X_MAX_CAMERA_BW_MHZ), T11X_MC_RA(VE_PTSA_RATE_0)); writel(0x3d, T11X_MC_RA(VE_PTSA_MIN_0)); writel(0x14, T11X_MC_RA(VE_PTSA_MAX_0)); writel(0x01, T11X_MC_RA(RING2_PTSA_RATE_0)); writel(0x3f, T11X_MC_RA(RING2_PTSA_MIN_0)); writel(0x05, T11X_MC_RA(RING2_PTSA_MAX_0)); writel(38 * emc_freq / T11X_BASE_EMC_FREQ_MHZ, T11X_MC_RA(MLL_MPCORER_PTSA_RATE_0)); writel(0x3f, T11X_MC_RA(MLL_MPCORER_PTSA_MIN_0)); writel(0x05, T11X_MC_RA(MLL_MPCORER_PTSA_MAX_0)); writel(0x01, T11X_MC_RA(SMMU_SMMU_PTSA_RATE_0)); writel(0x01, T11X_MC_RA(SMMU_SMMU_PTSA_MIN_0)); writel(0x01, T11X_MC_RA(SMMU_SMMU_PTSA_MAX_0)); ring1_rate = readl(T11X_MC_RA(DIS_PTSA_RATE_0)) + readl(T11X_MC_RA(DISB_PTSA_RATE_0)); #if defined(CONFIG_TEGRA_ERRATA_977223) ring1_rate /= 2; #endif ring1_rate += readl(T11X_MC_RA(VE_PTSA_RATE_0)) + readl(T11X_MC_RA(RING2_PTSA_RATE_0)); writel(ring1_rate, T11X_MC_RA(RING1_PTSA_RATE_0)); writel(0x36, T11X_MC_RA(RING1_PTSA_MIN_0)); writel(0x1f, T11X_MC_RA(RING1_PTSA_MAX_0)); writel(0x00, T11X_MC_RA(DIS_EXTRA_SNAP_LEVELS_0)); writel(0x03, T11X_MC_RA(HEG_EXTRA_SNAP_LEVELS_0)); }
/* Thresholds for scaling are specified in % of fifo freeness. * If threshold_low is specified as 20%, it means when the fifo free * between 0 to 20%, use la as programmed_la. * If threshold_mid is specified as 50%, it means when the fifo free * between 20 to 50%, use la as programmed_la/2 . * If threshold_high is specified as 80%, it means when the fifo free * between 50 to 80%, use la as programmed_la/4. * When the fifo is free between 80 to 100%, use la as 0(highest priority). */ int t3_enable_la_scaling(enum tegra_la_id id, unsigned int threshold_low, unsigned int threshold_mid, unsigned int threshold_high) { unsigned long reg; void __iomem *scaling_enable_reg = (void __iomem *)(T3_MC_RA(ARB_OVERRIDE)); int idx = cs->id_to_index[id]; VALIDATE_ID(id, cs); VALIDATE_THRESHOLDS(threshold_low, threshold_mid, threshold_high); if (cs->la_info_array[idx].scaling_supported == false) goto exit; spin_lock(&cs->lock); la_debug("\n%s: id=%d, tl=%d, tm=%d, th=%d", __func__, id, threshold_low, threshold_mid, threshold_high); cs->scaling_info[idx].threshold_low = threshold_low; cs->scaling_info[idx].threshold_mid = threshold_mid; cs->scaling_info[idx].threshold_high = threshold_high; cs->scaling_info[idx].scaling_ref_count++; if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_1BB)) set_disp_latency_thresholds(id); else if (id >= ID(VI_WSB) && id <= ID(VI_WY)) set_vi_latency_thresholds(id); if (!cs->la_scaling_enable_count++) { reg = readl(scaling_enable_reg); reg |= (1 << GLOBAL_LATENCY_SCALING_ENABLE_BIT); writel(reg, scaling_enable_reg); la_debug("enabled scaling."); } spin_unlock(&cs->lock); exit: return 0; }