static void pdc_intc_setup(struct pdc_intc_priv *priv) { int i; unsigned int soc_sys_wake_regoff; unsigned int soc_sys_wake; /* * Mask all syswake interrupts before routing, or we could receive an * interrupt before we're ready to handle it. */ pdc_write(priv, PDC_IRQ_ENABLE, 0); /* * Enable routing of all syswakes * Disable all wake sources */ priv->irq_route = ((PDC_IRQ_ROUTE_EXT_EN_SYS0 << priv->nr_syswakes) - PDC_IRQ_ROUTE_EXT_EN_SYS0); pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route); /* Initialise syswake IRQ */ for (i = 0; i < priv->nr_syswakes; ++i) { /* set the IRQ mode to none */ soc_sys_wake_regoff = PDC_SYS_WAKE_BASE + i*PDC_SYS_WAKE_STRIDE; soc_sys_wake = PDC_SYS_WAKE_INT_NONE << PDC_SYS_WAKE_INT_MODE_SHIFT; pdc_write(priv, soc_sys_wake_regoff, soc_sys_wake); } }
static int tz1090_pdc_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int output_value) { struct tz1090_pdc_gpio *priv = to_pdc(chip); u32 value; int lstat; __global_lock2(lstat); /* EXT_POWER doesn't seem to have an output value bit */ if (offset < 6) { value = pdc_read(priv, REG_SOC_GPIO_CONTROL0); if (output_value) value |= BIT(offset); else value &= ~BIT(offset); pdc_write(priv, REG_SOC_GPIO_CONTROL0, value); } value = pdc_read(priv, REG_SOC_GPIO_CONTROL1); value &= ~BIT(offset); pdc_write(priv, REG_SOC_GPIO_CONTROL1, value); __global_unlock2(lstat); return 0; }
static void perip_irq_unmask(struct irq_data *data) { struct pdc_intc_priv *priv = irqd_to_priv(data); raw_spin_lock(&priv->lock); priv->irq_route |= data->mask; pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route); raw_spin_unlock(&priv->lock); }
pdc_bool pdc_init_output( void *opaque, pdc_output *out, int compatibility, pdc_outctl *oc) { static const char *fn = "pdc_init_output"; pdc_core *pdc = out->pdc; int i; pdc_cleanup_output(out, pdc_false); out->opaque = opaque; out->lastobj = 0; #if defined(MVS) || defined(MVS_TEST) out->fopenparams = oc->fopenparams; out->recordsize = oc->recordsize; #endif if (out->file_offset == NULL) { out->file_offset_capacity = ID_CHUNKSIZE; out->file_offset = (pdc_off_t *) pdc_malloc(pdc, sizeof(pdc_off_t) * out->file_offset_capacity, fn); } for (i = 1; i < out->file_offset_capacity; ++i) out->file_offset[i] = PDC_BAD_ID; out->compresslevel = PDF_DEFAULT_COMPRESSION; out->compr_changed = pdc_false; out->flush = oc->flush; memcpy(out->id[0], out->id[1], MD5_DIGEST_LENGTH); if (!pdc_init_stream(pdc, out, oc->filename, oc->fp, oc->writeproc)) return pdc_false; { /* Write the document header */ pdc_printf(out, "%%PDF-%s\n", pdc_get_pdfversion(pdc, compatibility)); #define PDC_MAGIC_BINARY "\045\344\343\317\322\012" pdc_write(out, PDC_MAGIC_BINARY, sizeof(PDC_MAGIC_BINARY) - 1); } out->open = pdc_true; return pdc_true; }
pdc_bool pdc_init_output( void *opaque, pdc_output *out, const char *filename, FILE *fp, size_t (*writeproc)(pdc_output *out, void *data, size_t size), int compatibility) { static const char *fn = "pdc_init_output"; pdc_core *pdc = out->pdc; int i; out->lastobj = 0; if (out->file_offset == NULL) { out->file_offset_capacity = + ID_CHUNKSIZE; out->file_offset = (long *) pdc_malloc(pdc, sizeof(long) * out->file_offset_capacity, fn); } for (i = 1; i < out->file_offset_capacity; ++i) out->file_offset[i] = PDC_BAD_ID; out->compresslevel = PDF_DEFAULT_COMPRESSION; out->compr_changed = pdc_false; out->opaque = opaque; memcpy(out->id[0], out->id[1], MD5_DIGEST_LENGTH); if (!pdc_init_stream(pdc, out, filename, fp, writeproc)) return pdc_false; /* Write the document header */ if (compatibility == PDC_1_5) pdc_puts(out, "%PDF-1.5\n"); else if (compatibility == PDC_1_4) pdc_puts(out, "%PDF-1.4\n"); else pdc_puts(out, "%PDF-1.3\n"); /* binary magic number */ #define PDC_MAGIC_BINARY "\045\344\343\317\322\012" pdc_write(out, PDC_MAGIC_BINARY, sizeof(PDC_MAGIC_BINARY) - 1); return pdc_true; }
static int tz1090_pdc_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { struct tz1090_pdc_gpio *priv = to_pdc(chip); u32 value; int lstat; __global_lock2(lstat); value = pdc_read(priv, REG_SOC_GPIO_CONTROL1); value |= BIT(offset); pdc_write(priv, REG_SOC_GPIO_CONTROL1, value); __global_unlock2(lstat); return 0; }
static int syswake_irq_set_type(struct irq_data *data, unsigned int flow_type) { struct pdc_intc_priv *priv = irqd_to_priv(data); unsigned int syswake = hwirq_to_syswake(data->hwirq); unsigned int irq_mode; unsigned int soc_sys_wake_regoff, soc_sys_wake; /* translate to syswake IRQ mode */ switch (flow_type) { case IRQ_TYPE_EDGE_BOTH: irq_mode = PDC_SYS_WAKE_INT_CHANGE; break; case IRQ_TYPE_EDGE_RISING: irq_mode = PDC_SYS_WAKE_INT_UP; break; case IRQ_TYPE_EDGE_FALLING: irq_mode = PDC_SYS_WAKE_INT_DOWN; break; case IRQ_TYPE_LEVEL_HIGH: irq_mode = PDC_SYS_WAKE_INT_HIGH; break; case IRQ_TYPE_LEVEL_LOW: irq_mode = PDC_SYS_WAKE_INT_LOW; break; default: return -EINVAL; } raw_spin_lock(&priv->lock); /* set the IRQ mode */ soc_sys_wake_regoff = PDC_SYS_WAKE_BASE + syswake*PDC_SYS_WAKE_STRIDE; soc_sys_wake = pdc_read(priv, soc_sys_wake_regoff); soc_sys_wake &= ~PDC_SYS_WAKE_INT_MODE; soc_sys_wake |= irq_mode << PDC_SYS_WAKE_INT_MODE_SHIFT; pdc_write(priv, soc_sys_wake_regoff, soc_sys_wake); /* and update the handler */ irq_setup_alt_chip(data, flow_type); raw_spin_unlock(&priv->lock); return 0; }
/* copy the complete contents of src to a stream */ void pdf_copy_stream(PDF *p, PDF_data_source *src, pdc_bool compress) { int oldcompresslevel = pdc_get_compresslevel(p->out); if (!compress) pdc_set_compresslevel(p->out, 0); if (src->init) src->init(p, src); pdc_begin_pdfstream(p->out); while (src->fill(p, src)) pdc_write(p->out, src->next_byte, src->bytes_available); pdc_end_pdfstream(p->out); if (src->terminate) src->terminate(p, src); if (!compress) pdc_set_compresslevel(p->out, oldcompresslevel); }
/* applies to both peripheral and syswake interrupts */ static int pdc_irq_set_wake(struct irq_data *data, unsigned int on) { struct pdc_intc_priv *priv = irqd_to_priv(data); irq_hw_number_t hw = data->hwirq; unsigned int mask = (1 << 16) << hw; unsigned int dst_irq; raw_spin_lock(&priv->lock); if (on) priv->irq_route |= mask; else priv->irq_route &= ~mask; pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route); raw_spin_unlock(&priv->lock); /* control the destination IRQ wakeup too for standby mode */ if (hwirq_is_syswake(hw)) dst_irq = priv->syswake_irq; else dst_irq = priv->perip_irqs[hw]; irq_set_irq_wake(dst_irq, on); return 0; }
static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) { struct platform_device *pdev = to_platform_device(gmu->dev); void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc"); void __iomem *seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq"); if (!pdcptr || !seqptr) goto err; /* Disable SDE clock gating */ gmu_write(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24)); /* Setup RSC PDC handshake for sleep and wakeup */ gmu_write(gmu, REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0, 1); gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA, 0); gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR, 0); gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0); gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0); gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4, 0x80000000); gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0); gmu_write(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0); gmu_write(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520); gmu_write(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_LO, 0x4510); gmu_write(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514); /* Load RSC sequencer uCode for sleep and wakeup */ gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xa7a506a0); gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xa1e6a6e7); gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e081e1); gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 0xe9a982e2); gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8); /* Load PDC sequencer uCode for power up and power down sequence */ pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0, 0xfebea1e1); pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 1, 0xa5a4a3a2); pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 2, 0x8382a6e0); pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 3, 0xbce3e284); pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 4, 0x002081fc); /* Set TCS commands used by PDC sequence for low power modes */ pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD_ENABLE_BANK, 7); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK, 0); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CONTROL, 0); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID, 0x10108); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR, 0x30010); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA, 1); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 4, 0x10108); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 4, 0x30000); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 4, 0x0); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 8, 0x10108); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, 0x30080); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 8, 0x0); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD_ENABLE_BANK, 7); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK, 0); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CONTROL, 0); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID, 0x10108); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR, 0x30010); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA, 2); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x30000); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 8, 0x10108); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, 0x30080); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 8, 0x3); /* Setup GPU PDC */ pdc_write(pdcptr, REG_A6XX_PDC_GPU_SEQ_START_ADDR, 0); pdc_write(pdcptr, REG_A6XX_PDC_GPU_ENABLE_PDC, 0x80000001); /* ensure no writes happen before the uCode is fully written */ wmb(); err: if (!IS_ERR_OR_NULL(pdcptr)) iounmap(pdcptr); if (!IS_ERR_OR_NULL(seqptr)) iounmap(seqptr); }