/** * psb_dpst_device_pool_destroy - destroy all dpst related resources * * @state: dpst state instance to destroy * */ void psb_dpst_device_pool_destroy(struct dpst_state *state) { int i; struct umevent_list *list; struct umevent_obj *umevent_test; if(state == NULL) { DRM_INFO("DPST state already NULL in psb_dpst_device_pool_destroy\n"); return; } list = state->list; flush_workqueue(state->dpst_wq); destroy_workqueue(state->dpst_wq); for (i = 0; i < DRM_DPST_MAX_NUM_EVENTS; i++) { umevent_test = list_entry((state->dpst_change_wq_data.dev_umevent_arry[i]), struct umevent_obj, head); state->dpst_change_wq_data.dev_umevent_arry[i] = NULL; } psb_umevent_cleanup(list); kfree(state); }
static int udl_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(interface); struct drm_device *dev; int r; dev = drm_dev_alloc(&driver, &interface->dev); if (IS_ERR(dev)) return PTR_ERR(dev); r = drm_dev_register(dev, (unsigned long)udev); if (r) goto err_free; usb_set_intfdata(interface, dev); DRM_INFO("Initialized udl on minor %d\n", dev->primary->index); return 0; err_free: drm_dev_unref(dev); return r; }
/* * Init DSI DPI encoder. * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector * return pointer of newly allocated DPI encoder, NULL on error */ struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, struct mdfld_dsi_connector *dsi_connector, const struct panel_funcs *p_funcs) { struct mdfld_dsi_dpi_output *dpi_output = NULL; struct mdfld_dsi_config *dsi_config; struct drm_connector *connector = NULL; struct drm_encoder *encoder = NULL; int pipe; u32 data; int ret; pipe = dsi_connector->pipe; if (mdfld_get_panel_type(dev, pipe) != TC35876X) { dsi_config = mdfld_dsi_get_config(dsi_connector); /* panel hard-reset */ if (p_funcs->reset) { ret = p_funcs->reset(pipe); if (ret) { DRM_ERROR("Panel %d hard-reset failed\n", pipe); return NULL; } } /* panel drvIC init */ if (p_funcs->drv_ic_init) p_funcs->drv_ic_init(dsi_config, pipe); /* panel power mode detect */ ret = mdfld_dsi_get_power_mode(dsi_config, &data, false); if (ret) { DRM_ERROR("Panel %d get power mode failed\n", pipe); dsi_connector->status = connector_status_disconnected; } else { DRM_INFO("pipe %d power mode 0x%x\n", pipe, data); dsi_connector->status = connector_status_connected; } } dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL); if (!dpi_output) { DRM_ERROR("No memory\n"); return NULL; } if (dsi_connector->pipe) dpi_output->panel_on = 0; else dpi_output->panel_on = 0; dpi_output->dev = dev; if (mdfld_get_panel_type(dev, pipe) != TC35876X) dpi_output->p_funcs = p_funcs; dpi_output->first_boot = 1; /*get fixed mode*/ dsi_config = mdfld_dsi_get_config(dsi_connector); /*create drm encoder object*/ connector = &dsi_connector->base.base; encoder = &dpi_output->base.base.base; drm_encoder_init(dev, encoder, p_funcs->encoder_funcs, DRM_MODE_ENCODER_LVDS); drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs); /*attach to given connector*/ drm_mode_connector_attach_encoder(connector, encoder); /*set possible crtcs and clones*/ if (dsi_connector->pipe) { encoder->possible_crtcs = (1 << 2); encoder->possible_clones = (1 << 1); } else { encoder->possible_crtcs = (1 << 0); encoder->possible_clones = (1 << 0); } dsi_connector->base.encoder = &dpi_output->base.base; return &dpi_output->base; }
static int udl_parse_vendor_descriptor(struct drm_device *dev, struct usb_device *usbdev) { struct udl_device *udl = dev->dev_private; char *desc; char *buf; char *desc_end; u8 total_len = 0; buf = kzalloc(MAX_VENDOR_DESCRIPTOR_SIZE, GFP_KERNEL); if (!buf) return false; desc = buf; total_len = usb_get_descriptor(usbdev, 0x5f, /* vendor specific */ 0, desc, MAX_VENDOR_DESCRIPTOR_SIZE); if (total_len > 5) { DRM_INFO("vendor descriptor length:%x data:%11ph\n", total_len, desc); if ((desc[0] != total_len) || /* descriptor length */ (desc[1] != 0x5f) || /* vendor descriptor type */ (desc[2] != 0x01) || /* version (2 bytes) */ (desc[3] != 0x00) || (desc[4] != total_len - 2)) /* length after type */ goto unrecognized; desc_end = desc + total_len; desc += 5; /* the fixed header we've already parsed */ while (desc < desc_end) { u8 length; u16 key; key = le16_to_cpu(*((u16 *) desc)); desc += sizeof(u16); length = *desc; desc++; switch (key) { case 0x0200: { /* max_area */ u32 max_area; max_area = le32_to_cpu(*((u32 *)desc)); DRM_DEBUG("DL chip limited to %d pixel modes\n", max_area); udl->sku_pixel_limit = max_area; break; } default: break; } desc += length; } } goto success; unrecognized: /* allow udlfb to load for now even if firmware unrecognized */ DRM_ERROR("Unrecognized vendor firmware descriptor\n"); success: kfree(buf); return true; }
/** * intel_vgt_balloon - balloon out reserved graphics address trunks * @dev_priv: i915 device private data * * This function is called at the initialization stage, to balloon out the * graphic address space allocated to other vGPUs, by marking these spaces as * reserved. The ballooning related knowledge(starting address and size of * the mappable/unmappable graphic memory) is described in the vgt_if structure * in a reserved mmio range. * * To give an example, the drawing below depicts one typical scenario after * ballooning. Here the vGPU1 has 2 pieces of graphic address spaces ballooned * out each for the mappable and the non-mappable part. From the vGPU1 point of * view, the total size is the same as the physical one, with the start address * of its graphic space being zero. Yet there are some portions ballooned out( * the shadow part, which are marked as reserved by drm allocator). From the * host point of view, the graphic address space is partitioned by multiple * vGPUs in different VMs. :: * * vGPU1 view Host view * 0 ------> +-----------+ +-----------+ * ^ |###########| | vGPU3 | * | |###########| +-----------+ * | |###########| | vGPU2 | * | +-----------+ +-----------+ * mappable GM | available | ==> | vGPU1 | * | +-----------+ +-----------+ * | |###########| | | * v |###########| | Host | * +=======+===========+ +===========+ * ^ |###########| | vGPU3 | * | |###########| +-----------+ * | |###########| | vGPU2 | * | +-----------+ +-----------+ * unmappable GM | available | ==> | vGPU1 | * | +-----------+ +-----------+ * | |###########| | | * | |###########| | Host | * v |###########| | | * total GM size ------> +-----------+ +-----------+ * * Returns: * zero on success, non-zero if configuration invalid or ballooning failed */ int intel_vgt_balloon(struct drm_i915_private *dev_priv) { struct i915_ggtt *ggtt = &dev_priv->ggtt; unsigned long ggtt_end = ggtt->base.start + ggtt->base.total; unsigned long mappable_base, mappable_size, mappable_end; unsigned long unmappable_base, unmappable_size, unmappable_end; int ret; if (!intel_vgpu_active(dev_priv)) return 0; mappable_base = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.base)); mappable_size = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.size)); unmappable_base = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.base)); unmappable_size = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.size)); mappable_end = mappable_base + mappable_size; unmappable_end = unmappable_base + unmappable_size; DRM_INFO("VGT ballooning configuration:\n"); DRM_INFO("Mappable graphic memory: base 0x%lx size %ldKiB\n", mappable_base, mappable_size / 1024); DRM_INFO("Unmappable graphic memory: base 0x%lx size %ldKiB\n", unmappable_base, unmappable_size / 1024); if (mappable_base < ggtt->base.start || mappable_end > ggtt->mappable_end || unmappable_base < ggtt->mappable_end || unmappable_end > ggtt_end) { DRM_ERROR("Invalid ballooning configuration!\n"); return -EINVAL; } /* Unmappable graphic memory ballooning */ if (unmappable_base > ggtt->mappable_end) { ret = vgt_balloon_space(&ggtt->base.mm, &bl_info.space[2], ggtt->mappable_end, unmappable_base); if (ret) goto err; } /* * No need to partition out the last physical page, * because it is reserved to the guard page. */ if (unmappable_end < ggtt_end - PAGE_SIZE) { ret = vgt_balloon_space(&ggtt->base.mm, &bl_info.space[3], unmappable_end, ggtt_end - PAGE_SIZE); if (ret) goto err; } /* Mappable graphic memory ballooning */ if (mappable_base > ggtt->base.start) { ret = vgt_balloon_space(&ggtt->base.mm, &bl_info.space[0], ggtt->base.start, mappable_base); if (ret) goto err; } if (mappable_end < ggtt->mappable_end) { ret = vgt_balloon_space(&ggtt->base.mm, &bl_info.space[1], mappable_end, ggtt->mappable_end); if (ret) goto err; } DRM_INFO("VGT balloon successfully\n"); return 0; err: DRM_ERROR("VGT balloon fail\n"); intel_vgt_deballoon(dev_priv); return ret; }
void mid_hdmi_audio_init(struct android_hdmi_priv *hdmi_priv) { DRM_INFO("%s: HDMI is not supported.\n", __func__); }
static int vmw_ttm_mem_global_init(struct drm_global_reference *ref) { DRM_INFO("global init.\n"); return ttm_mem_global_init(ref->object); }
static int gmbus_xfer(device_t adapter, struct iic_msg *msgs, uint32_t num) { struct intel_iic_softc *sc = device_get_softc(adapter); struct intel_gmbus *bus = sc->bus; struct drm_i915_private *dev_priv = bus->dev_priv; int i, reg_offset; int ret = 0; sx_xlock(&dev_priv->gmbus_mutex); if (bus->force_bit) { ret = -IICBUS_TRANSFER(bus->bbbus, msgs, num); goto out; } reg_offset = dev_priv->gpio_mmio_base; I915_WRITE(GMBUS0 + reg_offset, bus->reg0); for (i = 0; i < num; i++) { u32 gmbus2; if (gmbus_is_index_read(msgs, i, num)) { ret = gmbus_xfer_index_read(dev_priv, &msgs[i]); i += 1; /* set i to the index of the read xfer */ } else if (msgs[i].flags & I2C_M_RD) { ret = gmbus_xfer_read(dev_priv, &msgs[i], 0); } else { ret = gmbus_xfer_write(dev_priv, &msgs[i]); } if (ret == -ETIMEDOUT) goto timeout; if (ret == -ENXIO) goto clear_err; ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50); if (ret) goto timeout; if (gmbus2 & GMBUS_SATOER) goto clear_err; } /* Generate a STOP condition on the bus. Note that gmbus can't generata * a STOP on the very first cycle. To simplify the code we * unconditionally generate the STOP condition with an additional gmbus * cycle. */ I915_WRITE(GMBUS1 + reg_offset, GMBUS_CYCLE_STOP | GMBUS_SW_RDY); /* Mark the GMBUS interface as disabled after waiting for idle. * We will re-enable it at the start of the next xfer, * till then let it sleep. */ if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, 10)) { DRM_DEBUG_KMS("GMBUS [%s] timed out waiting for idle\n", device_get_desc(adapter)); ret = -ETIMEDOUT; } I915_WRITE(GMBUS0 + reg_offset, 0); goto out; clear_err: /* * Wait for bus to IDLE before clearing NAK. * If we clear the NAK while bus is still active, then it will stay * active and the next transaction may fail. * * If no ACK is received during the address phase of a transaction, the * adapter must report -ENXIO. It is not clear what to return if no ACK * is received at other times. But we have to be careful to not return * spurious -ENXIO because that will prevent i2c and drm edid functions * from retrying. So return -ENXIO only when gmbus properly quiescents - * timing out seems to happen when there _is_ a ddc chip present, but * it's slow responding and only answers on the 2nd retry. */ ret = -ENXIO; if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, 10)) { DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n", device_get_desc(adapter)); ret = -ETIMEDOUT; } /* Toggle the Software Clear Interrupt bit. This has the effect * of resetting the GMBUS controller and so clearing the * BUS_ERROR raised by the slave's NAK. */ I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); I915_WRITE(GMBUS1 + reg_offset, 0); I915_WRITE(GMBUS0 + reg_offset, 0); DRM_DEBUG_KMS("GMBUS [%s] NAK for addr: %04x %c(%d)\n", device_get_desc(adapter), msgs[i].slave >> 1, (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len); goto out; timeout: DRM_INFO("GMBUS [%s] timed out, falling back to bit banging on pin %d\n", device_get_desc(adapter), bus->reg0 & 0xff); I915_WRITE(GMBUS0 + reg_offset, 0); /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ bus->force_bit = 1; ret = -IICBUS_TRANSFER(bus->bbbus, msgs, num); out: sx_xunlock(&dev_priv->gmbus_mutex); return -ret; }
int mrfld_gtt_init(struct psb_gtt *pg, int resume) { struct drm_device *dev = pg->dev; struct drm_psb_private *dev_priv = dev->dev_private; unsigned gtt_pages; unsigned long stolen_size, vram_stolen_size, ci_stolen_size; unsigned long rar_stolen_size; unsigned i, num_pages; unsigned pfn_base; uint32_t ci_pages, vram_pages; uint32_t tt_pages; uint32_t *ttm_gtt_map; int ret = 0; uint32_t pte; pg->initialized = 1; pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE); /* fix me: video mmu has hw bug to access 0x0D0000000, * then make gatt start at 0x0e000,0000 */ pg->mmu_gatt_start = PSB_MEM_TT_START; pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE) >> PAGE_SHIFT; pci_read_config_dword(dev->pdev, MRFLD_BGSM, &pg->pge_ctl); pg->gtt_phys_start = pg->pge_ctl & PAGE_MASK; pci_read_config_dword(dev->pdev, MRFLD_MSAC, >t_pages); printk(KERN_INFO "01 gtt_pages = 0x%x \n", gtt_pages); gtt_pages &= _APERTURE_SIZE_MASK; gtt_pages >>= _APERTURE_SIZE_POS; printk(KERN_INFO "02 gtt_pages = 0x%x \n", gtt_pages); switch (gtt_pages) { case _1G_APERTURE: gtt_pages = _1G_APERTURE_SIZE >> PAGE_SHIFT; break; case _512M_APERTURE: gtt_pages = _512M_APERTURE_SIZE >> PAGE_SHIFT; break; case _256M_APERTURE: gtt_pages = _256M_APERTURE_SIZE >> PAGE_SHIFT; break; default: DRM_ERROR("%s, invalded aperture size.\n", __func__); gtt_pages = _1G_APERTURE_SIZE >> PAGE_SHIFT; } gtt_pages >>= PAGE_SHIFT; gtt_pages *= 4; printk(KERN_INFO "03 gtt_pages = 0x%x \n", gtt_pages); /* HW removed the PSB_BSM, SW/FW needs it. */ pci_read_config_dword(dev->pdev, PSB_BSM, &pg->stolen_base); vram_stolen_size = pg->gtt_phys_start - pg->stolen_base - PAGE_SIZE; /* CI is not included in the stolen size since the TOPAZ MMU bug */ ci_stolen_size = dev_priv->ci_region_size; /* Don't add CI & RAR share buffer space * managed by TTM to stolen_size */ stolen_size = vram_stolen_size; rar_stolen_size = dev_priv->rar_region_size; printk(KERN_INFO "GMMADR(region 0) start: 0x%08x (%dM).\n", pg->gatt_start, pg->gatt_pages / 256); printk(KERN_INFO "GTT (can map %dM RAM), and actual RAM base 0x%08x.\n", gtt_pages * 4, pg->gtt_phys_start); printk(KERN_INFO "Stole memory information \n"); printk(KERN_INFO " base in RAM: 0x%x \n", pg->stolen_base); printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base).\n", vram_stolen_size / 1024); if (ci_stolen_size > 0) printk(KERN_INFO "CI Stole memory: RAM base = 0x%08x, size = %lu M \n", dev_priv->ci_region_start, ci_stolen_size / 1024 / 1024); if (rar_stolen_size > 0) printk(KERN_INFO "RAR Stole memory: RAM base = 0x%08x, size = %lu M \n", dev_priv->rar_region_start, rar_stolen_size / 1024 / 1024); if (resume && (gtt_pages != pg->gtt_pages) && (stolen_size != pg->stolen_size)) { DRM_ERROR("GTT resume error.\n"); ret = -EINVAL; goto out_err; } pg->gtt_pages = gtt_pages; pg->stolen_size = stolen_size; pg->vram_stolen_size = vram_stolen_size; pg->ci_stolen_size = ci_stolen_size; pg->rar_stolen_size = rar_stolen_size; pg->gtt_map = ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT); if (!pg->gtt_map) { DRM_ERROR("Failure to map gtt.\n"); ret = -ENOMEM; goto out_err; } pg->vram_addr = ioremap_wc(pg->stolen_base, stolen_size); if (!pg->vram_addr) { DRM_ERROR("Failure to map stolen base.\n"); ret = -ENOMEM; goto out_err; } DRM_INFO("%s: vram kernel virtual address %p\n", __FUNCTION__, pg->vram_addr); tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT; ttm_gtt_map = pg->gtt_map + tt_pages / 2; /* * insert vram stolen pages. */ pfn_base = pg->stolen_base >> PAGE_SHIFT; vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT; printk(KERN_INFO "Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n", num_pages, pfn_base, 0); for (i = 0; i < num_pages; ++i) { pte = psb_gtt_mask_pte(pfn_base + i, 0); iowrite32(pte, pg->gtt_map + i); } /* * Init rest of gtt managed by IMG. */ pfn_base = page_to_pfn(dev_priv->scratch_page); pte = psb_gtt_mask_pte(pfn_base, 0); for (; i < tt_pages / 2 - 1; ++i) iowrite32(pte, pg->gtt_map + i); /* * insert CI stolen pages */ pfn_base = dev_priv->ci_region_start >> PAGE_SHIFT; ci_pages = num_pages = ci_stolen_size >> PAGE_SHIFT; printk(KERN_INFO "Set up %d CI stolen pages starting at 0x%08x, GTT offset %dK\n", num_pages, pfn_base, (ttm_gtt_map - pg->gtt_map) * 4); for (i = 0; i < num_pages; ++i) { pte = psb_gtt_mask_pte(pfn_base + i, 0); iowrite32(pte, ttm_gtt_map + i); } /* * insert RAR stolen pages */ if (rar_stolen_size != 0) { pfn_base = dev_priv->rar_region_start >> PAGE_SHIFT; num_pages = rar_stolen_size >> PAGE_SHIFT; printk(KERN_INFO "Set up %d RAR stolen pages starting at 0x%08x, GTT offset %dK\n", num_pages, pfn_base, (ttm_gtt_map - pg->gtt_map + i) * 4); for (; i < num_pages + ci_pages; ++i) { pte = psb_gtt_mask_pte(pfn_base + i - ci_pages, 0); iowrite32(pte, ttm_gtt_map + i); } }
static int __init h8c7_lcd_init(void) { DRM_INFO("%s\n", __func__); return platform_driver_register(&h8c7_lcd_driver); }
static void mdfld_h8c7_dsi_controller_init(struct mdfld_dsi_config *dsi_config) { struct mdfld_dsi_hw_context *hw_ctx = &dsi_config->dsi_hw_context; struct drm_device *dev = dsi_config->dev; struct csc_setting csc = { .pipe = 0, .type = CSC_REG_SETTING, .enable_state = true, .data_len = CSC_REG_COUNT, .data.csc_reg_data = { 0xFFB0424, 0xFDF, 0x4320FF1, 0xFDC, 0xFF50FF5, 0x415} }; struct gamma_setting gamma = { .pipe = 0, .type = GAMMA_REG_SETTING, .enable_state = true, .data_len = GAMMA_10_BIT_TABLE_COUNT, .gamma_tableX100 = { 0x000000, 0x030303, 0x050505, 0x070707, 0x090909, 0x0C0C0C, 0x0E0E0E, 0x101010, 0x121212, 0x141414, 0x171717, 0x191919, 0x1B1B1B, 0x1D1D1D, 0x1F1F1F, 0x212121, 0x232323, 0x252525, 0x282828, 0x2A2A2A, 0x2C2C2C, 0x2E2E2E, 0x303030, 0x323232, 0x343434, 0x363636, 0x383838, 0x3A3A3A, 0x3C3C3C, 0x3E3E3E, 0x404040, 0x424242, 0x444444, 0x464646, 0x484848, 0x4A4A4A, 0x4C4C4C, 0x4E4E4E, 0x505050, 0x525252, 0x545454, 0x565656, 0x585858, 0x5A5A5A, 0x5C5C5C, 0x5E5E5E, 0x606060, 0x626262, 0x646464, 0x666666, 0x686868, 0x6A6A6A, 0x6C6C6C, 0x6E6E6E, 0x707070, 0x727272, 0x747474, 0x767676, 0x787878, 0x7A7A7A, 0x7C7C7C, 0x7E7E7E, 0x808080, 0x828282, 0x848484, 0x868686, 0x888888, 0x8A8A8A, 0x8C8C8C, 0x8E8E8E, 0x909090, 0x929292, 0x949494, 0x969696, 0x989898, 0x999999, 0x9B9B9B, 0x9D9D9D, 0x9F9F9F, 0xA1A1A1, 0xA3A3A3, 0xA5A5A5, 0xA7A7A7, 0xA9A9A9, 0xABABAB, 0xADADAD, 0xAFAFAF, 0xB1B1B1, 0xB3B3B3, 0xB5B5B5, 0xB6B6B6, 0xB8B8B8, 0xBABABA, 0xBCBCBC, 0xBEBEBE, 0xC0C0C0, 0xC2C2C2, 0xC4C4C4, 0xC6C6C6, 0xC8C8C8, 0xCACACA, 0xCCCCCC, 0xCECECE, 0xCFCFCF, 0xD1D1D1, 0xD3D3D3, 0xD5D5D5, 0xD7D7D7, 0xD9D9D9, 0xDBDBDB, 0xDDDDDD, 0xDFDFDF, 0xE1E1E1, 0xE3E3E3, 0xE4E4E4, 0xE6E6E6, 0xE8E8E8, 0xEAEAEA, 0xECECEC, 0xEEEEEE, 0xF0F0F0, 0xF2F2F2, 0xF4F4F4, 0xF6F6F6, 0xF7F7F7, 0xF9F9F9, 0xFBFBFB, 0xFDFDFD} }; PSB_DEBUG_ENTRY("\n"); /*reconfig lane configuration*/ dsi_config->lane_count = 3; dsi_config->lane_config = MDFLD_DSI_DATA_LANE_3_1; dsi_config->enable_gamma_csc = ENABLE_GAMMA | ENABLE_CSC; /* This is for 400 mhz. Set it to 0 for 800mhz */ hw_ctx->cck_div = 1; hw_ctx->pll_bypass_mode = 0; hw_ctx->mipi_control = 0x00; hw_ctx->intr_en = 0xffffffff; hw_ctx->hs_tx_timeout = 0xffffff; hw_ctx->lp_rx_timeout = 0xffffff; hw_ctx->turn_around_timeout = 0x1f; hw_ctx->device_reset_timer = 0xffff; hw_ctx->high_low_switch_count = 0x20; hw_ctx->init_count = 0xf0; hw_ctx->eot_disable = 0x3; hw_ctx->lp_byteclk = 0x4; hw_ctx->clk_lane_switch_time_cnt = 0x20000E; hw_ctx->hs_ls_dbi_enable = 0x0; /* HW team suggested 1390 for bandwidth setting */ hw_ctx->dbi_bw_ctrl = 1390; hw_ctx->dphy_param = 0x20124E1A; hw_ctx->dsi_func_prg = (0xa000 | dsi_config->lane_count); hw_ctx->mipi = TE_TRIGGER_GPIO_PIN; hw_ctx->mipi |= dsi_config->lane_config; if (dsi_config->enable_gamma_csc & ENABLE_CSC) { /* setting the tuned csc setting */ drm_psb_enable_color_conversion = 1; mdfld_intel_crtc_set_color_conversion(dev, &csc); } if (dsi_config->enable_gamma_csc & ENABLE_GAMMA) { /* setting the tuned gamma setting */ drm_psb_enable_gamma = 1; mdfld_intel_crtc_set_gamma(dev, &gamma); } } static struct drm_display_mode *h8c7_cmd_get_config_mode(void) { struct drm_display_mode *mode; PSB_DEBUG_ENTRY("\n"); mode = kzalloc(sizeof(*mode), GFP_KERNEL); if (!mode) return NULL; mode->htotal = 920; mode->hdisplay = 720; mode->hsync_start = 816; mode->hsync_end = 824; mode->vtotal = 1300; mode->vdisplay = 1280; mode->vsync_start = 1294; mode->vsync_end = 1296; mode->vrefresh = 60; mode->clock = mode->vrefresh * mode->vtotal * mode->htotal / 1000; mode->type |= DRM_MODE_TYPE_PREFERRED; PSB_DEBUG_ENTRY("hdisplay is %d\n", mode->hdisplay); PSB_DEBUG_ENTRY("vdisplay is %d\n", mode->vdisplay); PSB_DEBUG_ENTRY("HSS is %d\n", mode->hsync_start); PSB_DEBUG_ENTRY("HSE is %d\n", mode->hsync_end); PSB_DEBUG_ENTRY("htotal is %d\n", mode->htotal); PSB_DEBUG_ENTRY("VSS is %d\n", mode->vsync_start); PSB_DEBUG_ENTRY("VSE is %d\n", mode->vsync_end); PSB_DEBUG_ENTRY("vtotal is %d\n", mode->vtotal); PSB_DEBUG_ENTRY("clock is %d\n", mode->clock); drm_mode_set_name(mode); drm_mode_set_crtcinfo(mode, 0); return mode; } static int mdfld_dsi_h8c7_cmd_power_on(struct mdfld_dsi_config *dsi_config) { struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); int err = 0; int enable_err, enabled = 0; PSB_DEBUG_ENTRY("\n"); if (!sender) { DRM_ERROR("Failed to get DSI packet sender\n"); return -EINVAL; } if (!IS_ERR(h8c7_regulator_status.regulator)) { if (!h8c7_regulator_status.h8c7_mmc2_on) { PSB_DEBUG_ENTRY("Before power on, regulator is %d\n", regulator_is_enabled(h8c7_regulator_status.regulator)); PSB_DEBUG_ENTRY("Begin to power on\n"); h8c7_regulator_status.h8c7_mmc2_on = true; } else { DRM_ERROR("power on several times without off\n"); } enabled = regulator_is_enabled(h8c7_regulator_status.regulator); enable_err = regulator_enable(h8c7_regulator_status.regulator); if (enable_err < 0) { regulator_put(h8c7_regulator_status.regulator); DRM_ERROR("FATAL:enable h8c7 regulator error\n"); } /* vemmc2 need 50ms delay due to stability ** If already enabled, no need to wait for this delay. ** This code isn't race proof but since in addition to ** this panel driver only touch driver is enabling this ** regulator and does it after this function has been ** finished, this code works well enough for now. */ if (!enabled) msleep(50); PSB_DEBUG_ENTRY("After power on, regulator is %d\n", regulator_is_enabled(h8c7_regulator_status.regulator)); } /*exit sleep */ err = mdfld_dsi_send_dcs(sender, exit_sleep_mode, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM, MDFLD_DSI_SEND_PACKAGE); if (err) { DRM_ERROR("faild to exit_sleep mode\n"); goto power_err; } msleep(120); /*set tear on*/ err = mdfld_dsi_send_dcs(sender, set_tear_on, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM, MDFLD_DSI_SEND_PACKAGE); if (err) { DRM_ERROR("faild to set_tear_on mode\n"); goto power_err; } /*turn on display*/ err = mdfld_dsi_send_dcs(sender, set_display_on, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM, MDFLD_DSI_SEND_PACKAGE); if (err) { DRM_ERROR("faild to set_display_on mode\n"); goto power_err; } if (drm_psb_enable_cabc) { /* turn on cabc */ h8c7_disable_cabc[1] = 0x2; mdfld_dsi_send_mcs_long_hs(sender, h8c7_disable_cabc, sizeof(h8c7_disable_cabc), 0); mdelay(5); mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_off, 4, 0); mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_cabc_gain, 10, 0); mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_on, 4, 0); DRM_INFO("%s enable h8c7 cabc\n", __func__); } power_err: return err; } static int mdfld_dsi_h8c7_cmd_power_off(struct mdfld_dsi_config *dsi_config) { struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); int err = 0; PSB_DEBUG_ENTRY("\n"); if (!sender) { DRM_ERROR("Failed to get DSI packet sender\n"); return -EINVAL; } /* turn off cabc */ h8c7_disable_cabc[1] = 0x0; mdfld_dsi_send_mcs_long_lp(sender, h8c7_disable_cabc, sizeof(h8c7_disable_cabc), 0); /*turn off backlight*/ err = mdfld_dsi_send_mcs_long_lp(sender, h8c7_turn_off_backlight, sizeof(h8c7_turn_off_backlight), 0); if (err) { DRM_ERROR("%s: failed to turn off backlight\n", __func__); goto out; } mdelay(1); /*turn off display */ err = mdfld_dsi_send_dcs(sender, set_display_off, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM, MDFLD_DSI_SEND_PACKAGE); if (err) { DRM_ERROR("sent set_display_off faild\n"); goto out; } /*set tear off */ err = mdfld_dsi_send_dcs(sender, set_tear_off, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM, MDFLD_DSI_SEND_PACKAGE); if (err) { DRM_ERROR("sent set_tear_off faild\n"); goto out; } /*Enter sleep mode */ err = mdfld_dsi_send_dcs(sender, enter_sleep_mode, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM, MDFLD_DSI_SEND_PACKAGE); if (err) { DRM_ERROR("DCS 0x%x sent failed\n", enter_sleep_mode); goto out; } /** * MIPI spec shows it must wait 5ms * before sneding next command */ mdelay(5); /*enter deep standby mode*/ err = mdfld_dsi_send_mcs_long_lp(sender, h8c7_mcs_protect_off, 4, 0); if (err) { DRM_ERROR("Failed to turn off protection\n"); goto out; } err = mdfld_dsi_send_mcs_long_lp(sender, h8c7_set_power_dstb, 14, 0); if (err) DRM_ERROR("Failed to enter DSTB\n"); mdelay(5); mdfld_dsi_send_mcs_long_lp(sender, h8c7_mcs_protect_on, 4, 0); out: if (!IS_ERR(h8c7_regulator_status.regulator)) { if (h8c7_regulator_status.h8c7_mmc2_on) { h8c7_regulator_status.h8c7_mmc2_on = false; PSB_DEBUG_GENERAL("Begin to power off\n"); } else DRM_ERROR("power off several times without on\n"); regulator_disable(h8c7_regulator_status.regulator); PSB_DEBUG_GENERAL("After power off, regulator is %d\n", regulator_is_enabled(h8c7_regulator_status.regulator)); } return err; } static void h8c7_cmd_get_panel_info(int pipe, struct panel_info *pi) { PSB_DEBUG_ENTRY("\n"); if (pipe == 0) { pi->width_mm = PANEL_4DOT3_WIDTH; pi->height_mm = PANEL_4DOT3_HEIGHT; } } static int mdfld_dsi_h8c7_cmd_detect(struct mdfld_dsi_config *dsi_config) { int status; struct drm_device *dev = dsi_config->dev; struct mdfld_dsi_hw_registers *regs = &dsi_config->regs; u32 dpll_val, device_ready_val; int pipe = dsi_config->pipe; struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); PSB_DEBUG_ENTRY("\n"); if (pipe == 0) { /* * FIXME: WA to detect the panel connection status, and need to * implement detection feature with get_power_mode DSI command. */ if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { DRM_ERROR("hw begin failed\n"); return -EAGAIN; } dpll_val = REG_READ(regs->dpll_reg); device_ready_val = REG_READ(regs->device_ready_reg); if ((device_ready_val & DSI_DEVICE_READY) && (dpll_val & DPLL_VCO_ENABLE)) { dsi_config->dsi_hw_context.panel_on = true; mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_off, 4, 0); mdfld_dsi_send_gen_long_hs(sender, h8c7_set_disp_reg, 13, 0); mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_on, 4, 0); } else { dsi_config->dsi_hw_context.panel_on = false; DRM_INFO("%s: panel is not initialized!\n", __func__); } status = MDFLD_DSI_PANEL_CONNECTED; ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); } else { DRM_INFO("%s: do NOT support dual panel\n", __func__); status = MDFLD_DSI_PANEL_DISCONNECTED; } return status; }
/** * radeon_vce_init - allocate memory, load vce firmware * * @rdev: radeon_device pointer * * First step to get VCE online, allocate memory and load the firmware */ int radeon_vce_init(struct radeon_device *rdev) { static const char *fw_version = "[ATI LIB=VCEFW,"; static const char *fb_version = "[ATI LIB=VCEFWSTATS,"; unsigned long size; const char *fw_name, *c; uint8_t start, mid, end; int i, r; INIT_DELAYED_WORK(&rdev->vce.idle_work, radeon_vce_idle_work_handler); switch (rdev->family) { case CHIP_BONAIRE: case CHIP_KAVERI: case CHIP_KABINI: fw_name = FIRMWARE_BONAIRE; break; default: return -EINVAL; } r = request_firmware(&rdev->vce_fw, fw_name, rdev->dev); if (r) { dev_err(rdev->dev, "radeon_vce: Can't load firmware \"%s\"\n", fw_name); return r; } /* search for firmware version */ size = rdev->vce_fw->size - strlen(fw_version) - 9; c = rdev->vce_fw->data; for (;size > 0; --size, ++c) if (strncmp(c, fw_version, strlen(fw_version)) == 0) break; if (size == 0) return -EINVAL; c += strlen(fw_version); if (sscanf(c, "%2hhd.%2hhd.%2hhd]", &start, &mid, &end) != 3) return -EINVAL; /* search for feedback version */ size = rdev->vce_fw->size - strlen(fb_version) - 3; c = rdev->vce_fw->data; for (;size > 0; --size, ++c) if (strncmp(c, fb_version, strlen(fb_version)) == 0) break; if (size == 0) return -EINVAL; c += strlen(fb_version); if (sscanf(c, "%2u]", &rdev->vce.fb_version) != 1) return -EINVAL; DRM_INFO("Found VCE firmware/feedback version %hhd.%hhd.%hhd / %d!\n", start, mid, end, rdev->vce.fb_version); rdev->vce.fw_version = (start << 24) | (mid << 16) | (end << 8); /* we can only work with this fw version for now */ if (rdev->vce.fw_version != ((40 << 24) | (2 << 16) | (2 << 8))) return -EINVAL; /* allocate firmware, stack and heap BO */ size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) + RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE; r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->vce.vcpu_bo); if (r) { dev_err(rdev->dev, "(%d) failed to allocate VCE bo\n", r); return r; } r = radeon_bo_reserve(rdev->vce.vcpu_bo, false); if (r) { radeon_bo_unref(&rdev->vce.vcpu_bo); dev_err(rdev->dev, "(%d) failed to reserve VCE bo\n", r); return r; } r = radeon_bo_pin(rdev->vce.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, &rdev->vce.gpu_addr); radeon_bo_unreserve(rdev->vce.vcpu_bo); if (r) { radeon_bo_unref(&rdev->vce.vcpu_bo); dev_err(rdev->dev, "(%d) VCE bo pin failed\n", r); return r; } for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) { atomic_set(&rdev->vce.handles[i], 0); rdev->vce.filp[i] = NULL; } return 0; }
static int ast_detect_chip(struct drm_device *dev, bool *need_post) { struct ast_private *ast = dev->dev_private; uint32_t data, jreg; ast_open_key(ast); if (dev->pdev->device == PCI_CHIP_AST1180) { ast->chip = AST1100; DRM_INFO("AST 1180 detected\n"); } else { if (dev->pdev->revision >= 0x30) { ast->chip = AST2400; DRM_INFO("AST 2400 detected\n"); } else if (dev->pdev->revision >= 0x20) { ast->chip = AST2300; DRM_INFO("AST 2300 detected\n"); } else if (dev->pdev->revision >= 0x10) { uint32_t data; ast_write32(ast, 0xf004, 0x1e6e0000); ast_write32(ast, 0xf000, 0x1); data = ast_read32(ast, 0x1207c); switch (data & 0x0300) { case 0x0200: ast->chip = AST1100; DRM_INFO("AST 1100 detected\n"); break; case 0x0100: ast->chip = AST2200; DRM_INFO("AST 2200 detected\n"); break; case 0x0000: ast->chip = AST2150; DRM_INFO("AST 2150 detected\n"); break; default: ast->chip = AST2100; DRM_INFO("AST 2100 detected\n"); break; } ast->vga2_clone = false; } else { ast->chip = AST2000; DRM_INFO("AST 2000 detected\n"); } } /* * If VGA isn't enabled, we need to enable now or subsequent * access to the scratch registers will fail. We also inform * our caller that it needs to POST the chip * (Assumption: VGA not enabled -> need to POST) */ if (!ast_is_vga_enabled(dev)) { ast_enable_vga(dev); ast_enable_mmio(dev); DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); *need_post = true; } else *need_post = false; /* Check if we support wide screen */ switch (ast->chip) { case AST1180: ast->support_wide_screen = true; break; case AST2000: ast->support_wide_screen = false; break; default: jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); if (!(jreg & 0x80)) ast->support_wide_screen = true; else if (jreg & 0x01) ast->support_wide_screen = true; else { ast->support_wide_screen = false; /* Read SCU7c (silicon revision register) */ ast_write32(ast, 0xf004, 0x1e6e0000); ast_write32(ast, 0xf000, 0x1); data = ast_read32(ast, 0x1207c); data &= 0x300; if (ast->chip == AST2300 && data == 0x0) /* ast1300 */ ast->support_wide_screen = true; if (ast->chip == AST2400 && data == 0x100) /* ast1400 */ ast->support_wide_screen = true; } break; } /* Check 3rd Tx option (digital output afaik) */ ast->tx_chip_type = AST_TX_NONE; /* * VGACRA3 Enhanced Color Mode Register, check if DVO is already * enabled, in that case, assume we have a SIL164 TMDS transmitter * * Don't make that assumption if we the chip wasn't enabled and * is at power-on reset, otherwise we'll incorrectly "detect" a * SIL164 when there is none. */ if (!*need_post) { jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff); if (jreg & 0x80) ast->tx_chip_type = AST_TX_SIL164; } if ((ast->chip == AST2300) || (ast->chip == AST2400)) { /* * On AST2300 and 2400, look the configuration set by the SoC in * the SOC scratch register #1 bits 11:8 (interestingly marked * as "reserved" in the spec) */ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); switch (jreg) { case 0x04: ast->tx_chip_type = AST_TX_SIL164; break; case 0x08: ast->dp501_fw_addr = kzalloc(32*1024, GFP_KERNEL); if (ast->dp501_fw_addr) { /* backup firmware */ if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) { kfree(ast->dp501_fw_addr); ast->dp501_fw_addr = NULL; } } /* fallthrough */ case 0x0c: ast->tx_chip_type = AST_TX_DP501; } } /* Print stuff for diagnostic purposes */ switch(ast->tx_chip_type) { case AST_TX_SIL164: DRM_INFO("Using Sil164 TMDS transmitter\n"); break; case AST_TX_DP501: DRM_INFO("Using DP501 DisplayPort transmitter\n"); break; default: DRM_INFO("Analog VGA only\n"); } return 0; }
int ast_driver_load(struct drm_device *dev, unsigned long flags) { struct ast_private *ast; bool need_post; int ret = 0; ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL); if (!ast) return -ENOMEM; dev->dev_private = ast; ast->dev = dev; ast->regs = pci_iomap(dev->pdev, 1, 0); if (!ast->regs) { ret = -EIO; goto out_free; } /* * If we don't have IO space at all, use MMIO now and * assume the chip has MMIO enabled by default (rev 0x20 * and higher). */ if (!(pci_resource_flags(dev->pdev, 2) & IORESOURCE_IO)) { DRM_INFO("platform has no IO space, trying MMIO\n"); ast->ioregs = ast->regs + AST_IO_MM_OFFSET; } /* "map" IO regs if the above hasn't done so already */ if (!ast->ioregs) { ast->ioregs = pci_iomap(dev->pdev, 2, 0); if (!ast->ioregs) { ret = -EIO; goto out_free; } } ast_detect_chip(dev, &need_post); if (ast->chip != AST1180) { ast_get_dram_info(dev); ast->vram_size = ast_get_vram_info(dev); DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size); } if (need_post) ast_post_gpu(dev); ret = ast_mm_init(ast); if (ret) goto out_free; drm_mode_config_init(dev); dev->mode_config.funcs = (void *)&ast_mode_funcs; dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; dev->mode_config.preferred_depth = 24; dev->mode_config.prefer_shadow = 1; if (ast->chip == AST2100 || ast->chip == AST2200 || ast->chip == AST2300 || ast->chip == AST2400 || ast->chip == AST1180) { dev->mode_config.max_width = 1920; dev->mode_config.max_height = 2048; } else { dev->mode_config.max_width = 1600; dev->mode_config.max_height = 1200; } ret = ast_mode_init(dev); if (ret) goto out_free; ret = ast_fbdev_init(dev); if (ret) goto out_free; return 0; out_free: kfree(ast); dev->dev_private = NULL; return ret; }
static bool legacy_read_disabled_bios(struct radeon_device *rdev) { uint32_t seprom_cntl1; uint32_t viph_control; uint32_t bus_cntl; uint32_t crtc_gen_cntl; uint32_t crtc2_gen_cntl; uint32_t crtc_ext_cntl; uint32_t fp2_gen_cntl; bool r; DRM_INFO("%s: ===> Try disabled BIOS (legacy)...\n", __func__); seprom_cntl1 = RREG32(RADEON_SEPROM_CNTL1); viph_control = RREG32(RADEON_VIPH_CONTROL); if (rdev->flags & RADEON_IS_PCIE) bus_cntl = RREG32(RV370_BUS_CNTL); else bus_cntl = RREG32(RADEON_BUS_CNTL); crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL); crtc2_gen_cntl = 0; crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); fp2_gen_cntl = 0; #define PCI_DEVICE_ID_ATI_RADEON_QY 0x5159 if (rdev->ddev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) { fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); } if (!(rdev->flags & RADEON_SINGLE_CRTC)) { crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); } WREG32(RADEON_SEPROM_CNTL1, ((seprom_cntl1 & ~RADEON_SCK_PRESCALE_MASK) | (0xc << RADEON_SCK_PRESCALE_SHIFT))); /* disable VIP */ WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); /* enable the rom */ if (rdev->flags & RADEON_IS_PCIE) WREG32(RV370_BUS_CNTL, (bus_cntl & ~RV370_BUS_BIOS_DIS_ROM)); else WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); /* Turn off mem requests and CRTC for both controllers */ WREG32(RADEON_CRTC_GEN_CNTL, ((crtc_gen_cntl & ~RADEON_CRTC_EN) | (RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN))); if (!(rdev->flags & RADEON_SINGLE_CRTC)) { WREG32(RADEON_CRTC2_GEN_CNTL, ((crtc2_gen_cntl & ~RADEON_CRTC2_EN) | RADEON_CRTC2_DISP_REQ_EN_B)); } /* Turn off CRTC */ WREG32(RADEON_CRTC_EXT_CNTL, ((crtc_ext_cntl & ~RADEON_CRTC_CRT_ON) | (RADEON_CRTC_SYNC_TRISTAT | RADEON_CRTC_DISPLAY_DIS))); if (rdev->ddev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) { WREG32(RADEON_FP2_GEN_CNTL, (fp2_gen_cntl & ~RADEON_FP2_ON)); } r = radeon_read_bios(rdev); /* restore regs */ WREG32(RADEON_SEPROM_CNTL1, seprom_cntl1); WREG32(RADEON_VIPH_CONTROL, viph_control); if (rdev->flags & RADEON_IS_PCIE) WREG32(RV370_BUS_CNTL, bus_cntl); else WREG32(RADEON_BUS_CNTL, bus_cntl); WREG32(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl); if (!(rdev->flags & RADEON_SINGLE_CRTC)) { WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); } WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); if (rdev->ddev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) { WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); } return r; }
int qxl_device_init(struct qxl_device *qdev, struct drm_device *ddev, struct pci_dev *pdev, unsigned long flags) { int r; qdev->dev = &pdev->dev; qdev->ddev = ddev; qdev->pdev = pdev; qdev->flags = flags; mutex_init(&qdev->gem.mutex); mutex_init(&qdev->update_area_mutex); mutex_init(&qdev->release_mutex); mutex_init(&qdev->surf_evict_mutex); INIT_LIST_HEAD(&qdev->gem.objects); qdev->rom_base = pci_resource_start(pdev, 2); qdev->rom_size = pci_resource_len(pdev, 2); qdev->vram_base = pci_resource_start(pdev, 0); qdev->surfaceram_base = pci_resource_start(pdev, 1); qdev->surfaceram_size = pci_resource_len(pdev, 1); qdev->io_base = pci_resource_start(pdev, 3); qdev->vram_mapping = io_mapping_create_wc(qdev->vram_base, pci_resource_len(pdev, 0)); qdev->surface_mapping = io_mapping_create_wc(qdev->surfaceram_base, qdev->surfaceram_size); DRM_DEBUG_KMS("qxl: vram %p-%p(%dM %dk), surface %p-%p(%dM %dk)\n", (void *)qdev->vram_base, (void *)pci_resource_end(pdev, 0), (int)pci_resource_len(pdev, 0) / 1024 / 1024, (int)pci_resource_len(pdev, 0) / 1024, (void *)qdev->surfaceram_base, (void *)pci_resource_end(pdev, 1), (int)qdev->surfaceram_size / 1024 / 1024, (int)qdev->surfaceram_size / 1024); qdev->rom = ioremap(qdev->rom_base, qdev->rom_size); if (!qdev->rom) { pr_err("Unable to ioremap ROM\n"); return -ENOMEM; } qxl_check_device(qdev); r = qxl_bo_init(qdev); if (r) { DRM_ERROR("bo init failed %d\n", r); return r; } qdev->ram_header = ioremap(qdev->vram_base + qdev->rom->ram_header_offset, sizeof(*qdev->ram_header)); qdev->command_ring = qxl_ring_create(&(qdev->ram_header->cmd_ring_hdr), sizeof(struct qxl_command), QXL_COMMAND_RING_SIZE, qdev->io_base + QXL_IO_NOTIFY_CMD, false, &qdev->display_event); qdev->cursor_ring = qxl_ring_create( &(qdev->ram_header->cursor_ring_hdr), sizeof(struct qxl_command), QXL_CURSOR_RING_SIZE, qdev->io_base + QXL_IO_NOTIFY_CMD, false, &qdev->cursor_event); qdev->release_ring = qxl_ring_create( &(qdev->ram_header->release_ring_hdr), sizeof(uint64_t), QXL_RELEASE_RING_SIZE, 0, true, NULL); /* TODO - slot initialization should happen on reset. where is our * reset handler? */ qdev->n_mem_slots = qdev->rom->slots_end; qdev->slot_gen_bits = qdev->rom->slot_gen_bits; qdev->slot_id_bits = qdev->rom->slot_id_bits; qdev->va_slot_mask = (~(uint64_t)0) >> (qdev->slot_id_bits + qdev->slot_gen_bits); qdev->mem_slots = kmalloc(qdev->n_mem_slots * sizeof(struct qxl_memslot), GFP_KERNEL); idr_init(&qdev->release_idr); spin_lock_init(&qdev->release_idr_lock); idr_init(&qdev->surf_id_idr); spin_lock_init(&qdev->surf_id_idr_lock); mutex_init(&qdev->async_io_mutex); /* reset the device into a known state - no memslots, no primary * created, no surfaces. */ qxl_io_reset(qdev); /* must initialize irq before first async io - slot creation */ r = qxl_irq_init(qdev); if (r) return r; /* * Note that virtual is surface0. We rely on the single ioremap done * before. */ qdev->main_mem_slot = setup_slot(qdev, 0, (unsigned long)qdev->vram_base, (unsigned long)qdev->vram_base + qdev->rom->ram_header_offset); qdev->surfaces_mem_slot = setup_slot(qdev, 1, (unsigned long)qdev->surfaceram_base, (unsigned long)qdev->surfaceram_base + qdev->surfaceram_size); DRM_INFO("main mem slot %d [%lx,%x)\n", qdev->main_mem_slot, (unsigned long)qdev->vram_base, qdev->rom->ram_header_offset); qdev->gc_queue = create_singlethread_workqueue("qxl_gc"); INIT_WORK(&qdev->gc_work, qxl_gc_work); r = qxl_fb_init(qdev); if (r) return r; return 0; }
static int xylon_drm_load(struct drm_device *dev, unsigned long flags) { struct platform_device *pdev = dev->platformdev; struct xylon_drm_device *xdev; unsigned int bpp; int ret; xdev = devm_kzalloc(dev->dev, sizeof(*xdev), GFP_KERNEL); if (!xdev) return -ENOMEM; xdev->dev = dev; dev->dev_private = xdev; drm_mode_config_init(dev); drm_kms_helper_poll_init(dev); xdev->crtc = xylon_drm_crtc_create(dev); if (IS_ERR(xdev->crtc)) { DRM_ERROR("failed create xylon crtc\n"); ret = PTR_ERR(xdev->crtc); goto err_out; } xylon_drm_mode_config_init(dev); xdev->encoder = xylon_drm_encoder_create(dev); if (IS_ERR(xdev->encoder)) { DRM_ERROR("failed create xylon encoder\n"); ret = PTR_ERR(xdev->encoder); goto err_out; } xdev->connector = xylon_drm_connector_create(dev, xdev->encoder); if (IS_ERR(xdev->connector)) { DRM_ERROR("failed create xylon connector\n"); ret = PTR_ERR(xdev->connector); goto err_out; } ret = drm_vblank_init(dev, 1); if (ret) { DRM_ERROR("failed initialize vblank\n"); goto err_out; } dev->vblank_disable_allowed = 1; ret = xylon_drm_irq_install(dev); if (ret < 0) { DRM_ERROR("failed install irq\n"); goto err_irq; } ret = xylon_drm_crtc_get_param(xdev->crtc, &bpp, XYLON_DRM_CRTC_BUFF_BPP); if (ret) { DRM_ERROR("failed get bpp\n"); goto err_fbdev; } xdev->fbdev = xylon_drm_fbdev_init(dev, bpp, 1, 1); if (IS_ERR(xdev->fbdev)) { DRM_ERROR("failed initialize fbdev\n"); ret = PTR_ERR(xdev->fbdev); goto err_fbdev; } drm_helper_disable_unused_functions(dev); platform_set_drvdata(pdev, xdev); return 0; err_fbdev: xylon_drm_irq_uninstall(dev); err_irq: drm_vblank_cleanup(dev); err_out: drm_mode_config_cleanup(dev); if (ret == -EPROBE_DEFER) DRM_INFO("driver load deferred, will be called again\n"); return ret; }
/* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */ void radeon_test_moves(struct radeon_device *rdev) { struct radeon_bo *vram_obj = NULL; struct radeon_bo **gtt_obj = NULL; struct radeon_fence *fence = NULL; uint64_t gtt_addr, vram_addr; unsigned i, n, size; int r; size = 1024 * 1024; /* Number of tests = * (Total GTT - IB pool - writeback page - ring buffers) / test size */ n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024; for (i = 0; i < RADEON_NUM_RINGS; ++i) n -= rdev->ring[i].ring_size; if (rdev->wb.wb_obj) n -= RADEON_GPU_PAGE_SIZE; if (rdev->ih.ring_obj) n -= rdev->ih.ring_size; n /= size; gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); if (!gtt_obj) { DRM_ERROR("Failed to allocate %d pointers\n", n); r = 1; goto out_cleanup; } r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, &vram_obj); if (r) { DRM_ERROR("Failed to create VRAM object\n"); goto out_cleanup; } r = radeon_bo_reserve(vram_obj, false); if (unlikely(r != 0)) goto out_cleanup; r = radeon_bo_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr); if (r) { DRM_ERROR("Failed to pin VRAM object\n"); goto out_cleanup; } for (i = 0; i < n; i++) { void *gtt_map, *vram_map; void **gtt_start, **gtt_end; void **vram_start, **vram_end; r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, gtt_obj + i); if (r) { DRM_ERROR("Failed to create GTT object %d\n", i); goto out_cleanup; } r = radeon_bo_reserve(gtt_obj[i], false); if (unlikely(r != 0)) goto out_cleanup; r = radeon_bo_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, >t_addr); if (r) { DRM_ERROR("Failed to pin GTT object %d\n", i); goto out_cleanup; } r = radeon_bo_kmap(gtt_obj[i], >t_map); if (r) { DRM_ERROR("Failed to map GTT object %d\n", i); goto out_cleanup; } for (gtt_start = gtt_map, gtt_end = gtt_map + size; gtt_start < gtt_end; gtt_start++) *gtt_start = gtt_start; radeon_bo_kunmap(gtt_obj[i]); r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); if (r) { DRM_ERROR("Failed to create GTT->VRAM fence %d\n", i); goto out_cleanup; } r = radeon_copy(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, fence); if (r) { DRM_ERROR("Failed GTT->VRAM copy %d\n", i); goto out_cleanup; } r = radeon_fence_wait(fence, false); if (r) { DRM_ERROR("Failed to wait for GTT->VRAM fence %d\n", i); goto out_cleanup; } radeon_fence_unref(&fence); r = radeon_bo_kmap(vram_obj, &vram_map); if (r) { DRM_ERROR("Failed to map VRAM object after copy %d\n", i); goto out_cleanup; } for (gtt_start = gtt_map, gtt_end = gtt_map + size, vram_start = vram_map, vram_end = vram_map + size; vram_start < vram_end; gtt_start++, vram_start++) { if (*vram_start != gtt_start) { DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, " "expected 0x%p (GTT/VRAM offset " "0x%16llx/0x%16llx)\n", i, *vram_start, gtt_start, (unsigned long long) (gtt_addr - rdev->mc.gtt_start + (void*)gtt_start - gtt_map), (unsigned long long) (vram_addr - rdev->mc.vram_start + (void*)gtt_start - gtt_map)); radeon_bo_kunmap(vram_obj); goto out_cleanup; } *vram_start = vram_start; } radeon_bo_kunmap(vram_obj); r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); if (r) { DRM_ERROR("Failed to create VRAM->GTT fence %d\n", i); goto out_cleanup; } r = radeon_copy(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, fence); if (r) { DRM_ERROR("Failed VRAM->GTT copy %d\n", i); goto out_cleanup; } r = radeon_fence_wait(fence, false); if (r) { DRM_ERROR("Failed to wait for VRAM->GTT fence %d\n", i); goto out_cleanup; } radeon_fence_unref(&fence); r = radeon_bo_kmap(gtt_obj[i], >t_map); if (r) { DRM_ERROR("Failed to map GTT object after copy %d\n", i); goto out_cleanup; } for (gtt_start = gtt_map, gtt_end = gtt_map + size, vram_start = vram_map, vram_end = vram_map + size; gtt_start < gtt_end; gtt_start++, vram_start++) { if (*gtt_start != vram_start) { DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, " "expected 0x%p (VRAM/GTT offset " "0x%16llx/0x%16llx)\n", i, *gtt_start, vram_start, (unsigned long long) (vram_addr - rdev->mc.vram_start + (void*)vram_start - vram_map), (unsigned long long) (gtt_addr - rdev->mc.gtt_start + (void*)vram_start - vram_map)); radeon_bo_kunmap(gtt_obj[i]); goto out_cleanup; } } radeon_bo_kunmap(gtt_obj[i]); DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n", gtt_addr - rdev->mc.gtt_start); } out_cleanup: if (vram_obj) { if (radeon_bo_is_reserved(vram_obj)) { radeon_bo_unpin(vram_obj); radeon_bo_unreserve(vram_obj); } radeon_bo_unref(&vram_obj); } if (gtt_obj) { for (i = 0; i < n; i++) { if (gtt_obj[i]) { if (radeon_bo_is_reserved(gtt_obj[i])) { radeon_bo_unpin(gtt_obj[i]); radeon_bo_unreserve(gtt_obj[i]); } radeon_bo_unref(>t_obj[i]); } } kfree(gtt_obj); } if (fence) { radeon_fence_unref(&fence); } if (r) { printk(KERN_WARNING "Error while testing BO move.\n"); } }
static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, const struct firmware *fw) { struct intel_css_header *css_header; struct intel_package_header *package_header; struct intel_dmc_header *dmc_header; struct intel_csr *csr = &dev_priv->csr; const struct stepping_info *si = intel_get_stepping_info(dev_priv); uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; uint32_t i; uint32_t *dmc_payload; uint32_t required_version; if (!fw) return NULL; /* Extract CSS Header information*/ css_header = (struct intel_css_header *)fw->data; if (sizeof(struct intel_css_header) != (css_header->header_len * 4)) { DRM_ERROR("Firmware has wrong CSS header length %u bytes\n", (css_header->header_len * 4)); return NULL; } csr->version = css_header->version; if (IS_KABYLAKE(dev_priv)) { required_version = KBL_CSR_VERSION_REQUIRED; } else if (IS_SKYLAKE(dev_priv)) { required_version = SKL_CSR_VERSION_REQUIRED; } else if (IS_BROXTON(dev_priv)) { required_version = BXT_CSR_VERSION_REQUIRED; } else { MISSING_CASE(INTEL_REVID(dev_priv)); required_version = 0; } if (csr->version != required_version) { DRM_INFO("Refusing to load DMC firmware v%u.%u," " please use v%u.%u [" FIRMWARE_URL "].\n", CSR_VERSION_MAJOR(csr->version), CSR_VERSION_MINOR(csr->version), CSR_VERSION_MAJOR(required_version), CSR_VERSION_MINOR(required_version)); return NULL; } readcount += sizeof(struct intel_css_header); /* Extract Package Header information*/ package_header = (struct intel_package_header *) &fw->data[readcount]; if (sizeof(struct intel_package_header) != (package_header->header_len * 4)) { DRM_ERROR("Firmware has wrong package header length %u bytes\n", (package_header->header_len * 4)); return NULL; } readcount += sizeof(struct intel_package_header); /* Search for dmc_offset to find firware binary. */ for (i = 0; i < package_header->num_entries; i++) { if (package_header->fw_info[i].substepping == '*' && si->stepping == package_header->fw_info[i].stepping) { dmc_offset = package_header->fw_info[i].offset; break; } else if (si->stepping == package_header->fw_info[i].stepping && si->substepping == package_header->fw_info[i].substepping) { dmc_offset = package_header->fw_info[i].offset; break; } else if (package_header->fw_info[i].stepping == '*' && package_header->fw_info[i].substepping == '*') dmc_offset = package_header->fw_info[i].offset; } if (dmc_offset == CSR_DEFAULT_FW_OFFSET) { DRM_ERROR("Firmware not supported for %c stepping\n", si->stepping); return NULL; } readcount += dmc_offset; /* Extract dmc_header information. */ dmc_header = (struct intel_dmc_header *)&fw->data[readcount]; if (sizeof(struct intel_dmc_header) != (dmc_header->header_len)) { DRM_ERROR("Firmware has wrong dmc header length %u bytes\n", (dmc_header->header_len)); return NULL; } readcount += sizeof(struct intel_dmc_header); /* Cache the dmc header info. */ if (dmc_header->mmio_count > ARRAY_SIZE(csr->mmioaddr)) { DRM_ERROR("Firmware has wrong mmio count %u\n", dmc_header->mmio_count); return NULL; } csr->mmio_count = dmc_header->mmio_count; for (i = 0; i < dmc_header->mmio_count; i++) { if (dmc_header->mmioaddr[i] < CSR_MMIO_START_RANGE || dmc_header->mmioaddr[i] > CSR_MMIO_END_RANGE) { DRM_ERROR(" Firmware has wrong mmio address 0x%x\n", dmc_header->mmioaddr[i]); return NULL; } csr->mmioaddr[i] = _MMIO(dmc_header->mmioaddr[i]); csr->mmiodata[i] = dmc_header->mmiodata[i]; } /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */ nbytes = dmc_header->fw_size * 4; if (nbytes > CSR_MAX_FW_SIZE) { DRM_ERROR("CSR firmware too big (%u) bytes\n", nbytes); return NULL; } csr->dmc_fw_size = dmc_header->fw_size; dmc_payload = kmalloc(nbytes, GFP_KERNEL); if (!dmc_payload) { DRM_ERROR("Memory allocation failed for dmc payload\n"); return NULL; } return memcpy(dmc_payload, &fw->data[readcount], nbytes); }
void radeon_test_ring_sync2(struct radeon_device *rdev, struct radeon_ring *ringA, struct radeon_ring *ringB, struct radeon_ring *ringC) { struct radeon_fence *fenceA = NULL, *fenceB = NULL; struct radeon_semaphore *semaphore = NULL; int ridxA = radeon_ring_index(rdev, ringA); int ridxB = radeon_ring_index(rdev, ringB); int ridxC = radeon_ring_index(rdev, ringC); bool sigA, sigB; int i, r; r = radeon_fence_create(rdev, &fenceA, ridxA); if (r) { DRM_ERROR("Failed to create sync fence 1\n"); goto out_cleanup; } r = radeon_fence_create(rdev, &fenceB, ridxB); if (r) { DRM_ERROR("Failed to create sync fence 2\n"); goto out_cleanup; } r = radeon_semaphore_create(rdev, &semaphore); if (r) { DRM_ERROR("Failed to create semaphore\n"); goto out_cleanup; } r = radeon_ring_lock(rdev, ringA, 64); if (r) { DRM_ERROR("Failed to lock ring A %d\n", ridxA); goto out_cleanup; } radeon_semaphore_emit_wait(rdev, ridxA, semaphore); radeon_fence_emit(rdev, fenceA); radeon_ring_unlock_commit(rdev, ringA); r = radeon_ring_lock(rdev, ringB, 64); if (r) { DRM_ERROR("Failed to lock ring B %d\n", ridxB); goto out_cleanup; } radeon_semaphore_emit_wait(rdev, ridxB, semaphore); radeon_fence_emit(rdev, fenceB); radeon_ring_unlock_commit(rdev, ringB); mdelay(1000); if (radeon_fence_signaled(fenceA)) { DRM_ERROR("Fence A signaled without waiting for semaphore.\n"); goto out_cleanup; } if (radeon_fence_signaled(fenceB)) { DRM_ERROR("Fence A signaled without waiting for semaphore.\n"); goto out_cleanup; } r = radeon_ring_lock(rdev, ringC, 64); if (r) { DRM_ERROR("Failed to lock ring B %p\n", ringC); goto out_cleanup; } radeon_semaphore_emit_signal(rdev, ridxC, semaphore); radeon_ring_unlock_commit(rdev, ringC); for (i = 0; i < 30; ++i) { mdelay(100); sigA = radeon_fence_signaled(fenceA); sigB = radeon_fence_signaled(fenceB); if (sigA || sigB) break; } if (!sigA && !sigB) { DRM_ERROR("Neither fence A nor B has been signaled\n"); goto out_cleanup; } else if (sigA && sigB) { DRM_ERROR("Both fence A and B has been signaled\n"); goto out_cleanup; } DRM_INFO("Fence %c was first signaled\n", sigA ? 'A' : 'B'); r = radeon_ring_lock(rdev, ringC, 64); if (r) { DRM_ERROR("Failed to lock ring B %p\n", ringC); goto out_cleanup; } radeon_semaphore_emit_signal(rdev, ridxC, semaphore); radeon_ring_unlock_commit(rdev, ringC); mdelay(1000); r = radeon_fence_wait(fenceA, false); if (r) { DRM_ERROR("Failed to wait for sync fence A\n"); goto out_cleanup; } r = radeon_fence_wait(fenceB, false); if (r) { DRM_ERROR("Failed to wait for sync fence B\n"); goto out_cleanup; } out_cleanup: if (semaphore) radeon_semaphore_free(rdev, semaphore); if (fenceA) radeon_fence_unref(&fenceA); if (fenceB) radeon_fence_unref(&fenceB); if (r) printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); }
static int qxlfb_create(struct qxl_fbdev *qfbdev, struct drm_fb_helper_surface_size *sizes) { struct qxl_device *qdev = qfbdev->qdev; struct fb_info *info; struct drm_framebuffer *fb = NULL; struct drm_mode_fb_cmd2 mode_cmd; struct drm_gem_object *gobj = NULL; struct qxl_bo *qbo = NULL; int ret; int size; int bpp = sizes->surface_bpp; int depth = sizes->surface_depth; void *shadow; mode_cmd.width = sizes->surface_width; mode_cmd.height = sizes->surface_height; mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 1) / 8), 64); mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); ret = qxlfb_create_pinned_object(qfbdev, &mode_cmd, &gobj); if (ret < 0) return ret; qbo = gem_to_qxl_bo(gobj); QXL_INFO(qdev, "%s: %dx%d %d\n", __func__, mode_cmd.width, mode_cmd.height, mode_cmd.pitches[0]); shadow = vmalloc(mode_cmd.pitches[0] * mode_cmd.height); /* TODO: what's the usual response to memory allocation errors? */ BUG_ON(!shadow); QXL_INFO(qdev, "surface0 at gpu offset %lld, mmap_offset %lld (virt %p, shadow %p)\n", qxl_bo_gpu_offset(qbo), qxl_bo_mmap_offset(qbo), qbo->kptr, shadow); size = mode_cmd.pitches[0] * mode_cmd.height; info = drm_fb_helper_alloc_fbi(&qfbdev->helper); if (IS_ERR(info)) { ret = PTR_ERR(info); goto out_unref; } info->par = qfbdev; qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj, &qxlfb_fb_funcs); fb = &qfbdev->qfb.base; /* setup helper with fb data */ qfbdev->helper.fb = fb; qfbdev->shadow = shadow; strcpy(info->fix.id, "qxldrmfb"); drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; info->fbops = &qxlfb_ops; /* * TODO: using gobj->size in various places in this function. Not sure * what the difference between the different sizes is. */ info->fix.smem_start = qdev->vram_base; /* TODO - correct? */ info->fix.smem_len = gobj->size; info->screen_base = qfbdev->shadow; info->screen_size = gobj->size; drm_fb_helper_fill_var(info, &qfbdev->helper, sizes->fb_width, sizes->fb_height); /* setup aperture base/size for vesafb takeover */ info->apertures->ranges[0].base = qdev->ddev->mode_config.fb_base; info->apertures->ranges[0].size = qdev->vram_size; info->fix.mmio_start = 0; info->fix.mmio_len = 0; if (info->screen_base == NULL) { ret = -ENOSPC; goto out_destroy_fbi; } info->fbdefio = &qxl_defio; fb_deferred_io_init(info); qdev->fbdev_info = info; qdev->fbdev_qfb = &qfbdev->qfb; DRM_INFO("fb mappable at 0x%lX, size %lu\n", info->fix.smem_start, (unsigned long)info->screen_size); DRM_INFO("fb: depth %d, pitch %d, width %d, height %d\n", fb->depth, fb->pitches[0], fb->width, fb->height); return 0; out_destroy_fbi: drm_fb_helper_release_fbi(&qfbdev->helper); out_unref: if (qbo) { ret = qxl_bo_reserve(qbo, false); if (likely(ret == 0)) { qxl_bo_kunmap(qbo); qxl_bo_unpin(qbo); qxl_bo_unreserve(qbo); } } if (fb && ret) { drm_gem_object_unreference_unlocked(gobj); drm_framebuffer_cleanup(fb); kfree(fb); } drm_gem_object_unreference_unlocked(gobj); return ret; }
/** * radeon_driver_load_kms - Main load function for KMS. * * @dev: drm dev pointer * @flags: device flags * * This is the main load function for KMS (all asics). * It calls radeon_device_init() to set up the non-display * parts of the chip (asic init, CP, writeback, etc.), and * radeon_modeset_init() to set up the display parts * (crtcs, encoders, hotplug detect, etc.). * Returns 0 on success, error on failure. */ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) { struct radeon_device *rdev; int r, acpi_status; rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL); if (rdev == NULL) { return -ENOMEM; } dev->dev_private = (void *)rdev; /* update BUS flag */ if (drm_pci_device_is_agp(dev)) { DRM_INFO("RADEON_IS_AGP\n"); flags |= RADEON_IS_AGP; } else if (pci_is_pcie(dev->dev->bsddev)) { DRM_INFO("RADEON_IS_PCIE\n"); flags |= RADEON_IS_PCIE; } else { DRM_INFO("RADEON_IS_PCI\n"); flags |= RADEON_IS_PCI; } #ifdef PM_TODO if ((radeon_runtime_pm != 0) && radeon_has_atpx() && ((flags & RADEON_IS_IGP) == 0)) #endif /* radeon_device_init should report only fatal error * like memory allocation failure or iomapping failure, * or memory manager initialization failure, it must * properly initialize the GPU MC controller and permit * VRAM allocation */ r = radeon_device_init(rdev, dev, dev->pdev, flags); if (r) { dev_err(&dev->pdev->dev, "Fatal error during GPU init\n"); goto out; } /* Again modeset_init should fail only on fatal error * otherwise it should provide enough functionalities * for shadowfb to run */ r = radeon_modeset_init(rdev); if (r) dev_err(&dev->pdev->dev, "Fatal error during modeset init\n"); /* Call ACPI methods: require modeset init * but failure is not fatal */ if (!r) { acpi_status = radeon_acpi_init(rdev); if (acpi_status) dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n"); } #ifdef PM_TODO if (radeon_is_px(dev)) { pm_runtime_use_autosuspend(dev->dev); pm_runtime_set_autosuspend_delay(dev->dev, 5000); pm_runtime_set_active(dev->dev); pm_runtime_allow(dev->dev); pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); } #endif out: if (r) radeon_driver_unload_kms(dev); return r; }
int ni_init_microcode(struct radeon_device *rdev) { struct platform_device *pdev; const char *chip_name; const char *rlc_chip_name; size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size; char fw_name[30]; int err; DRM_DEBUG("\n"); pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); err = IS_ERR(pdev); if (err) { printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); return -EINVAL; } switch (rdev->family) { case CHIP_BARTS: chip_name = "BARTS"; rlc_chip_name = "BTC"; pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; mc_req_size = BTC_MC_UCODE_SIZE * 4; break; case CHIP_TURKS: chip_name = "TURKS"; rlc_chip_name = "BTC"; pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; mc_req_size = BTC_MC_UCODE_SIZE * 4; break; case CHIP_CAICOS: chip_name = "CAICOS"; rlc_chip_name = "BTC"; pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; mc_req_size = BTC_MC_UCODE_SIZE * 4; break; case CHIP_CAYMAN: chip_name = "CAYMAN"; rlc_chip_name = "CAYMAN"; pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4; me_req_size = CAYMAN_PM4_UCODE_SIZE * 4; rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4; mc_req_size = CAYMAN_MC_UCODE_SIZE * 4; break; case CHIP_ARUBA: chip_name = "ARUBA"; rlc_chip_name = "ARUBA"; /* pfp/me same size as CAYMAN */ pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4; me_req_size = CAYMAN_PM4_UCODE_SIZE * 4; rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4; mc_req_size = 0; break; default: BUG(); } DRM_INFO("Loading %s Microcode\n", chip_name); snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); if (err) goto out; if (rdev->pfp_fw->size != pfp_req_size) { printk(KERN_ERR "ni_cp: Bogus length %zu in firmware \"%s\"\n", rdev->pfp_fw->size, fw_name); err = -EINVAL; goto out; } snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); if (err) goto out; if (rdev->me_fw->size != me_req_size) { printk(KERN_ERR "ni_cp: Bogus length %zu in firmware \"%s\"\n", rdev->me_fw->size, fw_name); err = -EINVAL; } snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name); err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev); if (err) goto out; if (rdev->rlc_fw->size != rlc_req_size) { printk(KERN_ERR "ni_rlc: Bogus length %zu in firmware \"%s\"\n", rdev->rlc_fw->size, fw_name); err = -EINVAL; } /* no MC ucode on TN */ if (!(rdev->flags & RADEON_IS_IGP)) { snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev); if (err) goto out; if (rdev->mc_fw->size != mc_req_size) { printk(KERN_ERR "ni_mc: Bogus length %zu in firmware \"%s\"\n", rdev->mc_fw->size, fw_name); err = -EINVAL; } } out: platform_device_unregister(pdev); if (err) { if (err != -EINVAL) printk(KERN_ERR "ni_cp: Failed to load firmware \"%s\"\n", fw_name); release_firmware(rdev->pfp_fw); rdev->pfp_fw = NULL; release_firmware(rdev->me_fw); rdev->me_fw = NULL; release_firmware(rdev->rlc_fw); rdev->rlc_fw = NULL; release_firmware(rdev->mc_fw); rdev->mc_fw = NULL; } return err; }
static long vmw_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg, long (*ioctl_func)(struct file *, unsigned int, unsigned long)) { struct drm_file *file_priv = filp->private_data; struct drm_device *dev = file_priv->minor->dev; unsigned int nr = DRM_IOCTL_NR(cmd); struct vmw_master *vmaster; unsigned int flags; long ret; /* * Do extra checking on driver private ioctls. */ if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { const struct drm_ioctl_desc *ioctl = &vmw_ioctls[nr - DRM_COMMAND_BASE]; if (nr == DRM_COMMAND_BASE + DRM_VMW_EXECBUF) { ret = (long) drm_ioctl_permit(ioctl->flags, file_priv); if (unlikely(ret != 0)) return ret; if (unlikely((cmd & (IOC_IN | IOC_OUT)) != IOC_IN)) goto out_io_encoding; return (long) vmw_execbuf_ioctl(dev, arg, file_priv, _IOC_SIZE(cmd)); } if (unlikely(ioctl->cmd != cmd)) goto out_io_encoding; flags = ioctl->flags; } else if (!drm_ioctl_flags(nr, &flags)) return -EINVAL; vmaster = vmw_master_check(dev, file_priv, flags); if (IS_ERR(vmaster)) { ret = PTR_ERR(vmaster); if (ret != -ERESTARTSYS) DRM_INFO("IOCTL ERROR Command %d, Error %ld.\n", nr, ret); return ret; } ret = ioctl_func(filp, cmd, arg); if (vmaster) ttm_read_unlock(&vmaster->lock); return ret; out_io_encoding: DRM_ERROR("Invalid command format, ioctl %d\n", nr - DRM_COMMAND_BASE); return -EINVAL; }
/** * i915_reset - reset chip after a hang * @dev: drm device to reset * * Reset the chip. Useful if a hang is detected. Returns zero on successful * reset or otherwise an error code. * * Procedure is fairly simple: * - reset the chip using the reset reg * - re-init context state * - re-init hardware status page * - re-init ring buffer * - re-init interrupt state * - re-init display */ int i915_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; bool simulated; int ret; intel_reset_gt_powersave(dev); mutex_lock(&dev->struct_mutex); i915_gem_reset(dev); simulated = dev_priv->gpu_error.stop_rings != 0; ret = intel_gpu_reset(dev, ALL_ENGINES); /* Also reset the gpu hangman. */ if (simulated) { DRM_INFO("Simulated gpu hang, resetting stop_rings\n"); dev_priv->gpu_error.stop_rings = 0; if (ret == -ENODEV) { DRM_INFO("Reset not implemented, but ignoring " "error for simulated gpu hangs\n"); ret = 0; } } if (i915_stop_ring_allow_warn(dev_priv)) pr_notice("drm/i915: Resetting chip after gpu hang\n"); if (ret) { DRM_ERROR("Failed to reset chip: %i\n", ret); mutex_unlock(&dev->struct_mutex); return ret; } intel_overlay_reset(dev_priv); /* Ok, now get things going again... */ /* * Everything depends on having the GTT running, so we need to start * there. Fortunately we don't need to do this unless we reset the * chip at a PCI level. * * Next we need to restore the context, but we don't use those * yet either... * * Ring buffer needs to be re-initialized in the KMS case, or if X * was running at the time of the reset (i.e. we weren't VT * switched away). */ /* Used to prevent gem_check_wedged returning -EAGAIN during gpu reset */ dev_priv->gpu_error.reload_in_reset = true; ret = i915_gem_init_hw(dev); dev_priv->gpu_error.reload_in_reset = false; mutex_unlock(&dev->struct_mutex); if (ret) { DRM_ERROR("Failed hw init on reset %d\n", ret); return ret; } /* * rps/rc6 re-init is necessary to restore state lost after the * reset and the re-install of gt irqs. Skip for ironlake per * previous concerns that it doesn't respond well to some forms * of re-init after reset. */ if (INTEL_INFO(dev)->gen > 5) intel_enable_gt_powersave(dev); return 0; }
static void vmw_print_capabilities(uint32_t capabilities) { DRM_INFO("Capabilities:\n"); if (capabilities & SVGA_CAP_RECT_COPY) DRM_INFO(" Rect copy.\n"); if (capabilities & SVGA_CAP_CURSOR) DRM_INFO(" Cursor.\n"); if (capabilities & SVGA_CAP_CURSOR_BYPASS) DRM_INFO(" Cursor bypass.\n"); if (capabilities & SVGA_CAP_CURSOR_BYPASS_2) DRM_INFO(" Cursor bypass 2.\n"); if (capabilities & SVGA_CAP_8BIT_EMULATION) DRM_INFO(" 8bit emulation.\n"); if (capabilities & SVGA_CAP_ALPHA_CURSOR) DRM_INFO(" Alpha cursor.\n"); if (capabilities & SVGA_CAP_3D) DRM_INFO(" 3D.\n"); if (capabilities & SVGA_CAP_EXTENDED_FIFO) DRM_INFO(" Extended Fifo.\n"); if (capabilities & SVGA_CAP_MULTIMON) DRM_INFO(" Multimon.\n"); if (capabilities & SVGA_CAP_PITCHLOCK) DRM_INFO(" Pitchlock.\n"); if (capabilities & SVGA_CAP_IRQMASK) DRM_INFO(" Irq mask.\n"); if (capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) DRM_INFO(" Display Topology.\n"); if (capabilities & SVGA_CAP_GMR) DRM_INFO(" GMR.\n"); if (capabilities & SVGA_CAP_TRACES) DRM_INFO(" Traces.\n"); if (capabilities & SVGA_CAP_GMR2) DRM_INFO(" GMR2.\n"); if (capabilities & SVGA_CAP_SCREEN_OBJECT_2) DRM_INFO(" Screen Object 2.\n"); if (capabilities & SVGA_CAP_COMMAND_BUFFERS) DRM_INFO(" Command Buffers.\n"); if (capabilities & SVGA_CAP_CMD_BUFFERS_2) DRM_INFO(" Command Buffers 2.\n"); if (capabilities & SVGA_CAP_GBOBJECTS) DRM_INFO(" Guest Backed Resources.\n"); if (capabilities & SVGA_CAP_DX) DRM_INFO(" DX Features.\n"); }
/* ************************************************************************* *\ * FUNCTION: mdfld_dsi_tpo_ic_init * * DESCRIPTION: This function is called only by mrst_dsi_mode_set and * restore_display_registers. since this function does not * acquire the mutex, it is important that the calling function * does! \* ************************************************************************* */ static void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe) { struct drm_device *dev = dsi_config->dev; u32 dcsChannelNumber = dsi_config->channel_num; u32 gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe); u32 gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe); u32 gen_ctrl_val = GEN_LONG_WRITE; DRM_INFO("Enter mrst init TPO MIPI display.\n"); gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS; /* Flip page order */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x00008036); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS)); /* 0xF0 */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x005a5af0); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); /* Write protection key */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x005a5af1); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); /* 0xFC */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x005a5afc); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); /* 0xB7 */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x770000b7); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x00000044); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS)); /* 0xB6 */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x000a0ab6); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); /* 0xF2 */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x081010f2); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x4a070708); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x000000c5); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); /* 0xF8 */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x024003f8); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x01030a04); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x0e020220); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x00000004); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS)); /* 0xE2 */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x398fc3e2); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x0000916f); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS)); /* 0xB0 */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x000000b0); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS)); /* 0xF4 */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x240242f4); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x78ee2002); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x2a071050); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x507fee10); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x10300710); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS)); /* 0xBA */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x19fe07ba); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x101c0a31); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x00000010); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); /* 0xBB */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x28ff07bb); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x24280a31); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x00000034); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); /* 0xFB */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x535d05fb); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x1b1a2130); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x221e180e); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x131d2120); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x535d0508); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x1c1a2131); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x231f160d); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x111b2220); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x535c2008); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x1f1d2433); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x2c251a10); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x2c34372d); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x00000023); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS)); /* 0xFA */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x525c0bfa); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x1c1c232f); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x2623190e); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x18212625); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x545d0d0e); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x1e1d2333); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x26231a10); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x1a222725); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x545d280f); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x21202635); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x31292013); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x31393d33); mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x00000029); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS)); /* Set DM */ mdfld_wait_for_HS_DATA_FIFO(dev, pipe); REG_WRITE(gen_data_reg, 0x000100f7); mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); }
static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) { struct vmw_private *dev_priv; int ret; uint32_t svga_id; enum vmw_res_type i; bool refuse_dma = false; char host_log[100] = {0}; dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (unlikely(dev_priv == NULL)) { DRM_ERROR("Failed allocating a device private struct.\n"); return -ENOMEM; } pci_set_master(dev->pdev); dev_priv->dev = dev; dev_priv->vmw_chipset = chipset; dev_priv->last_read_seqno = (uint32_t) -100; mutex_init(&dev_priv->cmdbuf_mutex); mutex_init(&dev_priv->release_mutex); mutex_init(&dev_priv->binding_mutex); mutex_init(&dev_priv->global_kms_state_mutex); rwlock_init(&dev_priv->resource_lock); ttm_lock_init(&dev_priv->reservation_sem); spin_lock_init(&dev_priv->hw_lock); spin_lock_init(&dev_priv->waiter_lock); spin_lock_init(&dev_priv->cap_lock); spin_lock_init(&dev_priv->svga_lock); for (i = vmw_res_context; i < vmw_res_max; ++i) { idr_init(&dev_priv->res_idr[i]); INIT_LIST_HEAD(&dev_priv->res_lru[i]); } mutex_init(&dev_priv->init_mutex); init_waitqueue_head(&dev_priv->fence_queue); init_waitqueue_head(&dev_priv->fifo_queue); dev_priv->fence_queue_waiters = 0; dev_priv->fifo_queue_waiters = 0; dev_priv->used_memory_size = 0; dev_priv->io_start = pci_resource_start(dev->pdev, 0); dev_priv->vram_start = pci_resource_start(dev->pdev, 1); dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); dev_priv->assume_16bpp = !!vmw_assume_16bpp; dev_priv->enable_fb = enable_fbdev; vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); svga_id = vmw_read(dev_priv, SVGA_REG_ID); if (svga_id != SVGA_ID_2) { ret = -ENOSYS; DRM_ERROR("Unsupported SVGA ID 0x%x\n", svga_id); goto out_err0; } dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES); ret = vmw_dma_select_mode(dev_priv); if (unlikely(ret != 0)) { DRM_INFO("Restricting capabilities due to IOMMU setup.\n"); refuse_dma = true; } dev_priv->vram_size = vmw_read(dev_priv, SVGA_REG_VRAM_SIZE); dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE); dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH); dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT); vmw_get_initial_size(dev_priv); if (dev_priv->capabilities & SVGA_CAP_GMR2) { dev_priv->max_gmr_ids = vmw_read(dev_priv, SVGA_REG_GMR_MAX_IDS); dev_priv->max_gmr_pages = vmw_read(dev_priv, SVGA_REG_GMRS_MAX_PAGES); dev_priv->memory_size = vmw_read(dev_priv, SVGA_REG_MEMORY_SIZE); dev_priv->memory_size -= dev_priv->vram_size; } else { /* * An arbitrary limit of 512MiB on surface * memory. But all HWV8 hardware supports GMR2. */ dev_priv->memory_size = 512*1024*1024; } dev_priv->max_mob_pages = 0; dev_priv->max_mob_size = 0; if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { uint64_t mem_size = vmw_read(dev_priv, SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); /* * Workaround for low memory 2D VMs to compensate for the * allocation taken by fbdev */ if (!(dev_priv->capabilities & SVGA_CAP_3D)) mem_size *= 2; dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE; dev_priv->prim_bb_mem = vmw_read(dev_priv, SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM); dev_priv->max_mob_size = vmw_read(dev_priv, SVGA_REG_MOB_MAX_SIZE); dev_priv->stdu_max_width = vmw_read(dev_priv, SVGA_REG_SCREENTARGET_MAX_WIDTH); dev_priv->stdu_max_height = vmw_read(dev_priv, SVGA_REG_SCREENTARGET_MAX_HEIGHT); vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH); dev_priv->texture_max_width = vmw_read(dev_priv, SVGA_REG_DEV_CAP); vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT); dev_priv->texture_max_height = vmw_read(dev_priv, SVGA_REG_DEV_CAP); } else { dev_priv->texture_max_width = 8192; dev_priv->texture_max_height = 8192; dev_priv->prim_bb_mem = dev_priv->vram_size; } vmw_print_capabilities(dev_priv->capabilities); ret = vmw_dma_masks(dev_priv); if (unlikely(ret != 0)) goto out_err0; if (dev_priv->capabilities & SVGA_CAP_GMR2) { DRM_INFO("Max GMR ids is %u\n", (unsigned)dev_priv->max_gmr_ids); DRM_INFO("Max number of GMR pages is %u\n", (unsigned)dev_priv->max_gmr_pages); DRM_INFO("Max dedicated hypervisor surface memory is %u kiB\n", (unsigned)dev_priv->memory_size / 1024); } DRM_INFO("Maximum display memory size is %u kiB\n", dev_priv->prim_bb_mem / 1024); DRM_INFO("VRAM at 0x%08x size is %u kiB\n", dev_priv->vram_start, dev_priv->vram_size / 1024); DRM_INFO("MMIO at 0x%08x size is %u kiB\n", dev_priv->mmio_start, dev_priv->mmio_size / 1024); ret = vmw_ttm_global_init(dev_priv); if (unlikely(ret != 0)) goto out_err0; vmw_master_init(&dev_priv->fbdev_master); ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); dev_priv->active_master = &dev_priv->fbdev_master; dev_priv->mmio_virt = memremap(dev_priv->mmio_start, dev_priv->mmio_size, MEMREMAP_WB); if (unlikely(dev_priv->mmio_virt == NULL)) { ret = -ENOMEM; DRM_ERROR("Failed mapping MMIO.\n"); goto out_err3; } /* Need mmio memory to check for fifo pitchlock cap. */ if (!(dev_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) && !(dev_priv->capabilities & SVGA_CAP_PITCHLOCK) && !vmw_fifo_have_pitchlock(dev_priv)) { ret = -ENOSYS; DRM_ERROR("Hardware has no pitchlock\n"); goto out_err4; } dev_priv->tdev = ttm_object_device_init (dev_priv->mem_global_ref.object, 12, &vmw_prime_dmabuf_ops); if (unlikely(dev_priv->tdev == NULL)) { DRM_ERROR("Unable to initialize TTM object management.\n"); ret = -ENOMEM; goto out_err4; } dev->dev_private = dev_priv; ret = pci_request_regions(dev->pdev, "vmwgfx probe"); dev_priv->stealth = (ret != 0); if (dev_priv->stealth) { /** * Request at least the mmio PCI resource. */ DRM_INFO("It appears like vesafb is loaded. " "Ignore above error if any.\n"); ret = pci_request_region(dev->pdev, 2, "vmwgfx stealth probe"); if (unlikely(ret != 0)) { DRM_ERROR("Failed reserving the SVGA MMIO resource.\n"); goto out_no_device; } } if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { ret = drm_irq_install(dev, dev->pdev->irq); if (ret != 0) { DRM_ERROR("Failed installing irq: %d\n", ret); goto out_no_irq; } } dev_priv->fman = vmw_fence_manager_init(dev_priv); if (unlikely(dev_priv->fman == NULL)) { ret = -ENOMEM; goto out_no_fman; } ret = ttm_bo_device_init(&dev_priv->bdev, dev_priv->bo_global_ref.ref.object, &vmw_bo_driver, dev->anon_inode->i_mapping, VMWGFX_FILE_PAGE_OFFSET, false); if (unlikely(ret != 0)) { DRM_ERROR("Failed initializing TTM buffer object driver.\n"); goto out_no_bdev; } /* * Enable VRAM, but initially don't use it until SVGA is enabled and * unhidden. */ ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM, (dev_priv->vram_size >> PAGE_SHIFT)); if (unlikely(ret != 0)) { DRM_ERROR("Failed initializing memory manager for VRAM.\n"); goto out_no_vram; } dev_priv->bdev.man[TTM_PL_VRAM].use_type = false; dev_priv->has_gmr = true; if (((dev_priv->capabilities & (SVGA_CAP_GMR | SVGA_CAP_GMR2)) == 0) || refuse_dma || ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR, VMW_PL_GMR) != 0) { DRM_INFO("No GMR memory available. " "Graphics memory resources are very limited.\n"); dev_priv->has_gmr = false; } if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { dev_priv->has_mob = true; if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_MOB, VMW_PL_MOB) != 0) { DRM_INFO("No MOB memory available. " "3D will be disabled.\n"); dev_priv->has_mob = false; } } if (dev_priv->has_mob) { spin_lock(&dev_priv->cap_lock); vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_DX); dev_priv->has_dx = !!vmw_read(dev_priv, SVGA_REG_DEV_CAP); spin_unlock(&dev_priv->cap_lock); } ret = vmw_kms_init(dev_priv); if (unlikely(ret != 0)) goto out_no_kms; vmw_overlay_init(dev_priv); ret = vmw_request_device(dev_priv); if (ret) goto out_no_fifo; DRM_INFO("DX: %s\n", dev_priv->has_dx ? "yes." : "no."); snprintf(host_log, sizeof(host_log), "vmwgfx: %s-%s", VMWGFX_REPO, VMWGFX_GIT_VERSION); vmw_host_log(host_log); memset(host_log, 0, sizeof(host_log)); snprintf(host_log, sizeof(host_log), "vmwgfx: Module Version: %d.%d.%d", VMWGFX_DRIVER_MAJOR, VMWGFX_DRIVER_MINOR, VMWGFX_DRIVER_PATCHLEVEL); vmw_host_log(host_log); if (dev_priv->enable_fb) { vmw_fifo_resource_inc(dev_priv); vmw_svga_enable(dev_priv); vmw_fb_init(dev_priv); } dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; register_pm_notifier(&dev_priv->pm_nb); return 0; out_no_fifo: vmw_overlay_close(dev_priv); vmw_kms_close(dev_priv); out_no_kms: if (dev_priv->has_mob) (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB); if (dev_priv->has_gmr) (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); out_no_vram: (void)ttm_bo_device_release(&dev_priv->bdev); out_no_bdev: vmw_fence_manager_takedown(dev_priv->fman); out_no_fman: if (dev_priv->capabilities & SVGA_CAP_IRQMASK) drm_irq_uninstall(dev_priv->dev); out_no_irq: if (dev_priv->stealth) pci_release_region(dev->pdev, 2); else pci_release_regions(dev->pdev); out_no_device: ttm_object_device_release(&dev_priv->tdev); out_err4: memunmap(dev_priv->mmio_virt); out_err3: vmw_ttm_global_release(dev_priv); out_err0: for (i = vmw_res_context; i < vmw_res_max; ++i) idr_destroy(&dev_priv->res_idr[i]); if (dev_priv->ctx.staged_bindings) vmw_binding_state_free(dev_priv->ctx.staged_bindings); kfree(dev_priv); return ret; }
static void mid_get_fuse_settings(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); uint32_t fuse_value = 0; uint32_t fuse_value_tmp = 0; #define FB_REG06 0xD0810600 #define FB_MIPI_DISABLE (1 << 11) #define FB_REG09 0xD0810900 #define FB_REG09 0xD0810900 #define FB_SKU_MASK 0x7000 #define FB_SKU_SHIFT 12 #define FB_SKU_100 0 #define FB_SKU_100L 1 #define FB_SKU_83 2 if (pci_root == NULL) { WARN_ON(1); return; } pci_write_config_dword(pci_root, 0xD0, FB_REG06); pci_read_config_dword(pci_root, 0xD4, &fuse_value); /* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */ if (IS_MRST(dev)) dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE; DRM_INFO("internal display is %s\n", dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display"); /* Prevent runtime suspend at start*/ if (dev_priv->iLVDS_enable) { dev_priv->is_lvds_on = true; dev_priv->is_mipi_on = false; } else { dev_priv->is_mipi_on = true; dev_priv->is_lvds_on = false; } dev_priv->video_device_fuse = fuse_value; pci_write_config_dword(pci_root, 0xD0, FB_REG09); pci_read_config_dword(pci_root, 0xD4, &fuse_value); dev_dbg(dev->dev, "SKU values is 0x%x.\n", fuse_value); fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT; dev_priv->fuse_reg_value = fuse_value; switch (fuse_value_tmp) { case FB_SKU_100: dev_priv->core_freq = 200; break; case FB_SKU_100L: dev_priv->core_freq = 100; break; case FB_SKU_83: dev_priv->core_freq = 166; break; default: dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n", fuse_value_tmp); dev_priv->core_freq = 0; } dev_dbg(dev->dev, "LNC core clk is %dMHz.\n", dev_priv->core_freq); pci_dev_put(pci_root); }
bool dm_pp_get_clock_levels_by_type( const struct dc_context *ctx, enum dm_pp_clock_type clk_type, struct dm_pp_clock_levels *dc_clks) { struct amdgpu_device *adev = ctx->driver_context; void *pp_handle = adev->powerplay.pp_handle; struct amd_pp_clocks pp_clks = { 0 }; struct amd_pp_simple_clock_info validation_clks = { 0 }; uint32_t i; if (adev->powerplay.pp_funcs->get_clock_by_type) { if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle, dc_to_pp_clock_type(clk_type), &pp_clks)) { /* Error in pplib. Provide default values. */ get_default_clock_levels(clk_type, dc_clks); return true; } } pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type); if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks) { if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks( pp_handle, &validation_clks)) { /* Error in pplib. Provide default values. */ DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n"); validation_clks.engine_max_clock = 72000; validation_clks.memory_max_clock = 80000; validation_clks.level = 0; } } DRM_INFO("DM_PPLIB: Validation clocks:\n"); DRM_INFO("DM_PPLIB: engine_max_clock: %d\n", validation_clks.engine_max_clock); DRM_INFO("DM_PPLIB: memory_max_clock: %d\n", validation_clks.memory_max_clock); DRM_INFO("DM_PPLIB: level : %d\n", validation_clks.level); /* Translate 10 kHz to kHz. */ validation_clks.engine_max_clock *= 10; validation_clks.memory_max_clock *= 10; /* Determine the highest non-boosted level from the Validation Clocks */ if (clk_type == DM_PP_CLOCK_TYPE_ENGINE_CLK) { for (i = 0; i < dc_clks->num_levels; i++) { if (dc_clks->clocks_in_khz[i] > validation_clks.engine_max_clock) { /* This clock is higher the validation clock. * Than means the previous one is the highest * non-boosted one. */ DRM_INFO("DM_PPLIB: reducing engine clock level from %d to %d\n", dc_clks->num_levels, i); dc_clks->num_levels = i > 0 ? i : 1; break; } } } else if (clk_type == DM_PP_CLOCK_TYPE_MEMORY_CLK) { for (i = 0; i < dc_clks->num_levels; i++) { if (dc_clks->clocks_in_khz[i] > validation_clks.memory_max_clock) { DRM_INFO("DM_PPLIB: reducing memory clock level from %d to %d\n", dc_clks->num_levels, i); dc_clks->num_levels = i > 0 ? i : 1; break; } } } return true; }